What is the equivalent of GDB's “define” in LLDB? - c++

I would like to define a LLDB function that runs 2 commands at the same time (for instance, print variable value and go to next line). Debugging C code using GDB I would do this:
(gdb) def f
Type commands for definition of "f".
End with a line saying just "end".
>p i
>n
>end
(gdb) f
But trying the same with LLDB doesn't work:
(lldb) def f
error: 'def' is not a valid command.
error: Unrecognized command 'def'.
Is there a way to do it?

From http://lldb.llvm.org/tutorial.html:
lldb also has a built-in Python interpreter, which is accessible by the "script" command. All the functionality of the debugger is available as classes in the Python interpreter, so the more complex commands that in gdb you would introduce with the "define" command can be done by writing Python functions using the lldb-Python library, then loading the scripts into your running session and accessing them with the "script" command.

Related

How to run gdb on an executable with arguments?

How can I run something like gdb -e path/to/exe -ex 'run --argnamae argvalue'?
Let's assume a recent version of gfb, within the past year or two.
Gdb runs and prints responses but not interactively.
I think you want gdb --args path/to/exe command line arguments
which will start gdb debugging path/to/exe pass three command line arguments to your exe command, line, and arguments, you can then interact with gdb before issuing the run command.
As for the ImportError: No module named 'libstdcxx' I believe this is already answered here which points to a bug report here.
It appears some versions of GCC have a broken pretty printers python script, you might need to adjust the python sys.path with (gdb) python sys.path.append("/usr/share/gcc-4.8/python"), adjust the path to match whatever GCC version is actually present on your system. You could probably add a command like this to your .gdbinit file to save typing it every time.
How can I run something like ...
You can do this:
gdb path/to/exe -ex 'set args arg1 arg2 arg3'
Or use a shorthand notation for the above:
gdb --args path/to/exe arg1 arg2 arg3
If you want to pass arguments from file,
try this
(gdb) run < the_file_contains_data

How to debug a C++ program that takes input from a script in gdb

Background info: The C++ program(LAMMPS - an open source) takes in a input script that has all the commands to be executed. The executable is named "lmp_fedora", input script named "in.hit". The program's run command "./lmp_fedora < in.hit"
My Problem: I am trying to debug one of the .cpp files in LAMMPS.
My Attempts: 1. I tried "gdb lmp_fedora < in.hit", but it failed. 2. Also tried to find the pid of the running program using ps aux, but wasn't sure which id it was.
My Question: How do you debug a input script(that has commands linked to c++ project) using gdb?
You use the gdb run command:
$ gdb lmp_fedora
(gdb) run <in.hit
From the help:
(gdb) help run
Start debugged program. You may specify arguments to give it.
Args may include "*", or "[...]"; they are expanded using "sh".
Input and output redirection with ">", "<", or ">>" are also allowed.
With no arguments, uses arguments last specified (with "run" or "set args").
To cancel previous arguments and run with no arguments,
use "set args" without arguments.
When you say gdb foo < bar that means bar is input to gdb, not to foo.
I think what you want to use is the gdb command set args.

How can I suppress error messages and silently continue a GDB script?

I have a GDB script that is deadreckon'ing up the callstack and blindly calling list and up using gdb 7.2:
gdb -q -batch -x gdb.cmd
gdb.cmd has:
list
up-silently
list
up-silently
[...]
Unfortunately, this will fail if gdb can't find the source file or it is inside a library that wasn't compiled with -g:
gdb.cmd:30: Error in sourced command file:
Line number 63 out of range; /home/ross/tmp.cc has 62 lines.
How can I suppress all errors and continue executing the script even if list or any other command fails?
There isn't a good way from the gdb CLI. The gdb CLI is rather limited.
If your gdb is built against Python, you can do it reasonably easily. Search for the "ignore-errors" script.

How to use gdb to reverse engineer an ELF which runs another program?

I am a beginner and got some trouble in RE.
I have an ELF 'bomb' and an unknown file 'model.abc'.
The correct way to run bomb is:
bomb model.abc
Now I want to use gdb to see the value of some addresses when running it. Can any one help me?
First start gdb from a shell prompt:
$ gdb bomb
Then run your program from the (gdb) prompt with the command line you want:
(gdb) run model.abc
You need to launch your program this way because gdb doesn't allow you to specify command line arguments for your program on the gdb command line.
Another, more convenient way of debugging a program with arguments:
gdb --args program <arguments>
If you don't have symbols, you'll have to start from the entry point. To figure our where it is, use:
(gdb) info file
Symbols from "/.../tesprog".
Local exec file:
`/.../tesprog', file type elf32-i386.
Entry point: 0x804abc0
Then you can set breakpoint on it before running:
break *0x804abc0
Note that the entry will be most often the library startup code (ctr0.s), it might take a while to get to the actual code written by the programmer.

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?