Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bus error when recompiling the binary

Sometimes, on various Unix architectures, recompiling a program while it is running causes the program to crash with a "Bus error". Can anyone explain under which conditions this happens? First, how can updating the binary on disk do anything to the code in memory? The only thing I can imagine is that some systems mmap the code into memory and when the compiler rewrites the disk image, this causes the mmap to become invalid. What would the advantages be of such a method? It seems very suboptimal to be able to crash running codes by changing the executable.

like image 970
Lutorm Avatar asked Sep 05 '25 03:09

Lutorm


1 Answers

On local filesystems, all major Unix-like systems support solving this problem by removing the file. The old vnode stays open and, even after the directory entry is gone and then reused for the new image, the old file is still there, unchanged, and now unnamed, until the last reference to it (in this case the kernel) goes away.

But if you just start rewriting it, then yes, it is mmap(3)'ed. When the block is rewritten one of two things can happen depending on which mmap(3) options the dynamic linker uses:

  1. the kernel will invalidate the corresponding page, or
  2. the disk image will change but existing memory pages will not

Either way, the running program is possibly in trouble. In the first case, it is essentially guaranteed to blow up, and in the second case it will get clobbered unless all of the pages have been referenced, paged in, and are never dropped.

There were two mmap flags intended to fix this. One was MAP_DENYWRITE (prevent writes) and the other was MAP_COPY, which kept a pure version of the original and prevented writers from changing the mapped image.

But DENYWRITE has been disabled for security reasons, and COPY is not implemented in any major Unix-like system.

like image 189
DigitalRoss Avatar answered Sep 08 '25 09:09

DigitalRoss