How to 'catch syscall' in LLDB? - lldb

As known,we can use command 'catch syscall' in GDB to break on every system function.
Is there a similar command in LLDB?
(gdb) catch syscall
Catchpoint 1 (syscall)
(gdb) r
Starting program: /tmp/catch-syscall
Catchpoint 1 (call to syscall 'close'), \
0xffffe424 in __kernel_vsyscall ()
(gdb) c
Continuing.
Catchpoint 1 (returned from syscall 'close'), \
0xffffe424 in __kernel_vsyscall ()
(gdb)

Not yet, feel free to file an enhancement request using the http://lldb.llvm.org Bug Report link.
If you're on Mac OS X and are just interested in recording syscalls you can use dtrace, you can get it to dump stack traces and the like. That doesn't help if you need to be stopped in the debugger at the syscall, but might work for some purposes.

Related

Linux Kernel function memblock_alloc_range_nid is not presented in the address space

I'm trying to debug physical memory allocation to understand what part of the Linux Kernel use memblock_alloc_range_nid on x86-64 and how.
I'm running the latest Linux Kernel 5.19-rc2 built from upstream with Ubuntu 20.04 inside QEMU. The problem is it's not possible to access memory address the function memblock_alloc_range_nid is located at. While other Kernel functions can be easily disassembled.
Here is what I have in my gdb connected to the QEMU VM:
(gdb) disas memblock_alloc_range_nid
Cannot access memory at address 0xffffffff831a05d1
(gdb) disas native_safe_halt
Dump of assembler code for function native_safe_halt:
#...
End of assembler dump.
What's wrong with the function memblock_alloc_range_nid? Why is it not possible to access its address? It seems all the function from memblock.c cannot be accessed.
As Margaret and Roi have noted in the above comments, memblock_alloc_range_nid() is annotated with __init. Functions annotated with __init, __head and similar macros are only needed during kernel initialization right after boot. After the kernel has finished initializing things, the special memory section containing all those functions is unmapped from memory since they are not needed anymore.
If you want to debug any such function, you will have to break very early, for example at start_kernel(), then you can inspect the function or set a breakpoint and continue execution to hit it.
Important: add -S (uppercase) to your QEMU command line options to make it stop and wait for the debugger before starting the kernel, and start the kernel with KASLR disabled using -append "nokaslr" (or adding nokaslr if you are already specifying -append).
The following GDB script should be what you need:
$ cat script.gdb
directory /path/to/kernel-source-dir
file /path/to/kernel-source-dir/vmlinux
target remote localhost:1234
break start_kernel
continue
Launch gdb -x script.gdb (after starting QEMU), and when you hit the start_kernel breakpoint, you can add another one for memblock_alloc_range_nid, then continue:
0x000000000000fff0 in exception_stacks ()
Breakpoint 1 at 0xffffffff82fbab4c
Breakpoint 1, 0xffffffff82fbab4c in start_kernel ()
(gdb) b memblock_alloc_range_nid
Breakpoint 2 at 0xffffffff82fe2879
(gdb) c
Continuing.
Breakpoint 2, 0xffffffff82fe2879 in memblock_alloc_range_nid ()
(gdb) disassemble
Dump of assembler code for function memblock_alloc_range_nid:
=> 0xffffffff82fe2879 <+0>: push r15
0xffffffff82fe287b <+2>: mov r15,rcx
0xffffffff82fe287e <+5>: push r14
0xffffffff82fe2880 <+7>: mov r14,rdx
0xffffffff82fe2883 <+10>: push r13
0xffffffff82fe2885 <+12>: mov r13d,r9
...

How to use GDB to debug QEMU with SMP (symmetric multiple processors)?

