Why GDB jumps unpredictably between lines and prints variables as “”?

后端 未结 8 1095
伪装坚强ぢ
伪装坚强ぢ 2020-12-02 05:10

Can anyone explain this behavior of gdb?

900         memset(&new_ckpt_info,\'\\0\',sizeof(CKPT_INFO));
(gdb)
**903         prev_offset   = cp_node->of         


        
相关标签:
8条回答
  • 2020-12-02 05:36

    When debugging optimized programs (which may be necessary if the bug doesn't show up in debug builds), you often have to understand assembly compiler generated.

    In your particular case, return value of cpnd_find_exact_ckptinfo will be stored in the register which is used on your platform for return values. On ix86, that would be %eax. On x86_64: %rax, etc. You may need to google for '[your processor] procedure calling convention' if it's none of the above.

    You can examine that register in GDB and you can set it. E.g. on ix86:

    (gdb) p $eax
    (gdb) set $eax = 0 
    
    0 讨论(0)
  • 2020-12-02 05:40

    Declare found as "volatile". This should tell the compiler to NOT optimize it out.

    volatile int found = 0;
    
    0 讨论(0)
  • 2020-12-02 05:43

    Im using QtCreator with gdb.

    Adding

    QMAKE_CXXFLAGS += -O0
    QMAKE_CXXFLAGS -= -O1
    QMAKE_CXXFLAGS -= -O2
    QMAKE_CXXFLAGS -= -O3
    

    Works well for me

    0 讨论(0)
  • 2020-12-02 05:44

    To debug optimized code, learn assembly/machine language.

    Use the GDB TUI mode. My copy of GDB enables it when I type the minus and Enter. Then type C-x 2 (that is hold down Control and press X, release both and then press 2). That will put it into split source and disassembly display. Then use stepi and nexti to move one machine instruction at a time. Use C-x o to switch between the TUI windows.

    Download a PDF about your CPU's machine language and the function calling conventions. You will quickly learn to recognize what is being done with function arguments and return values.

    You can display the value of a register by using a GDB command like p $eax

    0 讨论(0)
  • 2020-12-02 05:48

    You pretty much can't set the value of found. Debugging optimized programs is rarely worth the trouble, the compiler can rearrange the code in ways that it'll in no way correspond to the source code (other than producing the same result), thus confusing debuggers to no end.

    0 讨论(0)
  • 2020-12-02 05:51

    Typically, boolean values that are used in branches immediately after they're calculated like this are never actually stored in variables. Instead, the compiler just branches directly off the condition codes that were set from the preceding comparison. For example,

    int a = SomeFunction();
    bool result = --a >= 0; // use subtraction as example computation
    if ( result ) 
    {
       foo(); 
    }
    else
    {
       bar();
    }
    return;
    

    Usually compiles to something like:

    call .SomeFunction  ; calls to SomeFunction(), which stores its return value in eax
    sub eax, 1 ; subtract 1 from eax and store in eax, set S (sign) flag if result is negative
    jl ELSEBLOCK ; GOTO label "ELSEBLOCK" if S flag is set
    call .foo ; this is the "if" black, call foo()
    j FINISH ; GOTO FINISH; skip over the "else" block
    ELSEBLOCK: ; label this location to the assembler
    call .bar
    FINISH: ; both paths end up here
    ret ; return
    

    Notice how the "bool" is never actually stored anywhere.

    0 讨论(0)
提交回复
热议问题