admin管理员组

文章数量:1130349

It's a follow up question of In a release build by GCC, i.e., without -g flag, is register info trustable?, thanks for the answer of it, I now understand that the registers designated for function args might be broken.

Furthermore, during my investigation on the crash of release build(where no debug info is available), I suspect that the callstack itself is broken too, as some function calls seem to be missed, that is, the callstack shows in GDB is not reachable according to source code, some necessary frames that may finally lead to the deepest frame are missed.

Recalling my already rusted knowledge about computer arch, the function frames should be stored in memory and specific registers, e.g., Program Counter(PC) register, etc. I wonder is it possible that those registers compromised too? or is there any other issue for which GDB is unable to trace back the real callstack?

UPDATE #1:

Checking by layout asm, I can see the expected next frame, i.e,. the function missed, see below, note that for confidentiality purpose I replaced the function name, but the register and address are real, just in case it does matter to resolve this issue:

0x210fe9d <OBFUSCATEDiib+894> call 0x210ea10 <_ZTheFuncIAssumedMissed>
0x210fea0 <OBFUSCATEDiib+899> mov %rax,%rdi

But by backtrace, the function is indeed absent... I got even more confused, what may be happening here?

UPDATE #2:

Just confirmed the build with debug info can correctly show the backtrace.

It's a follow up question of In a release build by GCC, i.e., without -g flag, is register info trustable?, thanks for the answer of it, I now understand that the registers designated for function args might be broken.

Furthermore, during my investigation on the crash of release build(where no debug info is available), I suspect that the callstack itself is broken too, as some function calls seem to be missed, that is, the callstack shows in GDB is not reachable according to source code, some necessary frames that may finally lead to the deepest frame are missed.

Recalling my already rusted knowledge about computer arch, the function frames should be stored in memory and specific registers, e.g., Program Counter(PC) register, etc. I wonder is it possible that those registers compromised too? or is there any other issue for which GDB is unable to trace back the real callstack?

UPDATE #1:

Checking by layout asm, I can see the expected next frame, i.e,. the function missed, see below, note that for confidentiality purpose I replaced the function name, but the register and address are real, just in case it does matter to resolve this issue:

0x210fe9d <OBFUSCATEDiib+894> call 0x210ea10 <_ZTheFuncIAssumedMissed>
0x210fea0 <OBFUSCATEDiib+899> mov %rax,%rdi

But by backtrace, the function is indeed absent... I got even more confused, what may be happening here?

UPDATE #2:

Just confirmed the build with debug info can correctly show the backtrace.

Share Improve this question edited Mar 28 at 10:32 PkDrew asked Mar 26 at 10:17 PkDrewPkDrew 9472 gold badges7 silver badges23 bronze badges 17
  • 3 If some frames are missing from the callstack than it is likely that the compiler has inlined the calls. – gerum Commented Mar 26 at 10:25
  • 1 "unreachable callstack" - does it just skip steps (inlined calls) or is it genuinely nonsensical? (overwritten stack and/or heavy UB like -Werror=return-type) – teapot418 Commented Mar 26 at 10:29
  • 1 Whether the functions are inlined has nothing (well, little) to do with whether they are declared inline. It is completely valid (and common) for a compiler to inline a function not declared inline. – Weijun Zhou Commented Mar 26 at 10:32
  • 5 An inlined call in one place may still generate an externally callable version of the function in case someone else needs it. So no. – teapot418 Commented Mar 26 at 10:35
  • 1 You can compile optimised code with -g. Is there a reason not to do that? It won't directly address your specific issue but it should help in other ways – catnip Commented Mar 26 at 16:50
 |  Show 12 more comments

1 Answer 1

Reset to default 1

why function frame is missed in backtrace of GDB?

There are two main reasons:

  • the function was inlined
  • the function used tail call optimization

Building with -g (as you were advised in comments) helps with inlining -- GDB will be able to display inlined frames using the debug info provided by the compiler with -g.

But -g will not help with tail call optimization (where the compiler transforms int foo() { return bar(); } into foo: JMP bar and all traces of foo being called are erased).

