2013-12-09 11 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 

Tôi cần dừng điều kiện nào nếu chương trình kết thúc?Làm thế nào để lặp trong một kịch bản GDB cho đến khi chương trình kết thúc?

+0

Tôi giả sử rằng '$ start = 1' là mệnh đề dừng vòng lặp. Vì vậy, bạn muốn 'while ($ start == 0)'? Liên kết này sẽ giúp https://sourceware.org/gdb/onlinedocs/gdb/Command-Files.html – KeithSmith

Trả lời

0

Chỉ cần lặp trong vòng lặp vô hạn. Nó sẽ thoát khi chương trình kết thúc.

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

Nhìn vào kịch bản gdb của bạn:

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 

Một số điều cần lưu ý:

  1. Kịch bản gdb (cái gọi là "gỡ rối") và debuggee luôn hoạt động trong một toggling mode: WHENEVER THE GDB SCRIPT RUN, debuggee bị tạm dừng và NOT running, và bất cứ khi nào DEBUGGEE đang chạy, script gdb bị tạm dừng và NOT RUNNING.

  2. Tại sao lại như vậy? Điều này là bởi vì bất cứ khi nào debuggee ở chế độ bị tạm dừng (API "ptrace()" đọc và tùy chọn khác nhau của nó: PEEKUSER, POKEUSER, PTRACE_CONT) trình gỡ rối thực sự có thể sạch (và bộ nhớ nhất quán) đọc bộ nhớ của debuggee mà không sợ tham nhũng, và do đó tất cả các biến giá trị của nó vv

Khi gỡ lỗi không chạy, tức là, nó thực sự "tiếp tục" hoạt động, nơi điều khiển được chuyển đến debuggee, các debuggee do đó có thể tiếp tục chạy và biến đổi bộ nhớ riêng của nó, mà không sợ bị đọc sai bởi quá trình khác - bởi vì nó không thể xảy ra được.

Vậy làm thế nào để chúng ta biết khi nào debuggee kết thúc? Khi "tiếp tục" không thành công và do đó gdbscript sẽ không tiếp tục chạy. Nhưng nếu bạn thiết lập một debuggee mà không có bất kỳ breakpoint nào, sau đó thực hiện lệnh gdb "run" bạn sẽ thấy debuggee chạy liên tục, không có script gdb nào có cơ hội thực thi.

Vì vậy, hiệu quả nếu tập lệnh của bạn đang chạy, khi đó debuggee đang ở chế độ STOP và ngược lại. Và nếu debuggee đã kết thúc bằng cách gọi exit(), tập lệnh gdb cũng sẽ không chạy.

ví dụ:

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 

Và sau đó chạy "gdb/bin/ls" và tiếp theo là "phá vỡ ghi" và "chạy-al" và sau đó "myloop_print 10000" (chuỗi hoặc trật tự là rất quan trọng) , chúng ta có thể thấy rằng mỗi "viết" nó sẽ phá vỡ và gdbscript sẽ in ra quầy.

Và cuối cùng vài dòng thực hiện là:

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) 

nào rõ ràng cho thấy rằng bộ đếm cuối cùng in là 286, mặc dù tôi đã quy định 10000 là giới hạn.

Chạy vĩ mô mà không debuggee chạy:

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

Chúng ta có thể thấy rằng gdbscript sẽ không chạy.

Và nếu bạn thực hiện "gdb/bin/ls" và tiếp theo là "myloop_print 10000" (giả sử macro được xác định bên trong .gdbinit) thì bạn sẽ nhận được gdbscript chạy để hoàn thành 10000 vòng - mà không có debuggee chạy.

Các vấn đề liên quan