From: Jeff Dike <jdike@ka...> - 2000-12-09 21:58:03
> (BTW, could the naming scheme for patches be changed to not conflict
> with the patch-2.x.y-testz.bz2 pattern from Linus?)
That will change with test12. You're not the first to complain about that :-)
> arch/um/kernel/unmap_fin.o(.text+0x13160):strpbrk: first defined here
> /bin/ld: Warning: size of symbol `strpbrk' changed from 179 to 98 in
That's because of a stupid trick I'm playing in order to make breakpoints work.
I don't know why it fails to build for some people and works for others. I
think I know a way to reduce (if not eliminate) the likelyhood of this
From: Jeff Dike <jdike@ka...> - 2000-12-10 03:21:01
> Why did that make it fail with those error messages? You need to
> include the profiling libs, of course, but . . .
OK, I'll let you in on a gory secret.
UML runs its threads in separate processes. This makes context switching
faster, but it means that something tricky needs to be done in order to share
kernel data. If data isn't explicitly shared somehow, then each process will
get its own independent copy of the kernel's data, which would be bad.
So, what happens is that on bootup, the kernel's data segment is copied into a
file, the data segment is unmapped, and that file is mmapped shared in its
place. The fact that it's mapped shared causes it to be shared among all
future processes even though they have separate address spaces on the host.
Now, the advent of the kernel debugger means that the same thing must be done
with kernel text as well. The reason is that gdb is going to put breakpoints
in the code, and you want the kernel to stop no matter what process hits it.
So, changes to text must be shared, so text must be shared. And so it is,
using the same trick as for the data.
Except for one tiny little problem. When the text segment is unmapped so that
the file can be mmapped in its place, the code that was running no longer
exists. It was just unmapped.
So, the code that actually does the unmapping and remapping must not itself be
unmapped. So, this code (switcheroo()) is in its own little file (our friend
unmap.c) and it is stuck off in its own segment of the binary, which is not
unmapped. It is also necessary that everything that switcheroo calls also be
in that segment. So, unmap.c is linked with libc into another object file
Normally, this works great. unmap_fin.o pulls in a minimal set of symbols
from libc and links with the rest of the kernel and everyone is happy.
However, when you turn on profiling, unmap.o turns out to have a reference to
_mcount in it, and when that is linked against libc to produce unmap_fin.o, it
pulls in the entire world. And the entire world includes some symbols which
also have definitions in the kernel. So, the linker gets very snippy about
this and refuses to make a binary.
So, my fix was to turn off -pg when compiling unmap.c. This means that
switcheroo won't turn up in gprof, but I am happy to make that sacrifice.
Now, don't you wish you hadn't asked?