tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

gcc: optimizations, and stack traces

An issue I spotted a few months ago, but PR/52560 just reminded me about it.

Basically, in order to get a backtrace, GDB reads the %rbp register. At the
beginning of each function, GCC inserts the two following instructions:

	pushq   %rbp
	movq    %rsp,%rbp

Therefore, at any given point, a program can read %rbp, and unwrap the call
tree by iterating this way (approximately):

	uint64_t *rbp = read_rbp();
	uint64_t rip;
	while (1) {
		if (rbp == NULL)
			break; /* End of the chain */
		rip = *(rbp + 1);
		find_function_from_rip(rip); /* whatever */
		rbp = (uint64_t *)*ptr;

But the thing is, when a program is compiled with -O2, GCC can move the two
aforementioned instructions, and put them somewhere else in a function. That
is to say, the beginning of the function may not contain the two instructions.
Currently the x86 kernels (so, both i386 and amd64) are built with -O2.

It implies that if a bug occurs _before_ these two instructions are executed,
we have a %rbp that points to the _previous_ function, the one we got called
from. And therefore, GDB does not display the current function (where the bug
actually happened), but displays its caller.

There are also several cases where functions in the call tree can disappear
from the backtrace. In the following call tree:

	A -> B -> C -> D   (and D panics)

if, in B, GCC put the two instructions after the instruction that calls C,
the backtrace will be:

	A -> C -> D

This can make a bug completely undebuggable.

When I spotted this several months ago (while developing Live Kernel ASLR), I
tried to look for GCC options that say "optimize with -O2, but keep the stack
trace intact". I couldn't find one, and the only thing I ended up doing was
disabling -O2 in the makefiles.

Now, it doesn't mean that I didn't miss it.

Is someone interested in investigating this? Not being able to get correct
backtraces is a real problem for us.


Home | Main Index | Thread Index | Old Index