Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Evaluate an expression in gdb and lldb

Tags:

gcc

gdb

lldb

I'm trying to understand GDB and LLDB so that I can efficiently used it to debug my Programs at any point.

But it seem that I'm stuck I'm not sure how to print the output of C library function like pow, strnlen etc. If I ever want to explore there output.

Following are by LLDB and GDB output.

   3    int main(int argc,char *argv[]) {
   4       int a = pow(3,2);
-> 5       printf("the value of a is %d",a);
   6       return 0;
   7    }
(lldb) print pow(3,1)
warning: could not load any Objective-C class information. This will significantly reduce the quality of type information available.
error: 'pow' has unknown return type; cast the call to its declared return type
(lldb) print strlen("abc")
warning: could not load any Objective-C class information. This will significantly reduce the quality of type information available.
error: 'strlen' has unknown return type; cast the call to its declared return type
(lldb) expr int a = strlen("abc");
error: 'strlen' has unknown return type; cast the call to its declared return type
(lldb) expr int a = strlen("abc");

GDB output

Starting program: /Users/noobie/workspaces/myWork/pow 
[New Thread 0x1903 of process 35243]
warning: unhandled dyld version (15)

Thread 2 hit Breakpoint 1, main (argc=1, argv=0x7fff5fbffb10) at pow.c:5
5      int a = pow(3,2);
(gdb) print pow(3,2)
No symbol "pow" in current context.
(gdb) set pow(3,2)
No symbol "pow" in current context.
(gdb) set pow(3,2);
No symbol "pow" in current context.
(gdb) print pow(3,2);
No symbol "pow" in current context.
(gdb) call pow(3,2)
No symbol "pow" in current context.
(gdb) 

I have compiled the program using gcc with -g3 flag

i.e

gcc -g3 pow.c -o pow

like image 813
Noobie Avatar asked Feb 28 '17 03:02

Noobie


People also ask

How do I evaluate an expression in LLDB using backticks?

The LLDB command uses backticks to evaluate an expression and insert the scalar result. Show the general-purpose registers for the current thread formatted as signed decimal. — (lldb) register read --format i (lldb) re r -f i LLDB now supports the GDB shorthand format syntax, but no space is permitted after the command: (lldb) register read/d

How do I use the LLDB command?

The LLDB command uses backticks to evaluate an expression and insert the scalar result. Show the general-purpose registers for the current thread formatted as signed decimal. Note: LLDB tries to use the same format characters as printf (3) when possible. Type help format to see the full list of format specifiers.

How do I debug GDB in Visual Studio Code?

For the C++ (GDB/LLDB) debugging environment, you can execute GDB, LLDB and LLDB-MI commands directly through the debug console with the -exec command, but be careful, executing commands directly in the debug console is untested and might crash VS Code in some cases.

How do I write a new decimal value in LLDB?

Write a new decimal value 123 to the current thread register rax. Skip 8 bytes ahead of the current program counter (instruction pointer). The LLDB command uses backticks to evaluate an expression and insert the scalar result. Show the general-purpose registers for the current thread formatted as signed decimal.


1 Answers

The error you are getting from lldb, e.g.:

error: 'strlen' has unknown return type; cast the call to its declared return type

is just what it says. You need to cast the call to the proper return type:

(lldb) print (size_t) strlen("abc")
(size_t) $0 = 3

The reason the type information is missing from strlen and printf etc. is that to save space, the compiler only writes the signatures of functions into the debug information when it sees the definition of the function, not at every use site. Since you don't have the debug information for the standard C libraries, you don't have this information.

The reason the debugger requires this information before it will call the function is that if you call a function that returns a structure, but generate code as though the function returned a scalar value, calling the function will corrupt the stack of the thread on which the function was called, ruining your debug session. So lldb doesn't guess about this.

Note, on macOS, the system has "module maps" for most of the system libraries, which allow lldb to reconstruct types from the modules. To tell lldb to load a module when debugging a pure C program, run this command:

(lldb) expr -l objective-c -- @import Darwin

If you are debugging an ObjC program, you can leave off the language specification. After this expression runs, lldb will have loaded the module map and you can call most of the functions in the standard C libraries without casting.

like image 94
Jim Ingham Avatar answered Nov 16 '22 01:11

Jim Ingham