问题
I would like to store the executable name of the current inferior in a variable. I way to obtain the executable name in the gdb CLI is the following:
pipe info inferiors | awk '{ if ($1 == "*") { print $4} }'
But I am unable to store the output of this expression in a variable. The expression uses single and double quotes, which makes gdb complain if it is combined with set
and eval
.
(gdb) set $exec="pipe info inferiors | awk '{ if ($1 == "*") { print $4} }'"
Argument to arithmetic operation not a number or boolean.
(gdb) eval "!echo %s", "pipe info inferiors | awk '{ if ($1 == "*") { print $4} }'"
Argument to arithmetic operation not a number or boolean.
Then, how can I store the executable name in a variable? My goal is to pass the executable name to the file
command to reload the executable when Autotools are used (see the motivation).
回答1:
Your best bet is to use embedded Python. Example:
gdb -q ./a.out
Reading symbols from ./a.out...
(gdb) start
Temporary breakpoint 1 at 0x1129: file foo.c, line 3.
Starting program: /tmp/a.out
Temporary breakpoint 1, main () at foo.c:3
3 int v1 = 1, v2 = 2, v3 = 42;
(gdb) info inferiors
Num Description Connection Executable
* 1 process 217200 1 (native) /tmp/a.out
(gdb) python gdb.execute('set $pid = ' + str(gdb.selected_inferior().pid))
(gdb) p $pid
$1 = 217200
Update:
Original question asked for field 4, which is the pid
, but it appears that Gorka was actually interested in the file name, which can be found this way:
(gdb) python gdb.execute('set $f = "' + str(gdb.selected_inferior().progspace.filename) + '"')
(gdb) p $f
$2 = "/tmp/a.out"
Documentation: Inferiors, Progspaces
Update 2:
Now I get the file name again with the field 4... but I was obtaining the pid as you said. I cannot figure why this is happening.
You get pid or name depending on whether the inferior is running or not (that's the danger of parsing data that is intended for humans).
When the inferior is not running, info inferiors
prints:
(gdb) info inferiors
Num Description Connection Executable
* 1 <null> /bin/date
When the inferior is currently active, it prints:
(gdb) info inferiors
Num Description Connection Executable
* 1 process 118431 2 (native) /bin/date
回答2:
Although @EmployedRussian's answer is the most appropriated solution for the use case presented in the question, I think that the question of how to use pipe and awk to set a variable has not been answered yet. This could be done using python and splitting the pipe in two parts:
python res = gdb.execute('info inferiors', to_string=True);
python gdb.execute ('set $exec = "' + str(res.strip().split()[6]) + '"');
If a awk like command is preferred, try with the tools provided by python, for instance, convert res
to a pandas
DataFrame.
Note that, this approach could be catastrophic as has been seen here with the column selection issue.
来源:https://stackoverflow.com/questions/62105922/gdb-set-variable-using-pipe-and-awk