How to trigger a breakpoint in a guile script using gdb? - gdb

gdb has support for guile. I am trying to use the debugging capability.
Here is my attempt:
enter an interactive session with 'gr' command.
load a scheme file.
set a breakpoint to a procedure called create_branches.
finally call create_tree which calls create_branches.
I expect that calling (tree 3) would trigger the breakpoint. But it does not happen? Why?
This is stackoverflow_42404315.scm:
(define (tree n)
(create_trunk)
(create_branches n))
(define (create_trunk)
1)
(define (create_branches n)
n)
This is gdb session:
bash-3.2$ gdb
GNU gdb (GDB) 7.10
(gdb) gr
GNU Guile 2.0.12
scheme#(guile-user)> ,load "stackoverflow_42404315.scm"
scheme#(guile-user)> ,break create_branches
Trap 0: Breakpoint at #<procedure create_branches (n)>.
scheme#(guile-user)> (tree 3)
$1 = 3
scheme#(guile-user)> ,traps
0: Breakpoint at #<procedure create_branches (n)>

Related

GDB failing to record execution in vgdb

I'm trying to use gdb to record the execution in valgrind's gdbserver like so:
valgrind --vgdb-error=0 path/to/binary args
$ gdb path/to/binary
(gdb) target remote | vgdb
0x0000000004001090 in _start () from /lib64/ld-linux-x86-64.so.2
(gdb) target record-full
(gdb) c
Continuing.
/build/gdb-GT4MLW/gdb-8.1/gdb/target.c:3132: internal-error: gdbarch* default_thread_architecture(target_ops*, ptid_t): Assertion `inf != NULL' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Quit this debugging session? (y or n) n
This is a bug, please report it. For instructions, see:
<http://www.gnu.org/software/gdb/bugs/>.
/build/gdb-GT4MLW/gdb-8.1/gdb/target.c:3132: internal-error: gdbarch* default_thread_architecture(target_ops*, ptid_t): Assertion `inf != NULL' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Create a core file of GDB? (y or n) n
Command aborted.
(gdb)
I was hoping to use the recorded execution to set a read/write watchpoint and reverse execute to see where it's used. I've been running with valgrind's gdbserver to break on the SIGTRAP emitted when an invalid read/write occurs.
Is this genuinely a bug, or am I doing something wrong/unsupported?
The valgrind gdbserver does not support record.
See http://www.valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver-limitations

How do I configure GDB correctly, to stop error "You can't do that without a process to debug"

Ubuntu 16.04.4 LTS, GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
I am trying to call a function in a compiled C program and get the following:
"(gdb) call getVarName(someParam)
You can't do that without a process to debug."
There are no other codes or messages.
I can run the program from the shell prompt
jef#ubuntu$ ./program.
I can run the program within gdb after designating the file. Permissions are 777 (just to cover all bases).
Based on research, I set the SHELL with "export SHELL=/bin/bash"
and
set kernal.yama.ptrace_scope = 0 in /etc/sysctl.d/10-ptrace.conf
I still get the same behavior.
I still get the same behavior.
Naturally.
The error you are getting means: you can't do this, unless you are debugging a live process.
This will work:
(gdb) break main
(gdb) run
... GDB is now stopped, *and* you have a live process.
... you *can* call getVarName(...) now
(gdb) call getVarName(...)
(gdb) continue # causes the process to run to end and exit
[Inferior 1 (process 195969) exited normally]
(gdb) # Now you no longer have a live process, so you *again* can't
# call functions in it.

How do you capture console output under debug in clion?

I'm using clion to write a console application. If I simply run the program, I can see the results of my cout calls. But if I debug it, no output occurs under the Debug Console tab other than my exe's name and Process finished with exit code 0. Is there an extra step to get console output to show up under debug in clion?
Or is this not even clion specific and is a general thing people who have been using gdb already know about?
According to the JetBrains'post on clion debugger, you can see the debug output by click the "Console" tab, which is next to "Debugger" tab:
GDB manipulates the process of running a program.
An example of GDB session:
% cat hello.c
#include<stdio.h>
main() {
int count;
for (count=0;count<10;count++)
printf("Hello from CETS!\n");
}
% gcc -g hello.c
% gdb ./a.out
GDB is free software and you are welcome to distribute copies of it
under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.13 (sparc-sun-solaris2.3),
Copyright 1994 Free Software Foundation, Inc...
(gdb) b main
Breakpoint 1 at 0x10784: file hello.c, line 6.
(gdb) r
Starting program: /home1/b/bozo/./a.out
Breakpoint 1, main () at hello.c:6
6 for (count=0;count<10;count++)
(gdb) s
7 printf("Hello from CETS!\n");
(gdb) p count
$1 = 0
(gdb) disp count
1: count = 0
(gdb) set count=8
(gdb) s
Hello from CETS!
6 for (count=0;count<10;count++)
1: count = 8
(gdb)
7 printf("Hello from CETS!\n");
1: count = 9
(gdb) c
Continuing.
Hello from CETS!
Program exited with code 01.
(gdb) q
%
Content that might be helpful for you:
http://www.cs.swarthmore.edu/~newhall/unixhelp/howto_gdb.html
http://www.ifp.illinois.edu/~nakazato/tips/xgcc.html#GDB
http://www.seas.upenn.edu/cets/answers/gcc.html

