This is the mail archive of the
gdb@sourceware.org
mailing list for the GDB project.
problems with async mode using user-defined or python command sequences
- From: Tim Black <timblaktu at gmail dot com>
- To: gdb at sourceware dot org
- Date: Wed, 23 May 2012 11:36:43 -0700
- Subject: problems with async mode using user-defined or python command sequences
I'm using gdb 7.4.1 on embedded powerpc target and 2.6.32.28 kernel to
perform some analysis on my multi-threaded C++ program that uses
pthreads. My end goal was to script gdb with python to automate some
common analysis functions, and create a crude profiler by sampling the
stack of the active thread. The problem is that I am finding some
discrepancy in behavior when I run commands individually at the
command line vs. in a gdb user-defined command (or invoking the same
commands via python script). I found a reference to a very similar
problem on this mailing list:
http://sourceware.org/ml/gdb/2009-01/msg00157.html
Although I don't completely follow Pedro's response about the
limitation of async mode, I think he's implying that in async mode,
the relative timing of user-defined command sequences cannot be
trusted. This is what I found empirically.
In both scenarios, I perform the following start-up steps, loading my
program, setting its args, and turning on asynchronous and non-stop
debugging modes, then running the program in the background:
(gdb) file myprogram
(gdb) set args --interface=eth0 --try-count=0
(gdb) set target-async on
(gdb) set pagination off
(gdb) set non-stop on
(gdb) run &
At this point, if I manually issue "interrupt" and then "info threads"
commands, I see the list of all threads running except one that got
stopped. Then I can continue & and repeat to my hearts content, it
works consistently. When stopped, I can inspect that thread's stack
frames and all is well.
However, if instead I put these commands into a user-defined gdb command:
(gdb) define foo
(gdb) interrupt
(gdb) info threads
(gdb) continue &
(gdb) end
(gdb) foo
Cannot execute this command while the selected thread is running.
I believe the error msg is caused by the "continue &" command, because
the preceding "interrupt" did not stop any threads (yet). I thought
this was a problem inherent to the asynchronous gdb commanding, so I
inserted an absurdly long wait after the interrupt command and got the
same behavior:
(gdb) define foo
(gdb) interrupt
(gdb) shell sleep 5
(gdb) info threads
(gdb) continue &
(gdb) end
(gdb) foo
Cannot execute this command while the selected thread is running.
With or without the sleep command, I can always issue the manual CLI
commands and the threads get stopped correctly.
Similarly, I get the same results sourcing a python script to do the
thread perusal:
import gdb, time
gdb.execute("file myprogram")
gdb.execute("set args --interface=eth0 --try-count=0")
gdb.execute("set target-async on")
gdb.execute("set pagination off")
gdb.execute("set non-stop on")
gdb.execute("run &")
time.sleep(5)
gdb.execute("interrupt")
# here, I inspect threads via gdb module interface
# in practice, they're always all running bc the program never got interrupted
for thread in gdb.selected_inferior().threads():
print thread.is_running(),
gdb.execute("continue &")
I get the same result even if I specify from_tty=True in the
gdb.execute calls. Also, if I use continue -a it suppresses the error
string but does not help otherwise bc the interrupt call still doesn't
work.
So... is this:
* cockpit error? Is there something that I'm omitting or doing
incorrectly, given what I'm trying to accomplish? Should this work, or
do I have to use GDB/MI to asynchronously "drive" gdb like this?
* a timing problem? Maybe invoking shell sleep (or python
time.sleep()) doesn't do what I assume it would, in this context.
* a gdb problem?
Thanks.