2013-12-09 73 views
5
define traverse 
    while(CONDITION) 
     if $start == 0 
      set $start = 1 
      print_node 
      print_rss_item 
     else 
      continue 
      print_node 
      print_rss_item 
     end 
    end 
end 

如果程序結束,我需要什麼條件來停止循環?如何循環GDB腳本直到程序結束?

+0

我假設'$ start = 1'是停止循環的子句。所以你想'while($ start == 0)'?這個鏈接應該有助於https://sourceware.org/gdb/onlinedocs/gdb/Command-Files.html – KeithSmith

回答

0

簡單地在無限循環中循環。程序結束後它將退出。

define traverse 
    while(1) 
     if $start == 0 
      set $start = 1 
      print_node 
      print_rss_item 
     else 
      continue 
      print_node 
      print_rss_item 
     end 
    end 
end 
5

看着你的GDB腳本:

define traverse 
    while(CONDITION) 
     if $start == 0 
      set $start = 1 
      print_node 
      print_rss_item 
     else 
      continue 
      print_node 
      print_rss_item 
     end 
    end 
end 

有幾件事情需要注意:

  1. GDB的腳本(所謂的 「調試」)和調試中的反覆一直運行模式:WHENEVER THE GDB SCRIPT RUN,調試對象暫停且不運行,每當DEBUGGEE運行時,gdb腳本暫停且不運行。

  2. 這是爲什麼呢?這是因爲每當調試對象處於暫停模式(讀取「ptrace()」API及其各種選項:PEEKUSER,POKEUSER,PTRACE_CONT)時,調試器實際上可以乾淨地(和內存一致地)讀取調試對象的內存,腐敗,因此,所有的變量值等

調試時沒有運行,也就是說,它執行「繼續」操作,其中控制傳遞給調試,調試對象因此可以繼續運行和變化它自己的記憶,而不用擔心錯誤地被另一個進程讀取 - 因爲它不會發生。

那麼我們怎麼知道調試對象何時結束?當「繼續」失敗時,gdbscript不會繼續運行。但是如果你設置一個沒有任何斷點的調試對象,那麼執行gdb「run」命令,你會發現調試對象連續運行,沒有gdb腳本有機會執行。

如果你的腳本正在運行,那麼debuggee處於STOP模式,反之亦然。如果調試對象通過調用exit()結束,那麼gdb腳本也不會運行。

如:

defining the macro (inside .gdbinit file): 

define myloop_print 
set $total = $arg0 
set $i = 0 
    while($i<$total) 
    set $i = $i + 1 
    print $i, $i 
    cont 
    end 
end 

,然後運行 ​​「GDB /斌/ LS」,後 「破寫入」 和 「運行-al」,然後 「myloop_print 10000」(序列或順序很重要) ,我們可以看到每個「寫入」都會打破,gdbscript會打印出計數器。

而在去年執行的幾行:

Breakpoint 1, write() at ../sysdeps/unix/syscall-template.S:81 
81 in ../sysdeps/unix/syscall-template.S 
$40571 = 285 
drwxrwxr-x 2 tthtlc tthtlc 4096 Feb 18 00:00 yocto_slide 
[Inferior 1 (process 7395) exited normally] 
$40572 = 286 
The program is not being run. 
(gdb) 

這清楚地表明,最後打印的計數器是286,即使我已經指定爲10000極限。

運行宏沒有調試運行:

(gdb) myloop_print 10000 
$40573 = 1 
The program is not being run. 
(gdb) 

我們可以看到,gdbscript將無法運行。

如果你做的是「gdb/bin/ls」,然後是「myloop_print 10000」(假設宏定義在.gdbinit裏面),那麼你將得到gdbscript運行完成10000循環 - 沒有運行調試對象。