I am in a graduate operating systems class, and we are emulating our kernel using QEMU, and debugging it using gdb. Debugging has been straight-forward enough.. up until now. How can I connect gdb to the other CPUs I have running in QEMU?
Our makefile allows us to start qemu with either "make qemu-nox" or "make qemu-nox-gdb" in one terminal, and if we used the latter, then to connect to it with gdb using just "gdb" in another terminal (in the same directory). Thus, I'm not quite sure how to connect to the same QEMU, again, but to a different processor (I'm running with a total of 4 right now).
Each qemu CPU is visible as a separate thread within gdb. To inspect the state of another CPU, use the thread command to switch CPUs.
(gdb) info thread
Id Target Id Frame
* 1 Thread 1 (CPU#0 [running]) 0x80105163 in stosl (addr=0x89c3e000, data=16843009, cnt=1024) at x86.h:44
2 Thread 2 (CPU#1 [halted ]) halt () at x86.h:127
3 Thread 3 (CPU#2 [halted ]) halt () at x86.h:127
4 Thread 4 (CPU#3 [halted ]) halt () at x86.h:127
(gdb) where
#0 0x80105163 in stosl (addr=0x89c3e000, data=16843009, cnt=1024) at x86.h:44
#1 0x801051bf in memset (dst=0x89c3e000, c=1, n=4096) at string.c:8
#2 0x80102b5a in kfree (v=0x89c3e000 "\001\001\001\001") at kalloc.c:63
#3 0x80102af4 in freerange (vstart=0x80400000, vend=0x8e000000) at kalloc.c:47
#4 0x80102ac1 in kinit2 (vstart=0x80400000, vend=0x8e000000) at kalloc.c:38
#5 0x8010386a in main () at main.c:37
(gdb) thread 3
[Switching to thread 3 (Thread 3)]
#0 halt () at x86.h:127
127 }
(gdb) where
#0 halt () at x86.h:127
#1 0x80104aeb in scheduler () at proc.c:288
#2 0x801038f6 in mpmain () at main.c:59
#3 0x801038b0 in mpenter () at main.c:50
#4 0x0000705a in ?? ()

No Debug Symbols cross compile ARM on BusyBox

i'm trying to debug a C program, which runs on an ARM926EJ-S rev 5 (v5l). The software was cross-compiled (and is statically linked) with the std. arm-linux-gnueabi compiler (intalled via synaptic). I run Ubuntu 13.04 64bit. On the device is a Busybox v1.18.2. I successfully compiled gdbserver (with host=arm-linux-gnueabi) and gdb (with target=arm-linux-gnueabi) and can start my program on the embedded device via the locally running gdb...
My problem now is, that i don't have a proper backtrace output.
Message of gdb:
Remote debugging using 192.168.21.127:2345
0x0000a79c in ?? ()
(gdb) run
The "remote" target does not support "run". Try "help target" or "continue".
(gdb) continue
Continuing.
Cannot access memory at address 0x0
Program received signal SIGINT, Interrupt.
0x00026628 in ?? ()
(gdb) backtrace
#0 0x00026628 in ?? ()
#1 0x00036204 in ?? ()
#2 0x00036204 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb)
I try to compile the software with -g, -g3 -gdwarf-2, -ggdb, -ggdb3 without any difference.
Has anybody an idea what i am missing here?
Is this a problem maybe with the BusyBox or do i need additional libs on my host system?
I also tried the function backtrace_symbols from execinfo.h with nearly the same output...
Thanks in advance for any reply.
Another way for debugging is use gdb inside board follow below steps.
1)Run gdb process and attach your process to gdb using attach <pid> command
2)Continue your process using c command in gdb
Whenever you find any SIGINT or SIGSEGV then refer stack of your process using bt command in gdb.

GDB blows up when debugging multithreaded program that fast-forks and executes another program

I'm debugging my C program(s) with GDB and it's kinda wonky, probably because I'm not using glibc so it doesn't detect new threads until it breaks in them. I fixed this by adding a breakpoint which immediately resumes (break if 0).
Today however I ran into a wall.
I need to execve() really fast so normal fork() is out of the question (will use a ton of memory) and I can't vfork() (I need a stack to set up pipes etc) so I used the same method as in this library (https://code.google.com/p/popen-noshell/) which is basically only cloning with CLONE_VM. This (or calling execve() in general - I don't really know) makes GDB really confused for some reason - basically it's outputting something like this:
[New LWP 516]
[New LWP 520]
[New LWP 519]
[New LWP 521]
LWP 521 is executing new program: /bin/bash
Error in re-setting breakpoint 1: No source file named xxx.c.
Error in re-setting breakpoint 2: No source file named yyy.c.
Error in re-setting breakpoint 4: Function "zzz_main" not defined.
[LWP 521 exited]
Program received signal SIGTRAP, Trace/breakpoint trap.
[Switching to LWP 519]
0x00000000004307f8 in shell_execve ()
(gdb) info threads
Id Target Id Frame
* 5 LWP 519 "self-tes" 0x00000000004307f8 in shell_execve ()
4 LWP 520 "self-tes" 0x000000000040825f in ?? ()
3 LWP 516 "self-tes" 0x000000000040825f in ?? ()
2 LWP 515 "self-tes" 0x000000000040825f in ?? ()
1 LWP 512 "self-tes" 0x000000000040848a in ?? ()
GDB basically get's confused about everything and think it's currently executing /bin/bash - it's not - running without GDB works fine however I need it to debug my program. I've tried to disable every fork and exec setting I could find but nothing like "follow exec" is enabled. As you can see it tries to re-set breakpoints after the execve()... why?? It no longer recognizes any frames or symbols as it completely wiped the previous space and loaded /bin/bash instead.
How can I make GDB ignore the thread that calls the execve() and NOT try to load symbols for the subprocess?
EDIT: Oh and I'm currently using x86_64 Linux 3.2.0-27 (Ubuntu).
EDIT2: Also GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2) 7.4-2012.04
EDIT3: Also just checked with gdb 7.5. Same problem.
Found the problem! Apparently I forgot to mask flags with SIGCHLD when cloning which apparently gdb (or libthread) uses as a hint of spawning a subprocess (fork style) and not just another thread. Thanks #R.. for the hint which lead me in the right direction.

gdb: always stop at 0xffffe410 in __kernel_vsyscall ()

I'm using gdb to attach a running process, however, it always stops at __kernel_vsyscall. It looks like it stopped at my system call msgrcv(). I have to constantly "cont" it and don't know when it could jump out of kernel and go back to application. How can I make it continue? The following is my procedure.
How did I get this situation?
How to make it continue?
Thanks!
gdb
(gdb) attach PID
...
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
0xffffe410 in __kernel_vsyscall ()
(gdb)bt
#0 0xffffe410 in __kernel_vsyscall ()
#1 0x009ed573 in msgrcv () from /lib/libc.so.6
#2 0xf7f3a487 in _UX_wgetmsg (mode=0, msgp=0xffbb4178, pmaxtime=0xffbb4164,
pdata=0xf7f7a860, ux_type=0) at ../../../ux/com_ux/libux/com/UXipc.c:2550
#3 0xf7f3ad05 in UX_wgetmsg_v2 (mode=0, msgp=0xffbb4178, maxtime=10000,
ux_type=0) at ../../../ux/com_ux/libux/com/UXipc.c:2237
#4 0x0804bb9b in main (argc=1, argv=0xffbb5394)
at /path/to/my_application:243
How did I get this situation?
That situation is completely normal for when you attach to a process which is blocked in a system call (waiting for message, or for read to complete).
How to make it continue?
You type continue (at which point the application would again block, waiting for a message). If you want to debug some part of the application, set breakpoints before continuing.

Resources