2011-07-19 54 views
4

我從同事那裏收到了我的程序(運行在RHEL 5.3上的qt應用程序)的回溯,當我分析它時,發現了一些我無法解釋的東西。如果你看這個回溯,你會注意到main和_start的蹤跡。但在此之前,我們會看到_ZN19datalog_render_area9prepStripEh和_ZN12QMutexLockerD1Ev,它們位於我的程序中。如何在_start和main之前看到我的一些函數被調用。這不是不可能的嗎? (請原諒我回溯的佈局)_start和主回溯函數調用

 
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 

...函數調用程序

 
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 

回答

2

最有可能的是,你看到垃圾堆棧上。爲了獲得精確的堆棧跟蹤,調試器需要幀指針(通常在x86上省略以保存寄存器)或調試信息。如果沒有這些信息,它會試圖猜測 - 它掃描堆棧中的指針,看起來像一個類似於代碼的地址,並盡力將它們與它們所屬的函數進行匹配。

正如其他人所提到的,靜態初始化可能導致代碼在main之前執行,但此代碼已返回點main正在運行,因此它們沒有業務處於真正的堆棧跟蹤中。我會說,很可能,除了_start之外的所有東西都是垃圾數據,可以安全地忽略。

+0

這是一個很好的想法。我以300的深度調用回溯函數,所以我可能像你說的,看着垃圾。現在我想到了,當我在那裏重新創建時,確保在qt creator調試器窗口中堆棧非常短。 –

1

這是可能的外面。例如,可以將這些函數作爲某些靜態存儲持續時間對象的動態初始化的一部分來調用。

玩具例子:

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

int 
main() 
{} 
+2

確實可以存在靜態初始化器,但由於它們在main之前返回,所以它不應出現在main的精確堆棧軌跡上。 – bdonlan

1

看起來你有一個具有靜態數據成員的類。該靜態數據成員的構造函數調用QMutexLocker。靜態數據成員在調用main()之前構造。

+0

我將繼續修改_ZN19datalog_render_area9prepStripEh,直到它不再是靜態的。有另一個線程訪問另一個對象的數據成員,這個特定變量可以很好地被另一個線程同時寫入/讀取。這應該導致 –

+0

我也經歷了整個代碼,發現我擺脫了2個靜態成員。 thx –

+0

_ZN12QMutexLockerD1Ev是一個析構函數,而不是構造函數。 – bdonlan