in gdb, can we set a variable as an expression? - c

In the u-boot C code, the value "gd" is declared like this. (arm)
register volatile gd_t *gd asm ("r9")
and register r9 contains the pointer to the struct global_data. (typedef'd to gd_t)
While debugging/analying, to see gd->malloc_base in the C code, typing "p gd->malloc_base" doesn't work. it says Missing ELF symbol "gd".
I later learned that I should do "p ((gd_t *)$r9)->malloc_base" to see the value.
I'm typing this kind of command many times a day. Isn't there a way that I can assign a variable in gdb that represents ((gd_t *)$r9)? and why doesn't gdb recognize the value gd in the code?
What I want to do is make a variable representing ((gd_t *)$r9) so that I can use it like gd->ram_top or gd->env_has_init, etc. according to the value I'm curious about.

This is the comment of #ssbssa to my quetion (thanks #ssbssa). I asked him to put his answer but he doesn't. so I add the answer myself.
You can define macro like macro define gd ((gd_t *)$r0) and then you can later use p /x gd->reloc_off or p /x gd->flags. Of course you can put this macro define command in the command file and start gdb like this arm-none-eabi-gdb u-boot -x gdb_command.

Related

gdb alias for quick saving/loading of breakpoints

So I'm pretty new to gdb, and have just learned that you can save breakpoints with:
save breakpoints filename
and load them with
source filename
which is great, but because it's something I more or less plan on doing every time I enter/exit gdb, I'd like to get it down to a quick alias.
So, in my ~/.gdbinit I have the lines
alias savebps = save breakpoints .gdb_bps
alias loadbps = source .gdb_bps
loadbps
Unfortunately, every time I open gdb I get the error:
Invalid command to alias to: save breakpoints .gdb_bps
I know(/ strongly think) I have the syntax correct, as I've tested
alias savebps = help
and that alias works. So I think it's an issue with having a non-gdb command word (the filename) as part of an alias.
So, my questions are this:
Am I being totally stupid and there's already a great way to auto-save and maintain my list of breakpoints?
Can GDB have filenames in aliases? Or am I looking for something other than an 'alias'?
If they CAN have filenames in them, what am I doing wrong?
Oh and as a note the '.gdb_bps' is an arbitrary file name I just kinda came up with as it'd be a nice unobtrusive thing to easily .gitignore and stuff.
Thanks!
Can GDB have filenames in aliases?
Looks like no. It looks like aliases can't have any arguments to commands, not only filenames. This alias fails also:
(gdb) alias spe = set print elements 0
Invalid command to alias to: set print elements 0
Or am I looking for something other than an 'alias'?
Yes, you can use user-defined command instead:
(gdb) define savebps
Type commands for definition of "savebps".
End with a line saying just "end".
>save breakpoints .gdb_bps
>end
(gdb)
(gdb) define loadbps
Type commands for definition of "loadbps".
End with a line saying just "end".
>source .gdb_bps
>end
(gdb)

Show macros in debug symbols (embedded)

I am working with embedded application, and during debugging, the debugger is not able to resolve macro symbols (my theory: because macros are lost in preprocessing). I end up having to find the macro in source code first and then use the definition to watch a variable.
My question is:
Is there a way to incorporate the macro definition inside by elf file?
If yes, what steps do I need (flag do i need to set during compile, for example)?
If no, why not?
Any info is appreciated.
My exact setup is WindRiver compiler and lauterbach debugger.
But if you have info about other environment, please share, perhaps I can find a counterpart for my environment.
Not sure how this translates to your compiler & debugger, but it's possible with GCC and GDB.
If you rebuild and tell GCC to generate debug symbols optimized for GDB, using -ggdb3, it can preserve macro information:
$ make KCFLAGS=-ggdb3
...
(gdb) info macro task_is_stopped_or_traced
Defined at include/linux/sched.h:218
included at include/linux/nmi.h:7
included at kernel/sched.c:31
#define task_is_stopped_or_traced(task) ((task->state & (__TASK_STOPPED | __TASK_TRACED)) != 0)
(gdb) macro expand task_is_stopped_or_traced(init_task)
expands to: ((init_task->state & (4 | 8)) != 0)
(gdb) p task_is_stopped_or_traced(init_task)
$2 = 0
Usually, macros do not appear in debugging symbols because of how C files are compiled.
First, the file is preprocessed, and macros are expanded. Then, all preprocessing directives are deleted, and macro definitions discarded. Next, the actual compiling to machine code takes place, and this is where the compiler builds debugging information.

How can I examine in gdb a variable that has the same name as its type

I'm debugging an existing C library with gdb 7.4
I'm trying to examine a variable which, unfortunately, was declared with the same name as its type:
extern const enum rtx_class rtx_class[NUM_RTX_CODE];
Now I just can't find a way to examine this variable. p rtx_class returns Attempt to use a type name as an expression, the same with p &rtx_class and p rtx_class[0].
However, info var rtx_class works and returns const rtx_class rtx_class[145] as expected.
Any idea?
Try this workaround. For your binary do something like:
nm your-executable |grep rtx_class
You should get address (let's say it's 0xabcdef, assuming this is global variable.
Then in gdb do something like:
print *(rtx_class*)(0xabcdef+sizeof(rtx_class)*n)
This should print rtx_class[n]. Or at least it does in my simple testcase.

Checking when a variable is modified

Using Valgrind or any other debugger in Linux, how can one see places where a variable is modified. I am using gcc. Note that I don't want to step into the code using gdb. I just want to run the program and have the debugger report me in the end, places where the variable is modified in the code.
Hm, thinking about it it's not exact duplicate of Can I set a breakpoint on 'memory access' in GDB?, because it asks a little bit more. So:
Use gdb
Find the address you want to watch (hardware watchpoints only work for watching address, so you have to run it to the point where the variable or object are instantiated, take their address and use the watch command on that address.
Attach command to the address to give you a backtrace (or any other info you need to collect) and continue.
So you'll have something like:
p &variable
watch *$$
cmd
bt
c
end
(I am not completely sure with the $$, I normally use the $n as printed by the p command).
Use Breakpoint Command Lists to do this in gdb. You will have to know the address of variable to watch. Set watchpoint with a series of commands like this:
watch *0xfeedface
commands
silent
bt
cont
end
You can also optionally save all this output to log file. Look gdb doc for more details.

Environment variabile in Macro path

I need to define some path to files with macros. How can I use the $HOME environment variable?
I can't find it on the GNU manual, and this doesn't work:
#define LOGMMBOXMAN "$HOME/mmbox/LOGmmboxman"
No it shouldn't and you probably don't want constant-defined settings like that in any case. If you did that and it worked as you're intending to use it, your home directory would be built in as whatever $HOME is for whoever's doing the building. The executable then depends on that specific home directory existing. If that's OK, just #define your own home. I suspect it isn't though, so you need to deduce it at runtime.
For run-time deduction what you want is this, such that:
const char* home_dir = getenv("HOME");
If there is no $HOME defined, you get NULL returned so be sure to test for this.
You can then build your string based on that. You'll need #include <stdlib.h>.
Sounds like you are really asking "how can I set some cpp macro from my environment?"
If sothen you should just be able to add it to CPPFLAGS.
export CPPFLAGS="$CPPFLAGS -D LOGMMBOXMAN=$HOME/mmbox/LOGmmboxman"
Then in your code
#ifndef LOGBOXMAN
#error LOGBOXMAN not defined
#endif
Then make sure your source is built using the CPPFLAGS in the command line to gcc:
$ gcc -c file.c $CPPFLAGS
You can't. You need to use your build system to define a macro with the $HOME value (or equivalent on a non-unix system), i.e. something like this:
gcc -DHOME="/home/username" file.c
Or "/Users/username" for Mac OS X, or "C:\Users\username" (or something) for Windows. Basically, GCC provides the -D flag to define a macro on the command line. You can set up a script (or your build system) to take care of this macro definition for you, or perhaps make a system-dependent include file to define the HOME macro properly.
Then, in your C header, you can do:
#define LOGMMBOXMAN HOME "/mmbox/LOGmmboxman"
Note that, in C, consecutive string literals are concatenated. So this macro expands to:
"/home/username" "/mmbox/LOGmmboxman"
Which C interprets as
"/home/username/mmbox/LOGmmboxman"
EDIT: All that thinking, and I didn't think! D'oh!
As others have pointed out, you probably don't want to do this. This will hard-code your program to work for one specific user's home directory. This will likely cause problems if you want each user to use your program, but for each to keep his (or her) own separate files.
Ninefingers' answer is what you're most likely looking for. In the event that you ever find yourself in need of the above technique (i.e. storing application files in a system-specific place) I will leave my answer unchanged, but I expect it won't help you here.

Resources