Run process with gdb and detach it

Is it possible to run a process with gdb, modify some memory and then detach from the process afterwards?
I can't start the process from outside of gdb as I need to modify the memory, before the first instruction is executed.
When you detach from a process started with gdb, gdb will hang, but killing gdb from another process makes the debugged process still running.
I currently use the following script to launch the process:
echo '# custom gdb function that finds the entry_point an assigns it to $entry_point_address
entry_point
b *$entry_point_address
run
set *((char *)0x100004147) = 0xEB
set *((char *)0x100004148) = 0xE2
detach # gdb hangs here
quit # quit never gets executed
' | gdb -quiet "$file"
This happens in both of my gdb versions:
GNU gdb 6.3.50-20050815 (Apple version gdb-1824)
GNU gdb 6.3.50-20050815 (Apple version gdb-1822 + reverse.put.as patches v0.4)
I'm pretty sure that you can't detach from an inferior processes that was started directly under gdb, however, something like the following might work for you, this is based on a recent gdb, I don't know how much of this will work on version 6.3.
Create a small shell script, like this:
#! /bin/sh
echo $$
sleep 10
exec /path/to/your/program arg1 arg2 arg3
Now start this up, spot the pid from echo $$, and attach to the shell script like this gdb -p PID. Once attached you can:
(gdb) set follow-fork-mode child
(gdb) catch exec
(gdb) continue
Continuing.
[New process NEW-PID]
process NEW-PID is executing new program: /path/to/your/program
[Switching to process NEW-PID]
Catchpoint 1 (exec'd /path/to/your/program), 0x00007f40d8e9fc80 in _start ()
(gdb)
You can now modify the child process as required. Once you're finished just do:
(gdb) detach
And /path/to/your/program should resume (or start in this case) running.

How to script gdb (with python)? Example add breakpoints, run, what breakpoint did we hit?

I'm trying to create a little unit test with gdb,
for a embedded mcu that is controlled by OpenOCD (that gives me control over my target via a gdb server).
So I would like to automate this with some scripting of gdb.
I would like to write some kind of script for gdb that more or less does this:
Add a couple of breakpoints
Start the program
When we stop, where did it stop (get the frame info)
Quit.
Any ideas?
A example on how to do this in python gdb scripting would be nice.
Thanks
Johan
Note:
Let's say that we have this basic structure,
that more or less goes into test_failed() or test_success()
depending on what the function start_test() returns.
void test_failed() {
while(1);
}
void test_success() {
while(1);
}
int main(void) {
int status = start_test();
if( status > 0 ) {
test_failed();
}
test_success();
while(1);
}
To do this manually in gdb is very strait forward,
(gdb) break test_success
Breakpoint 1 at 0x20: file src/main.c, line 9.
(gdb) break test_failed
Breakpoint 2 at 0x18: file src/main.c, line 5.
(gdb) cont
Continuing.
Breakpoint 1, test_success () at src/main.c:9
9 while(1);
(gdb) frame
#0 test_success () at src/main.c:9
9 while(1);
(gdb)
So the next step I tried was to add those gdb commands into a gdb startup script that more or less just looked like this.
break test_success
break test_failed
target remote localhost:3333
cont
frame
and start it with
arm-none-eabi-gdb --batch --command=commands.gdb main.elf
And this kind of works, but it is not very nice.
How do I do this with the "new and cool" python scripts,
that gdb seem to support.
FYI recent gdb versions are scriptable in Python. You can call python code from the gdb command line. This opens a whole new world, check the relevant documentation. From the command line run:
dnf/yum/apt-get install gdb-doc
info gdb extending python
If you do not like the text-based info browser, here is one (among many?) alternative, graphical browser:
yelp 'info:gdb' # , go to "Extending"
Here is a sample gdb-python script. It attaches gdb to the first "your_program" found running.
#!/usr/bin/python
import subprocess
import string
def backquotes(cmdwords):
output = subprocess.Popen(cmdwords, stdout=subprocess.PIPE).communicate()[0]
return output.strip()
pid = backquotes(['pgrep', 'your_program'])
gdb.execute("attach " + str(pid))
A reduced example that I'm currently using:
class DebugPrintingBreakpoint(gdb.Breakpoint):
debugging_IDs = frozenset({37, 153, 420})
def stop(self):
top = gdb.newest_frame()
someVector = top.read_var('aVectorVar')
# Access the begin() & end() pointer of std::vector in GNU Standard C++ lib
first = someVector['_M_impl']['_M_start']
last = someVector['_M_impl']['_M_finish']
values = []
while first != last:
values.append(int(first.dereference()['intID']))
first = first + 1
if not set(values) & debugging_IDs:
return False # skip: none of the items we're looking for can be found by ID in the vector on the stack
print("Found other accompanying IDs: {}".format(values))
return True # drop to gdb's prompt
# Ensure shared libraries are loaded already
gdb.execute("start")
# Set our breakpoint, which happens to reside in some shared lib, hence the "start" previously
DebugPrintingBreakpoint("source.cpp:42")
gdb.execute("continue")
You can execute this script from gdb's prompt like this:
(gdb) source script.py
Or from the command-line:
$ gdb --command script.py ./executable.elf
See the complete GDB Python API docs for further info.
OK, I found the answer while asking the question... and it and it was a really simple thing.
You should not use both the "--command" and the "--eval" at the same time if you expect them to be executed in a specific order!
A more predicable way is to put everything in the commands.gdb file and ignore --eval.
So it becomes something like this:
arm-none-eabi-gdb --batch --command=commands.gdb main.elf
Where commands.gdb looks like this:
break test_success
break test_failed
target remote localhost:3333
cont
frame
But it would probably be so much nicer to do this with something like python instead.
Just wanted to note something that I find confusing whenever I come back to this topic (Note, I'm currently on Ubuntu 14.04, GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1):
First, there are references about it being "possible to invoke gdb as an interpreter":
9. Scripting gdb — The Cliffs of Inanity (http://tromey.com/blog/?p=548)
http://blog.scottt.tw/2012/01/exploring-gdb-python-api-with-ipython_31.html
... meaning, one would write a script text file with the shebang line #!/usr/bin/gbd -P or #!/usr/bin/gbd --python, then write Python code in it, then make it executable chmod +x pygdbscript, then run ./pygdbscript; ... but as in this post:
GDB - Missing "--python" Parameter? / Newbie Corner / Arch Linux Forums
..., I get gdb: unrecognized option '--python' if I try anything like that. Apparently this option is/was a feature in some "archer" branch of gdb?!
So, in order to run a Python script in gdb, there are actually two ways:
Name your script file with extension .py; say test.py here:
def Something():
print("hello from python")
Something()
gdb.execute("quit");
Note, in this case, you just write plain Python code; and you do not need to import gdb in order to access the gdb object. This you can run with either of:
gdb -x test.py
gdb -x=test.py
gdb --command test.py
gdb --command=test.py
gdb -command test.py
gdb -command=test.py
... which seem to be equivalent, as the result for any of these is the same printout, before gdb is instructed to exit by the script:
$ 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
NOTE that for this case, also names like test.gdb.py will be interpreted as pure Python scripts, since then end in .py.
Name your script anything else - as long as it does not end with .py extension; say test.pygdb here:
python
def Something():
print("hello from python")
Something()
gdb.execute("quit");
end
In this case, gdb interprets the script as being a gdb script, i.e. with gdb commands - and that means, that whatever Python code you may want to write in here, must be wrapped in "python" as a starting line and "end" at end of the Python code. Again, it would be called with any of these equivalent calls:
gdb -x test.pygdb
gdb -x=test.pygdb
gdb --command test.pygdb
gdb --command=test.pygdb
gdb -command test.pygdb
gdb -command=test.pygdb
... and then the output is the same as in the previous case (since it is the same Python script running):
$ gdb -x test.pygdb
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1
...
hello from python
And in response to OP: if the C code in OP is in /tmp/myprog.c - with an added int start_test() { return rand() % 50; } on top, otherwise it won't compile - , and is compiled with with gcc -g myprog.c -o myprog.exe into /tmp/myprog.exe; then you can use a myprog.gdb.py script like this:
# 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)
... then run this script with:
$ 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)
Note that at the end of this script, the (gdb) interactive prompt remains, and you can use it normally here; if you don't need the interactive prompt, you can do gdb.execute("quit"); as in the above scripts to force gdb to exit instead at end of script execution.
Also, for an example of subclassing breakpoint class in gdb Python, see How to print the current line of source at breakpoint in GDB and nothing else?