Просто хотел отметить кое-что, что меня сбивает с толку всякий раз, когда я возвращаюсь к этой теме (обратите внимание, я сейчас на Ubuntu 14.04, GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1):
Во-первых, есть упоминания о том, что "можно вызвать gdb
в качестве интерпретатора":
... это означает, что можно было бы написать текстовый файл сценария со строкой shebang #!/usr/bin/gbd -P
или #!/usr/bin/gbd --python
, затем написать в нем код Python, затем сделать его исполняемым chmod +x pygdbscript
, затем запустить ./pygdbscript
; ... но как в этом посте:
..., я получаю gdb: unrecognized option '--python'
, если попробую что-нибудь подобное. По-видимому, эта опция есть/была функцией в какой-то ветке "лучников" gdb
?!
Итак, чтобы запустить Python-скрипт в gdb
, на самом деле есть два пути:
- Назовите файл сценария с расширением
.py
; скажи test.py
здесь:
def Something():
print("hello from python")
Something()
gdb.execute("quit");
Обратите внимание, что в этом случае вы просто пишете простой код Python; и вам не нужно import gdb
для доступа к объекту gdb
. Это вы можете запустить с помощью любого из:
gdb -x test.py
gdb -x=test.py
gdb --command test.py
gdb --command=test.py
gdb -command test.py
gdb -command=test.py
... которые кажутся эквивалентными, так как результатом для любого из них является одна и та же распечатка, прежде чем gdb
получает указание выйти из сценария:
$ gdb -x=test.py
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1
...
For help, type "help".
Type "apropos word" to search for commands related to "word".
hello from python
ПРИМЕЧАНИЕ, что в этом случае такие имена, как test.gdb.py
, будут интерпретироваться как чистые скрипты Python, поскольку в этом случае они заканчиваются на .py
.
- Назовите свой скрипт как угодно, если он не не заканчивается расширением
.py
; скажите test.pygdb
здесь:
python
def Something():
print("hello from python")
Something()
gdb.execute("quit");
end
В этом случае gdb
интерпретирует сценарий как сценарий gdb
, т. е. с gdb
командами, и это означает, что любой код Python, который вы хотите написать здесь, должен быть обернут в "python
" как начальная строка и «end
» в конце кода Python. Опять же, он будет вызываться любым из этих эквивалентных вызовов:
gdb -x test.pygdb
gdb -x=test.pygdb
gdb --command test.pygdb
gdb --command=test.pygdb
gdb -command test.pygdb
gdb -command=test.pygdb
... и тогда вывод будет таким же, как и в предыдущем случае (поскольку это тот же самый скрипт Python):
$ gdb -x test.pygdb
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1
...
hello from python
И в ответ на OP: если код C в OP находится в /tmp/myprog.c
- с добавленным int start_test() { return rand() % 50; }
сверху, иначе он не будет компилироваться - и компилируется с gcc -g myprog.c -o myprog.exe
в /tmp/myprog.exe
; то вы можете использовать сценарий myprog.gdb.py
следующим образом:
# need to specify the executable file which we debug (in this case, not from command line)
# here `gdb` command `file` is used - it does not have a Python equivalent (https://sourceware.org/gdb/onlinedocs/gdb/Objfiles-In-Python.html#index-Objfile_002eframe_005ffilters)
# so we must use gdb.execute:
myexefile="/tmp/myprog.exe"
print("""
### myprog.gdb.py is running: """ + myexefile + """ - and adding breakpoints:
""")
gdb.execute("file " + myexefile)
gdb.execute("set pagination off")
ax = gdb.Breakpoint("test_success")
bx = gdb.Breakpoint("test_failed")
gdb.execute("run")
# here the program will break, so we can do:
print("""
### myprog.gdb.py after the break - current stack frame:
""")
current_frame_at_break = gdb.selected_frame()
print(current_frame_at_break) # instead of gdb.execute("frame")
print("""
### myprog.gdb.py - backtrace:
""")
gdb.execute("backtrace 2")
print("""
### myprog.gdb.py - go to frame that called current frame:
""")
parent_frame = current_frame_at_break.older()
print(parent_frame)
status_var = parent_frame.read_var("status")
print("status_var is: ", status_var)
... затем запустите этот скрипт с помощью:
$ gdb -x myprog.gdb.py
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1
....
For help, type "help".
Type "apropos word" to search for commands related to "word".
### myprog.gdb.py is running: /tmp/myprog.exe - and adding breakpoints:
Breakpoint 1 at 0x400565: file myprog.c, line 8.
Breakpoint 2 at 0x40055f: file myprog.c, line 4.
Breakpoint 2, test_failed () at myprog.c:4
4 while(1);
### myprog.gdb.py after the break - current stack frame:
{stack=0x7fffffffdc70,code=0x40055b,!special}
### myprog.gdb.py - backtrace:
#0 test_failed () at myprog.c:4
#1 0x000000000040058c in main () at myprog.c:15
### myprog.gdb.py - go to frame that called current frame:
{stack=0x7fffffffdc90,code=0x400567,!special}
status_var is: 33
(gdb)
Обратите внимание, что в конце этого сценария интерактивная подсказка (gdb)
остается, и вы можете использовать ее здесь как обычно; если вам не нужна интерактивная подсказка, вы можете сделать gdb.execute("quit");
, как в приведенных выше сценариях, чтобы заставить gdb
выйти вместо этого в конце выполнения сценария.
Кроме того, пример подкласса класса точки останова в gdb Python см. в разделе Как напечатать текущую строку исходного кода в точке останова в GDB и ничего больше?
person
sdaau
schedule
17.10.2017