It's a follow up question of In a release build by GCC, i.e., without -g flag, is register info trustable?, thanks for the answer of it, I now understand that the registers designated for function args might be broken.

Furthermore, during my investigation on the crash of release build(where no debug info is available), I suspect that the callstack itself is broken too, as some function calls seem to be missed, that is, the callstack shows in GDB is not reachable according to source code, some necessary frames that may finally lead to the deepest frame are missed.

Recalling my already rusted knowledge about computer arch, the function frames should be stored in memory and specific registers, e.g., Program Counter(PC) register, etc. I wonder is it possible that those registers compromised too? or is there any other issue for which GDB is unable to trace back the real callstack?

UPDATE #1:

Checking by layout asm, I can see the expected next frame, i.e,. the function missed, see below, note that for confidentiality purpose I replaced the function name, but the register and address are real, just in case it does matter to resolve this issue:

0x210fe9d <OBFUSCATEDiib+894> call 0x210ea10 <_ZTheFuncIAssumedMissed>
0x210fea0 <OBFUSCATEDiib+899> mov %rax,%rdi

But by backtrace, the function is indeed absent... I got even more confused, what may be happening here?

UPDATE #2:

Just confirmed the build with debug info can correctly show the backtrace.

It's a follow up question of In a release build by GCC, i.e., without -g flag, is register info trustable?, thanks for the answer of it, I now understand that the registers designated for function args might be broken.

Furthermore, during my investigation on the crash of release build(where no debug info is available), I suspect that the callstack itself is broken too, as some function calls seem to be missed, that is, the callstack shows in GDB is not reachable according to source code, some necessary frames that may finally lead to the deepest frame are missed.

Recalling my already rusted knowledge about computer arch, the function frames should be stored in memory and specific registers, e.g., Program Counter(PC) register, etc. I wonder is it possible that those registers compromised too? or is there any other issue for which GDB is unable to trace back the real callstack?

UPDATE #1:

Checking by layout asm, I can see the expected next frame, i.e,. the function missed, see below, note that for confidentiality purpose I replaced the function name, but the register and address are real, just in case it does matter to resolve this issue:

0x210fe9d <OBFUSCATEDiib+894> call 0x210ea10 <_ZTheFuncIAssumedMissed>
0x210fea0 <OBFUSCATEDiib+899> mov %rax,%rdi

But by backtrace, the function is indeed absent... I got even more confused, what may be happening here?

UPDATE #2:

Just confirmed the build with debug info can correctly show the backtrace.

Share Improve this question edited Mar 28 at 10:32 PkDrew asked Mar 26 at 10:17 PkDrewPkDrew 9472 gold badges7 silver badges23 bronze badges 17
  • 3 If some frames are missing from the callstack than it is likely that the compiler has inlined the calls. – gerum Commented Mar 26 at 10:25
  • 1 "unreachable callstack" - does it just skip steps (inlined calls) or is it genuinely nonsensical? (overwritten stack and/or heavy UB like -Werror=return-type) – teapot418 Commented Mar 26 at 10:29
  • 1 Whether the functions are inlined has nothing (well, little) to do with whether they are declared inline. It is completely valid (and common) for a compiler to inline a function not declared inline. – Weijun Zhou Commented Mar 26 at 10:32
  • 5 An inlined call in one place may still generate an externally callable version of the function in case someone else needs it. So no. – teapot418 Commented Mar 26 at 10:35
  • 1 You can compile optimised code with -g. Is there a reason not to do that? It won't directly address your specific issue but it should help in other ways – catnip Commented Mar 26 at 16:50
 |  Show 12 more comments

1 Answer 1

Reset to default 1

why function frame is missed in backtrace of GDB?

There are two main reasons:

  • the function was inlined
  • the function used tail call optimization

Building with -g (as you were advised in comments) helps with inlining -- GDB will be able to display inlined frames using the debug info provided by the compiler with -g.

But -g will not help with tail call optimization (where the compiler transforms int foo() { return bar(); } into foo: JMP bar and all traces of foo being called are erased).

本文标签: