首页 > 解决方案 > “目标 sim”“sim 内存大小 4Mb”“加载”“运行”后 gdb 模拟器崩溃

问题描述

我计划使用最新的 gdb 支持来调试 eBPF 代码。但是我运行后模拟器崩溃了。所以我尝试使用 -g 选项(gcc -g hello_wold.c)编译的常规“hello world”c 代码遇到了同样的问题。

gdb 版本:GNU gdb (GDB) 12.0.50.20211105-git

Reading symbols from /root/hello_program/a.out...
(gdb) target sim
Connected to the simulator.
(gdb) sim memory-size 4Mb
(gdb) load
Loading section .interp, size 0x1c lma 238
Loading section .note.ABI-tag, size 0x20 lma 254
Loading section .note.gnu.build-id, size 0x24 lma 274
Loading section .gnu.hash, size 0x1c lma 298
Loading section .dynsym, size 0xc0 lma 2b8
Loading section .dynstr, size 0x96 lma 378
Loading section .gnu.version, size 0x10 lma 40e
Loading section .gnu.version_r, size 0x20 lma 420
Loading section .rela.dyn, size 0xd8 lma 440
Loading section .rela.plt, size 0x18 lma 518
Loading section .init, size 0x17 lma 530
Loading section .plt, size 0x20 lma 550
Loading section .plt.got, size 0x8 lma 570
Loading section .text, size 0x1c2 lma 580
Loading section .fini, size 0x9 lma 744
Loading section .rodata, size 0x10 lma 750
Loading section .eh_frame_hdr, size 0x3c lma 760
Loading section .eh_frame, size 0x10c lma 7a0
Loading section .init_array, size 0x8 lma 200dd8
Loading section .fini_array, size 0x8 lma 200de0
Loading section .jcr, size 0x8 lma 200de8
Loading section .dynamic, size 0x1e0 lma 200df0
Loading section .got, size 0x30 lma 200fd0
Loading section .got.plt, size 0x20 lma 201000
Loading section .data, size 0x10 lma 201020
Start address 580
Transfer rate: 17760 bits in <1 sec.
(gdb) run
Starting program: /root/hello_program/a.out 


Fatal signal: Aborted
----- Backtrace -----
0x55ffda5588a7 gdb_internal_backtrace_1
    /root/binutils-gdb/gdb/bt-utils.c:121
0x55ffda5588a7 _Z22gdb_internal_backtracev
    /root/binutils-gdb/gdb/bt-utils.c:164
0x55ffda6506cd handle_fatal_signal
    /root/binutils-gdb/gdb/event-top.c:896
0x7f89e035905f ???
    /build/glibc-77giwP/glibc-2.24/signal/../sysdeps/unix/sysv/linux/x86_64/sigaction.c:0
0x7f89e0358fff __GI_raise
    ../sysdeps/unix/sysv/linux/raise.c:51
0x7f89e035a429 __GI_abort
    /build/glibc-77giwP/glibc-2.24/stdlib/abort.c:89
0x55ffda8e2728 sim_engine_invalid_insn
    /root/binutils-gdb/sim/bpf/traps.c:37
0x55ffda8da83d execute
    /root/binutils-gdb/sim/bpf/mloop-le.c:119

对于我用( clang -target bpf -g -O2 -c hello_world.c )编译的 bpf 代码

你好世界bpf代码

#include <linux/bpf.h>
#include "bpf_helpers.h"
#include <stdlib.h>
#include <stdio.h>

int bpf_prog(void *ctx) {
    
    char buf[] = "Hello World!\n";
    bpf_trace_printk(buf, sizeof(buf)); 
    bpf_trace_printk(buf, sizeof(buf)); 
    bpf_trace_printk(buf, sizeof(buf)); 
    bpf_trace_printk(buf, sizeof(buf));
            
    return 0;

}


错误

Type "apropos word" to search for commands related to "word"...
Reading symbols from /root/ebpf_test/hello_world.o...
(No debugging symbols found in /root/ebpf_test/hello_world.o)
(gdb) target sim
Connected to the simulator.
(gdb) sim memory-size 4Mb
(gdb) load
Loading section .text, size 0x28 lma 0
Loading section .rodata.str1.1, size 0xd lma 0
Start address 0
Transfer rate: 424 bits in <1 sec.
(gdb) run
Starting program: /root/ebpf_test/hello_world.o 


Fatal signal: Aborted
----- Backtrace -----
0x562154f4a63b gdb_internal_backtrace_1
    /root/binutils-gdb/gdb/bt-utils.c:121
0x562154f4a63b _Z22gdb_internal_backtracev
    /root/binutils-gdb/gdb/bt-utils.c:164
0x56215504d2ba handle_fatal_signal
    /root/binutils-gdb/gdb/event-top.c:896
0x7f6f1a85503f ???
0x7f6f1a854fb7 ???
0x7f6f1a856920 ???
0x5621552fb9f8 sim_engine_invalid_insn
    /root/binutils-gdb/sim/bpf/traps.c:37
0x5621552f3aaa execute
    /root/binutils-gdb/sim/bpf/mloop-le.c:119
0x5621552f3aaa bpfbf_ebpfle_engine_run_full
    /root/binutils-gdb/sim/bpf/mloop-le.c:222
0x5621552ddee4 engine_run_1

当我尝试调试 ebpf 程序时也会发生同样的情况。感谢任何帮助,以了解从哪里开始解决问题。

谢谢

标签: debugginggdbtargetebpf

解决方案


查看 GDB 加载的部分的数量,我不相信您的目标文件被编译为 eBPF 字节码。是gcc -g hello_world.c您用来生成它的命令吗?这将从您的主机架构(可能是 x86_64)编译指令。

编译为 eBPF

为了编译为 eBPF 指令,大多数人使用 clang 而不是 gcc。现在有一个 eBPF 的 gcc 后端,但我不知道它的状态是什么,我只是知道它的 eBPF 支持不如 clang/LLVM 那么完整。使用 clang,您可以运行:

$ clang -target bpf -g -O2 -c hello_world.c

这将生成一个包含 eBPF 指令的目标文件。请注意,我通常会添加-Wall-o hello_world.o显示潜在警告并命名输出文件。生成的目标文件应该可以在 gdb 中工作,前提是您有支持 eBPF 的最新版本(否则请参见此处)。

如果你关心一个特定的 eBPF 指令集(如果你刚开始,你可能不关心),你可以通过分两步编译来指定它,并通过选项传递相关-mcpu选项llc

$ clang -g -O2 -Wall -emit-llvm -c hello_world.c -o - | \
    llc -march=bpf -mcpu=probe -filetype=obj -o hello_world.o

另请参阅此资源以获取详细信息以及在程序集中编译和从程序集中编译。


推荐阅读