gdb - print macros names instead of a values - c

Is it possible to UNexpand macros in gdb ?
I've compiled binary with -g3 , and I can see macro definitions:
(gdb) info macro NGX_CORE_MODULE
Defined at /path/src/core/ngx_conf_file.h:70
included at /path/src/core/ngx_core.h:86
included at /path/src/core/ngx_cycle.c:9
#define NGX_CORE_MODULE 0x45524F43
(gdb)
but when i see at the variable, i see numeric value instead of the macro name
(gdb) p/x cycle->modules[0]->type
$17 = 0x45524f43
(gdb)
is it possible to get something like this:
(gdb) p cycle->modules[0]->type
$17 = NGX_CORE_MODULE
(gdb)
I'v tried user-defined function like this:
define expand_module_type_macro
if $arg0 == 0x45524F43
print "NGX_CORE_MODULE"
else
if $arg0 == 0x464E4F43
print "NGX_CONF_MODULE"
else
print $arg0
end
end
end
and it works
(gdb) expand_module_type_macro cycle->modules[0]->type
$18 = "NGX_CORE_MODULE"
(gdb)
but it has no practical use, because i can't use it with complex output:
(gdb) printf "module type=%s\n", expand_module_type_macro cycle->modules[0]->type
No symbol "expand_module_type_macro" in current context.
(gdb) set $m = expand_module_type_macro cycle->modules[0]->type
No symbol "expand_module_type_macro" in current context.
(gdb)

You might get something useful by creating a convenience function in python. I tested using this C program:
int var1 = 1234;
int var2 = 4567;
int
main ()
{
return 0;
}
And using this python script:
class ExpandMacro (gdb.Function):
"""Expand a value to a string, replacing with
macro name where possible."""
def __init__ (self):
super (ExpandMacro, self).__init__ ("expand")
def invoke (self, value):
if (value == 1234):
return "MY_MACRO"
else:
return str (value)
ExpandMacro ()
Then my GDB session:
(gdb) start
# .... snip ....
7 return 0;
(gdb) source lookup.py
(gdb) p $expand (var1)
$1 = "MY_MACRO"
(gdb) p $expand (var2)
$2 = "4567"
(gdb) printf "var1=%s\n", $expand (var1)
var1=MY_MACRO
(gdb) printf "var2=%s\n", $expand (var2)
var2=4567
In order to use the returned value with a %s format inside printf, I always return a string.

Related

How to break if a function is called from a certain file in gdb

I have let's say 10 files file1,file2 ... file10 and each file has a function named fnCaller() which calls to a function say rmCaller(). I want to break only when this rmCaller() is called from fnCaller() in file4.Is it possible?
You can use conditional breakpoints convenience functions:
(gdb) break myAddress
Breakpoint 1 at <myAddress>
(gdb) cond 1 $_caller_is("myfunction1") && $_caller_is("myfunction2") ...

Why is execve ignoring environment arguments?

Say we have program1:
int main(void) {
char *env[2];
env[0] = "PATH=/";
env[1] = NULL;
execve("/program2", NULL, env);
exit(0);
}
We also have program2:
int main(void) {
exit(0);
}
Debugging this, PATH isn't actually modified in the new process (program2) that is executed.
Debugging this, PATH isn't actually modified in the new process
(program2) that is executed.
This is not true. Note that p environ doesn't work, while x 0x8049650 (address environ##GLIBC_2.0, obtained from info var environ) does:
(gdb) p environ
$1 = (char **) 0x0
(gdb) p/x &environ
$2 = 0xf7fbfd44
(gdb) x 0x8049650
0x8049650 : 0xffffdf18
(gdb) x/s **0x8049650
0xffffdfe8: "PATH=/"

store gdb call expr return value

how to store return value of call expr in gdb? For example:
(gdb) call rbt_next(&some_global,0x0)
$2 = (rbt_node *) 0x7169ee00
rbt_next returns the pointer next node. However, when I try to do:
(gdb) set $w_sess = call rbt_next(&some_global,0x0)
Error: No symbol "call" in current context
I get the above error.
The reason why I want this is because I need to traverse a global rb tree to find a match. What I want to accomplish is this:-
while $w_sess = call rbt_next($some_global, $c_sess) != 0x0
if $c_sess == $w_sess
printf "Sess found in tree\n"
else
printf "Sess not found\n"
end
end
Leave out the word call. The part after set $foo = is just an ordinary expression like you'd use with print.

