i am having a macro whose definition runs into around 50 lines and has lot of 'if else' statements. This macro def'n appears in a .h file. I am running 'gdb in TUI mode', but when the execution reaches that macro, the code window goes blank and returns back only after the macro code gets executed. I want to see line by line execution of the full macro code. Please let me know how can that be done (one way is to replace the macro with its definition in the code and then recompile it. i don't want to use this option as there are several such macros in my code).
Any help will be greatly appreciated. looking forward to get the solution for this problem. Please let me know if there is some other way for this issue rather than the usage of preprocessed file ? i am having a code which runs into several hundred .c & .h files.
To execute one line of code, type "step" or "s". If the line to be executed is a function call, gdb will step into that function and start executing its code one line at a time. If you want to execute the entire function with one keypress, type "next" or "n".
This is equivalent to the "step over" command of most debuggers. If you want gdb to resume normal execution, type "continue" or "c". gdb will run until your program ends, your program crashes, or gdb encounters a breakpoint.
Run gdb with the generated executable. Here are few useful commands to get started with gdb for the above example:- run or r –> executes the program from start to end. break or b –> sets breakpoint on a particular line.
On the Design tab, in the Tools group, click Single Step. Click Run. If the macro is a new or edited macro, you will be prompted to save the macro before you can run it.
One option is to fully preprocess your C file, expanding all macros in it, and then compile the resulting preprocessed file.
For example, consider this simple C program:
// file: prep.c
#include <stdio.h>
#define MY_BIG_MACRO \
int i; \
printf("integers from 0 to 9:\n"); \
for (i = 0; i < 10; i++) \
printf("%d ", i); \
printf("\n");
int main(void)
{
MY_BIG_MACRO
return 0;
}
Compile it, saving the temporary files (including the preprocessed source code):
gcc -Wall -O2 -g -std=c99 prep.c -o prep.exe -save-temps
This should give you a preprocessed version of prep.c
, prep.i
(shortened for brevity):
# 1 "prep.c"
# 1 "C:\\MinGW\\msys\\1.0\\home\\Alex//"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "prep.c"
# 1 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.6.2/../../../../include/stdio.h" 1 3
...
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vswscanf (const wchar_t * __restrict__,
const wchar_t * __restrict__, __gnuc_va_list);
# 3 "prep.c" 2
# 11 "prep.c"
int main(void)
{
int i; printf("integers from 0 to 9:\n"); for (i = 0; i < 10; i++) printf("%d ", i); printf("\n");
return 0;
}
Now you want to get rid of the #-lines. One way or another, if they are left in, they will affect the debug info. Surprisingly, that means that the macro won't appear expanded in gdb
.
Thankfully, grep
can help (I'm not a grep pro, so check whether the params are correct, but they seem to work for me on Windows with MinGW x86):
grep ^[^\#].*$ prep.i > prepi.c
This will give you a stripped version of prep.i
in prepi.c
:
typedef unsigned int size_t;
typedef short unsigned int wchar_t;
typedef short unsigned int wint_t;
...
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vswscanf (const wchar_t * __restrict__,
const wchar_t * __restrict__, __gnuc_va_list);
int main(void)
{
int i; printf("integers from 0 to 9:\n"); for (i = 0; i < 10; i++) printf("%d ", i); printf("\n");
return 0;
}
Now you can compile it:
gcc -Wall -O2 -g -std=c99 prepi.c -o prepi.exe
And run it in gdb
:
gdb prepi.exe
Issue the following commands:
b main
r
l
This will execute the app until main()
and list the source code related to the reached breakpoint:
(gdb) b main
Breakpoint 1 at 0x40643f: file prepi.c, line 184.
(gdb) r
Starting program: C:\MinGW\msys\1.0\home\Alex\prepi.exe
[New Thread 7340.0x20c4]
Breakpoint 1, main () at prepi.c:184
184 int i; printf("integers from 0 to 9:\n"); for (i = 0; i < 10; i++) pri
ntf("%d ", i); printf("\n");
(gdb) l
179 const wchar_t * __restrict__, __gnuc_va_list);
180 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vswscanf (c
onst wchar_t * __restrict__,
181 const wchar_t * __restrict__, __gnuc_va_list);
182 int main(void)
183 {
184 int i; printf("integers from 0 to 9:\n"); for (i = 0; i < 10; i++) pri
ntf("%d ", i); printf("\n");
185 return 0;
186 }
(gdb)
As you can see, the macro body is now in the plain view.
One small problem here is that multi-line macros (those continued with \
) are expanded into a single line. I haven't found an option to expand them into multiple lines, but you can do that manually.
"One does not simply step
into macros."
You still have a few options:
stepi
to execute your macro one machine instruction at a time.If all the above does not work, really you should go back to using printf/fprintf
within your large macro.
I had to deal with a 300 lines MACRO, burried deep into the library. This was easier than compiling by hand and dealing with post-processed files.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With