2011-06-07 45 views
3

我想模擬一個函數(用於單元測試父函數)使用GDB。一種方法是在你打算模擬的函數中設置一個斷點,並使用GDB 返回命令。GDB腳本MOCK

但是,當GDB 調用命令被使用時,我無法做到這一點。

 
(gdb) b secret_check 
Breakpoint 1 at 0x80483ba: file ut_gdb.c, line 6. 
(gdb) start 
Temporary breakpoint 2 at 0x804843c: file ut_gdb.c, line 34. 
Starting program: ut.bin 
Temporary breakpoint 2, main() at ut_gdb.c:34 
34   int res = 0; 
(gdb) bt 
#0 main() at ut_gdb.c:34 
(gdb) call fact(3) 
Breakpoint 1, secret_check (check_type=1) at ut_gdb.c:6 
6    if(check_type == 0){ 
The program being debugged stopped while in a function called from GDB. 
Evaluation of the expression containing the function 
(fact) will be abandoned. 
When the function is done executing, GDB will silently stop. 
(gdb) bt 
#0 secret_check (check_type=1) at ut_gdb.c:6 
#1 0x080483ff in fact (n=3) at ut_gdb.c:19 
#2 
#3 main() at ut_gdb.c:34 

這是GDB的限制嗎?

回答

0

我期待如此。限制可能是GDB不能在一次停止(並且能夠繼續)兩個斷點。 GDB必須保留有關程序停止的當前點的信息,以便能夠繼續。爲了支持你想要做的事情,它需要保持一堆「繼續」狀態,並且有一些能力讓你指定你想要繼續的狀態。

+0

是否容易增加這個功能到GDB? – Kamath 2011-06-08 05:53:55

+0

我不是GDB開發者,所以我不知道。但是我的猜測是,從與他們一起工作的角度來看,這將是非常困難的。假設有一個單獨的「繼續」狀態而不是它們的列表 - 如果我猜測其中只有一個是正確的 - 可能會在整個程序中出現在各種地方, d必須找到並解決所有這些問題。如果很容易,有人可能已經修好了。 – 2011-06-10 01:55:22

0

有可能與GDB的Python接口來做到這一點:

import gdb 

class MyBreak(gdb.Breakpoint): 
    def __init__(self, spec): 
    gdb.Breakpoint.__init__(self, spec) 
    self.silent = True 

    def stop(self): 
    #do whatever you need 

    return False 

MyBreak("secret_check") 

你必須要小心你的stop回調做的,不是一切是合法的。 我並不意味着它不會工作,但它可能崩潰和/或在未來的版本,例如改變:

def stop(self): 
    print gdb.selected_thread().is_running() # True 
    gdb.execute("return 5") #working, but you're not really supposed to do it! 
    ... 

在即將到來的7.4版本的GDB中,FinishBreakpoint應該能夠幫助你很多與你的模擬功能(只是一個例子,我沒有測試它):

class MyFinishBreakpoint (gdb.FinishBreakpoint) 
    def __init__(self, param): 
    gdb.FinishBreakpoint() 
    self.param = param 

    def stop (self): 
    #change self.param as you want 
    return False 

class MyBreak(gdb.Breakpoint): 
    def stop(self): 
    #read parameters according to calling conventions 
    param = gdb.parse_and_eval("...") 
    MyFinishBreakpoint(param) 

    return False 
+0

哦,哇,我今天嘗試這個。我很遲纔看到這個回覆很安靜。 – Kamath 2012-05-03 08:24:20

0

你確定這不工作?只要忽略你得到的長信息。

對於我的情況fn1調用fn2。我想測試fn1和模擬fn2:

b fn2 
call fn1 
// gdb stops on the breakpoint 
return somevalue 
c 

而且一切似乎都沒問題。 (我用的cygwin的gdb 7.8。)


請看看: Debugging a programmatically called function with GDB