2015-04-29 78 views
0

爲了使用g ++(即選項「-O0 -ggdb」)和使用最新的gcc(5.1.0)和gdb(7.9)進行調試而構建的C++代碼,在使用「next」命令時,gdb中的代碼仍然非常非線性。作爲一個例子該函數調用可以預料與步驟通過一個單一的「下一個」:在gdb中避免源代碼級別的「跳躍」

7757| SDValue NewRoot = TLI->LowerFormalArguments(
7758|  DAG.getRoot(), F.getCallingConv(), F.isVarArg(), Ins, dl, DAG, InVals); 

然而它需要四個,與所顯示的執行線是第一7757,然後7758,然後再次7757,然後再次7758 。如果函數調用被壓縮到一行,那麼只需要一個「下一個」。如果呼叫是荒謬的膨脹則需要七「下一個」 S(顯示爲「#」註釋)

 7757| SDValue 
     7758| NewRoot 
     7759| = 
    #1,6 7760| TLI 
     7761| -> 
     7762| LowerFormalArguments(
    #5 7763|  DAG.getRoot(), 
     7764| F.getCallingConv(), 
    #3 7765| F.isVarArg(), 
     7766| Ins, 
     7767| dl, 
     7768| DAG, 
     7769| InVals 
#2,4,7 7770|); 

因此它有關,但不作爲「在不同線上的每個函數調用一樣簡單是步進點」。這會讓遞歸函數中的斷點變得特別混亂,我發現自己檢查了callstack,看它是真的是一個新的調用還是一個虛假的向後步驟。

由於將所有LLVM源重新包含在一行中的函數調用並不是一個真正可行的選項,是否有一些gcc/gdb選項用於控制此行爲?

編輯:現在與鐺3.5和lldb 3.5檢查:當與鐺建立時,只有三個「下一個」發生。 gdb和lldb在這兩種情況下都會看到相同的「下一個」行爲(即,4與gcc,3與clang)

回答

0

調試器的這種行爲是「GIGO」情況 - 也就是說,通常gdb只是做任何調試信息告訴它做的事情。也就是說,當出現奇怪的行爲時,通常是由於編譯器做出的決定。這可能是一個錯誤,也許值得一個錯誤報告,但如果它出於某種原因打算以這種方式工作,我也不會感到驚訝。

您可以通過使用readelfobjdump來檢查線表,以調查這些類型的問題。

+0

從'readelf --debug-dump'中可以看出,clang發出了比X更快的「advance by X and Line by Y」DWARF操作碼,而不是gcc對相同的代碼塊所做的操作,但是對於這兩種編譯器,在這種情況發生時不可預測(例如,自動對象的析構函數是否會在範圍末尾獲得單獨的「advance」) –

+0

但是,在DWARF-land中漫遊(無知)時,顯然調試器無法忽略這些中間進展,即在那裏似乎沒有任何特定於「下一個語句」命令可以利用的語句終止符的任何東西。所以編譯器會改變提前操作碼的粒度,我猜gcc和clang當前都沒有暴露控制權 –