On 2006-03-16,
zeecanvas@yahoo.com <zeecanvas@yahoo.com> wrote:[color=blue]
> Fred Kleinschmidt wrote:
> [...] I'd like to find the explanation for the crashes I'm finding,
> because perhaps it has to do with the mix of C and C++ (maybe I'm
> doing something wrong when linking), or perhaps there's some memory
> bug which I didn't detect previously. Perhaps I'm using the C compiler
> for files which require the C++ compiler, or viceversa. Perhaps I'm
> declaring as extern "C" some stuff which shouldn't be declared that
> way, etc...[/color]
I don't think extern "C" should make any difference for variables, C++
only mangles names of functions. So you could probably get rid of all
those. But it might not make any difference. Unless it's exercising the
linker bug.
[color=blue]
> The first crash is even funny: In the second line of code. The first
> line obtains a pointer to the application instance, and stores that
> pointer in a global variable. The second line calls an OS function
> with that pointer, and the application crashes.[/color]
[color=blue]
> If I store that pointer in a local variable, there's no crash there
> (but there's a crash later when another global variable is used).[/color]
[color=blue]
> Also, if that pointer is stored a program-wide global variable, but
> stored in the same file of that function that crashes, there's no
> crash there. If I move it to the file with just variables (no code),
> it crashes (and the variable was program-wide in the two cases,
> because every file that need to access it includes the declarations
> header).[/color]
It does sound like some kind of linker problem from what you describe.
Is the crash a null pointer read? I have once encountered a linker that
left some references unlinked, leaving them as calls to 0 (it was
functions in that case, not globals). If you use a debugger on it when
it crashes and look at the disassembly, you should expect to see an
actual address in the disassembly as a constant value somewhere around
where you're writing to the global. If you're writing to *0, then that
points the finger at a linker problem. If you're writing to what looks
like a valid address, try putting some code that writes (or reads) the
same global variable in the module in which the variable is defined, and
step that in the debugger, to see if your two modules have ended up with
a different idea of where this variable is supposed to be.
If a debugger is not practical to run, you can actually just as easily
do the same experiment with a disassembler. Write a function in each of
the two files: the one that defines the globals and the one that
crashes. Call the functions something you will be able to grep for
easily. Make the code in the functions extremely simple, it should just
read the global variable, and return its value (don't make it so simple
the compiler optimizes it away altogether). Compile and link. Then
disassemble the executable (not the .o files) with e.g. objdump -d. If
you have the GNU tools, objdump will probably work even if you aren't
using gcc. Compare the asm for your two simple functions, are they
working with the same addresses for the global? They obviously should
be.
This will hopefully confirm a linker problem. Then you have to try to
fix that... It might be a bug, or your build might include strange
things like linker scripts that have problems in them.