Debugging json_t object with GDB

I have a application in C programming which uses jansson library(json library written in C). I'm trying to view value of json_t object in gdb but it just prints
(gdb) p jmsg
$20 = (json_t *) 0x69c350
(gdb) p *jmsg
$21 = {type = JSON_OBJECT, refcount = 1}
How is it possible to view the value of json_t in gdb.?
When in GDB, you can make function calls directly. Jansson library has a json_dumps(json_t *, int flags) API that returns a char* string of the json_t object.
So while in GDB, just simply do:
(gdb) call json_dumps(obj, 0)
GDB will then print the string output of your json object.

How to view content of variable of type LPVOID

I have a C function that takes a parameter of type LPVOID. The values that gets passed in is \0 seperated array of characters. How can I cast the parameter to see the incoming value in visual studio / windbg?
You can do this in a script. Something like the following would work, which assumes char * strings and that the list ends in double NULLs (like a MULTI_SZ):
$$ Print a MULTI_SZ value in the debugger. Note that
$$ this script assume a char* string
$$ Grab the argument to the script
r #$t0 = ${$arg1}
$$ while *str != NULL
.while (by(#$t0) != 0)
{
$$ Print the string
da #$t0
$$ There's no strlen in this language, so find the NULL
.while (by(#$t0) != 0)
{
r #$t0 = #$t0 + 1
}
$$ String points to the NULL. Add one.
r #$t0 = #$t0 + 1
}
Save to a text file and then run the following in WinDBG:
0:000> $$>a<c:\dumps\multisz.txt 0x012210ec
012210ec "Foo"
012210f0 "Bar"
012210f4 "FooBar"
There is no cast that would allow you to observe that in watch windows. For VS you will have to open up a memory window on the address at the beginning of the null separated block.
In WinDbg command db <my_address> dumps raw memory along with ASCII conversion. If block is larger than 128 bytes, then add option l to the command. E.g this will print out first 0x200 bytes for local variable pVoid:
db poi pVoid l200
Simply casting to char* should work.
void f(LPVOID s)
{
char* ss = (char*) s; // put breakpoint here or watch the variable
for(char* r = ss; *r != '\0'; r += (strlen(r)+1)) { // iterate the string
printf("%s \n", r);
}
}
again a very late a answer but dpa in windbg can be leveraged to print the list
lpvoid:\>dir /b
lpvoid.cpp
lpvoid:\>type lpvoid.cpp
#include <stdio.h>
#include <windows.h>
int somefunc(LPVOID blah)
{
printf("%s\n",*(PCHAR *)blah);
return 0;
}
int main (void)
{
PCHAR foo[] = { "yay" , "boy" , "dog" , "cat" , "monkey" , "weedinducedweird
o" };
somefunc( foo);
return 0;
}
lpvoid:\>cl /Zi /nologo lpvoid.cpp
lpvoid.cpp
lpvoid:\>dir /b *.exe
lpvoid.exe
lpvoid:\>lpvoid.exe
yay
set a bp on somefunc or if you do not have symbols on address lik bp 401020
use dpa on the argument (blah here) or use dpa #esp+8
lpvoid:\>cdb -c "bp somefunc \"dpa poi(blah) l?6;q\";g;q" lpvoid.exe | grep -A 6
yay
0013ff60 00417c60 "yay"
0013ff64 00417c64 "boy"
0013ff68 00417c68 "dog"
0013ff6c 00417c6c "cat"
0013ff70 00417c70 "monkey"
0013ff74 00417c78 "weedinducedweirdo"
quit:
assuming no symbols here
lpvoid:\>cdb -c "bp 401020 \"dpa (#esp+8) l?6;q\";g;q" lpvoid.exe | grep -A 6 ya
y
0013ff60 00417c60 "yay"
0013ff64 00417c64 "boy"
0013ff68 00417c68 "dog"
0013ff6c 00417c6c "cat"
0013ff70 00417c70 "monkey"
0013ff74 00417c78 "weedinducedweirdo"
quit:

Resources