Let's say i have this file:
xb@dnxb:/tmp/c$ cat helloworld.h
void hello();
xb@dnxb:/tmp/c$ cat helloworld.c
#include <stdio.h>
void hello() {
printf("Hello world!\n");
printf("Next line\n");
}
xb@dnxb:/tmp/c$ cat main.c
#include <stdio.h>
#include "helloworld.h"
int
main(void) {
hello();
return 0;
}
And compiled with:
xb@dnxb:/tmp/c$ gcc -g3 -shared -o libhello.so -fPIC helloworld.c -std=c11
xb@dnxb:/tmp/c$ gcc -g3 main.c -o main -Wl,-rpath,"$PWD" -L. -lhello
Then debug with gdb:
xb@dnxb:/tmp/c$ gdb -q -n ./main
Reading symbols from ./main...done.
(gdb) b main
Breakpoint 1 at 0x40062a: file main.c, line 5.
(gdb) r
Starting program: /tmp/c/main
Breakpoint 1, main () at main.c:5
5 hello();
(gdb) s
hello () at helloworld.c:3
3 printf("Hello world!\n");
At this point, repeatedly pressing Enter (equivalent to type s and press Enter repeatedly):
(gdb)
_IO_puts (str=0x7ffff7bd9689 "Hello world!") at ioputs.c:33
33 ioputs.c: No such file or directory.
(gdb)
35 in ioputs.c
(gdb)
strlen () at ../sysdeps/x86_64/strlen.S:66
66 ../sysdeps/x86_64/strlen.S: No such file or directory.
(gdb)
What if i only care about helloworld.c without further step into printf()'s ioputs.c above ?
xb@dnxb:/tmp/c$ gdb -q -n ./main
Reading symbols from ./main...done.
(gdb) b main
Breakpoint 1 at 0x40062a: file main.c, line 5.
(gdb) r
Starting program: /tmp/c/main
Breakpoint 1, main () at main.c:5
5 hello();
(gdb) s
hello () at helloworld.c:3
3 printf("Hello world!\n");
(gdb) n
Hello world!
4 printf("Next line\n");
(gdb)
This is what i want, but it requires me to manually spot I'm in helloworld.c and it's the time to type n accordingly. My desired is:
(gdb) s
hello () at helloworld.c:3
3 printf("Hello world!\n");
Press Enter will skip step-in of custom filename, e.g. helloworld.c in this case, and direct skip to printf("Next line\n");:
(gdb)
Hello world!
4 printf("Next line\n");
(gdb)
The benefit is I don't have to spot where should i stop s and change to n, especially if the code hierarchy is big and i might step into helloworld.c for many time. I just have to repeatedly pressing Enter and skip unwanted depth/level.
How should i do that ?
[Code]
I wrote this code in my gdb startup file
~/.gdbinit(The first 6 lines is my existing lines before i wrote this code):[Explanation]
[1]
The basic idea is do
ninstead ofswhen encounter file(s) fullpath which i wanted to skip stepping.[2]
The "AAAAA..."(4096 chars) string is the only way i can found which can reserved the memory
$fpathfor full file path which require dynamically update afterward before the program is running. It might have better way to handle it, kindly comment if you know the better way.[3]
My 1st problem is parse the full filepath which was mixed inside
info source. I modified the gdb source code (gdb/source.c'ssource_info'ss->filenameis the full filepath) and compile it. But failed, it showsputsinstead of_IO_putsin the first stepping fromprintf, and i can't recall what i did, now it change tolibc.so.6only:But after that i realized i can simply saved output of
info sourceinto/tmp/gdbFilefirst(useset logginghack). Now use gdb commandshellto parse the file with regular Unix tool(grep/sed) and reformat it into/tmp/gdbFile.sources, then use gdb commandsourceto set the variable:[4]
/home/xiaobai/note/src/gdb-7.11.1/glibc-2.24/sysdeps/x86_64/strchr.Sis the example to shows it can disabled multiple+any filename. This file will called if i enabled step intoprintf. (simply change the filenamehelloworld.ctohelloworld2.cin my question to test)[5]
This code tested with empty space in filepath, e.g.
/tmp/c\ c/main[6]
Quite hard to extend if i want to exclude a lot of file path because i have to manually insert the
if-else-end. Kindly comment if you know the better way. I also a bit worry about the recursion ofif-esle-enddepth might cause problem (I'm not sure how gdb handle it internally), so i ensurenorsis the last instruction within condition.[7]
Luckily the Enter doesn't change to
s/n(last instruction ofsn) after i runsn, i.e. repeatedly press Enter will keep acts assn), otherwise i have no idea how to assign it.[Result]
Press Enter from
printfintohelloworld.cwill changestonautomatically, then change back tosafter return from this file. Note that my custom function is calledmystartup(simplymyshould work if no other command name starts with "my") andsn(not replacings, so you can invokedsin the middle ofhelloworld.cto stepping :):