Просто хотел отметить кое-что, что меня смущает, когда я возвращаюсь к этой теме (заметьте, я сейчас нахожусь на Ubuntu 14.04, GNU gdb (Ubuntu 7.7.1-0ubuntu5 ~ 14.04.3) 7.7.1):
Во-первых, есть упоминания о том, что " можно вызвать gdb
в качестве интерпретатора ":
... означает, что можно написать текстовый файл сценария со строкой шебанга #!/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 и ничего больше?