4

I received a backtrace of my program (qt app running on RHEL 5.3) from a coworker and as I was analyzing it I found something I could not explain. If you look at this backtrace, you will notice the trace for main and _start. But before that we see _ZN19datalog_render_area9prepStripEh and _ZN12QMutexLockerD1Ev which are in my program. How can I see some of my functions getting called before the _start and main. Isn't that impossible? (pardon the layout of my backtrace)

Funct Addr| Instr. Addr | FunctionSymbol  
----------|-------------|----------------------------------------------------------|  
0x8060bf2 | 0x8060dc0   | _Z11print_tracev  
0x8061386 | 0x806141c   | _Z15myMessageOutput9QtMsgTypePKc  
0x822b558 | 0x822b598   | _ZN5QListIP13QStandardItemEixEi  
0x8229ece | 0x8229f0b   | _ZN12vehicleModel14updHeaderModelEP5QListIjE  
0x822be7e | 0x822bf64   | _ZN14vehTableWidget19updVehicleTabLayoutEib  
0x822c668 | 0x822c8e7   | _ZN14vehTableWidget13setupVehTableEib  
0x82845f8 | 0x82846fc   | _ZN14vehTableWidget11qt_metacallEN11QMetaObject4CallEiPPv

...function calls outside the program

0x8060e86 | 0x80612ce | main  

_____________________|____________________|address outside of program: 4804252  

0x8060a70 | 0x8060a91 | _start  

_____________________|____________________|address outside of program: 3218418744  

0x808df02 | 0x808df13 | _ZN12QMutexLockerD1Ev    

_____________________|____________________|address outside of program: 3218420336  
_____________________|____________________|address outside of program: 152429104  
_____________________|____________________|address outside of program: 3218420552  

0x8208fa6 | 0x820acd0 | _ZN19datalog_render_area9prepStripEh  

_____________________|____________________|address outside of program: 3218420336  
_____________________|____________________|address outside of program: 3218420500  
yan bellavance
  • 4,710
  • 20
  • 62
  • 93

3 Answers3

2

Most likely, you're seeing garbage on the stack. In order to get an accurate stack trace, the debugger needs either frame pointers (often omitted on x86 to save a register) or debug information. Without this information, it tries to guess - it scans through the stack for pointers that look sorta-kinda-like code addresses, and does its best to match them to the functions they belong to.

As others have mentioned, static initialization can cause code to be executed before main, but this code has returned by the point main is run, so they have no business being on the true stack trace. I would say that, most likely, everything beyond _start is garbage data and can be safely ignored.

bdonlan
  • 224,562
  • 31
  • 268
  • 324
  • that's a good thought. I am calling the backtrace function with a depth of 300 so I am probably like you say, looking at garbage. Now that I think of it, im sure the stack was very short in the qt creator debugger window when I recreated it there. – yan bellavance Jul 20 '11 at 05:30
1

It's possible. For instance these functions could be called as part of the dynamic initialization of some static storage duration object.

Toy example:

const bool i = []() -> bool
{
    // arbitrary code here
    return true;
}();

int
main()
{}
Luc Danton
  • 34,649
  • 6
  • 70
  • 114
  • 2
    It's true that static initializers may exist, but since they return before main, it shouldn't appear on an accurate stack trace of main. – bdonlan Jul 20 '11 at 03:50
1

It looks like you have a class that has a static data member. The constructor for that static data member is calling QMutexLocker. Static data members are constructed before main() is called.

David Hammen
  • 32,454
  • 9
  • 60
  • 108
  • I'll work on modifying _ZN19datalog_render_area9prepStripEh until it doesn't have to be static anymore. There is an access to a data member from another object which is another thread and this specific variable can very well be written/read simultaneously by this other thread. That should lead to something – yan bellavance Jul 20 '11 at 03:43
  • i also went through the whole code and found 2 static members I got rid of. thx – yan bellavance Jul 20 '11 at 03:47
  • _ZN12QMutexLockerD1Ev is a destructor, not a constructor. – bdonlan Jul 20 '11 at 03:52
  • 1
    @yan, also, static members aren't the same thing as static constructors. Static constructors are when you have a static _data_ member, or a static _global (or file-scope) variable_, which has a type with a constructor. – bdonlan Jul 20 '11 at 04:00
  • @bdonlan, where can I find the meaning of those characters wrapping the symbol name, in this case ZN12 and D1Ev – yan bellavance Jul 20 '11 at 16:32
  • 1
    @yan, use the `c++filt` utility – bdonlan Jul 20 '11 at 16:53
  • 1
    Or just do the demangling by hand: http://www.codesourcery.com/public/cxx-abi/abi.html#demangler . `_ZN`=this is a nested mangled name. `12QMutexLocker`: The class. `D1`: The complete object destructor. `E`: End of function name. `v`: void arguments. In other words, `_ZN12QMutexLockerD1Ev` means `~QMutexLocker()`. Similarly, `_ZN19datalog_render_area9prepStripEh` is `datalog_render_area::prepStrip(unsigned char)`. – David Hammen Jul 20 '11 at 17:15