GDB: Set variable using pipe and awk

十年热恋 提交于 2020-06-16 17:27:15

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!