Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
519 views
in Technique[技术] by (71.8m points)

operating system - What happens when you overwrite a memory-mapped executable?

Following the comments on one of my questions I'm intrigued to know what happens when one overwrites an executable. I need to check my understanding on the matter.

Say I have /usr/bin/myprog. I run it and so the OS loads /usr/bin/myprog, probably via http://en.wikipedia.org/wiki/Memory-mapped_file#Common_uses.

For whatever reason that process remains in memory and I decide actually I've fixed a bug and I overwrite /usr/bin/myprog.

So, as far as I understand it:

  • If an instance of myprog is already loaded and I replace the file from which myprog was already loaded, the instance of myprog is unmodified.
  • If I run a new instance of myprog it will use the new code.

Am I correct?

However, according to the article on memory-mapped files, such a technique allows a developer to treat portions of a file as if they are physical memory.

So I see a contradiction in how I understood things. If pages are truly only loaded in on demand, then assuming myprog is not 100% paged, this wikipedia article implies new pages will load from the file on disk, which has changed since the original image was loaded.

However, I am pretty certain that my two compiled images would not be the same and that the relevant address offsets for each file are not identical. So, assuming this happens, the instruction pointer is going to get very lost... I am pretty certain an operating system does not load parts of two different images into memory as part of the same process.

So how does the combination of memory-mapping/demand-paging work for the execution of programs, please? Would overwriting that file trigger a page fault on each of the executables' pages to ensure it is loaded in for the currently running process?

I did a quick experiment with this:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char** argv)
{
    printf("Program resident...");
    while(1)
    {
        printf("??? Just notifying you I'm still here...
");
        usleep(1000000);
    }

    return 0;
}

And sure enough I could a) replace this executable whilst it was running and b) its output isn't changed.

SO what is going on? I'd particularly appreciate any suggestions for stuff I can do to see what happens (Linux or Windows).

Thanks all.

Edit: question to which I was referring that sparked this question: Upgrades without reboot - what kinds of problems happen in practice?

Also, I'm aware this doesn't specifically relate to programming, but the outcome of updating an executable. I am still interested, however, and I can't think of a better place to ask it.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Under Linux, if you replace an executable while it is running, the results are unpredictable and it may crash. Pages which have been modified (e.g. "bss" initialised data) won't be affected, but pages which haven't been modified (e.g. most code) will.

My guess is that in your case, the string was in a part which was a modified (copied) page so wasn't affected.

However, all that only happens if you actually overwrite the same file.

Most of the time, when you replace an executable, you'll be replacing the directory entry with a different file. This is typically done by renaming a temporary file (in the same directory) over the existing one. This is what (for example) package managers do.

In the replacing-directory-entry case, the previous executable file continues to exist as a totally separate (still executing) file, and the previous executable can have its pages discarded and reloaded without a problem - it still sees the old file.

Quite what the linker does with its output, I don't know. But /usr/bin/install creates a new file. I expect this behaviour is quite deliberate.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...