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
What condition do I need to stop the loop if the program is finished?
Looking at your gdb script:
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
Several things to note:
The gdb script (so called "debugger") and debuggee are always operating in a toggling mode: WHENEVER THE GDB SCRIPT RUN, the debuggee is paused and NOT running, and whenever the DEBUGGEE is running, the gdb script is paused and NOT RUNNING.
Why is this so? This is because whenever the debuggee is in paused mode (read up "ptrace()" API and its various option: PEEKUSER, POKEUSER, PTRACE_CONT) the debugger actually can cleanly (and memory-consistently) read the memory of the debuggee without fear of corruption, and thus all its variables values etc.
When debugger is not running, ie, it executed the "continue" operation, where control is passed to the debuggee, the debuggee can thus continue to run and change its own memory, without fear of wrongly being read by another process - because it cannot happened.
So how do we know when the debuggee has ended? When "continue" failed and thus the gdbscript will not continue running. But if you setup a debuggee without any breakpoints, then executing the gdb "run" command you will find the the debuggee run continuously, without the gdb script having a chance to execute.
So effectively if your script is running, then debuggee is in STOP mode, and vice versa. And if the debuggee has ended by calling exit(), the gdb script will not be running as well.
eg:
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
And then running "gdb /bin/ls" and followed by "break write" and "run -al" and then "myloop_print 10000" (the sequence or order is important), we can see that every "write" it will break and gdbscript will print out the counter.
And last few lines executed are:
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)
Which clearly shows that the last counter printed is 286, even though I had specified 10000 as the limit.
Running the macro without the debuggee running:
(gdb) myloop_print 10000
$40573 = 1
The program is not being run.
(gdb)
We can see that the gdbscript will not run.
And if you do "gdb /bin/ls" and followed by "myloop_print 10000" (assuming the macro is defined inside .gdbinit) then you will get gdbscript running to completion 10000 loops - without the debuggee ever running.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With