qemu riscv 用户模式 C++/musl 段错误
我是 qemu 新手,并尝试在用户模式下运行 riscv 二进制文件。不确定我是否遇到了错误或只是做错了什么。我使用的系统是非常简单的 x86_64 上的 Fedora 35。
作为参考,C++ hello world 使用来自 musl.cc 的预构建工具链对 mipsel 运行良好。
$ cat hello.cc
#include <iostream>
int main() {
std::cout << "Hello\n";
return 0;
}
$ mipsel-linux-musl-g++ -static -g -O0 hello.cc -o hello
$ qemu-mipsel hello
Hello
对于带有 riscv 的 C 也是如此(32 或 64 似乎并不重要)。
$ cat hello.c
#include<stdio.h>
int main(int argc, char **argv) {
printf("Hello\n");
return 0;
}
$ riscv32-linux-musl-gcc -static -g -Og hello.c -o hello
$ qemu-riscv32 hello
Hello
但对于 C++/riscv 我遇到了段错误。
$ riscv32-linux-musl-g++ -static -g -Og hello.cc -o hello
$ qemu-riscv32 hello
Segmentation fault (core dumped)
显然来自 qemu 本身
Thread 1 "qemu-riscv32" received signal SIGSEGV, Segmentation fault.
0x00007fffe802558e in code_gen_buffer ()
(gdb) bt
#0 0x00007fffe802558e in code_gen_buffer ()
#1 0x00005555556bb44e in cpu_tb_exec (cpu=0x555555887b50, itb=<optimized out>, tb_exit=0x7fffffffd9a0) at ../accel/tcg/cpu-exec.c:353
#2 0x00005555556bc2f9 in cpu_loop_exec_tb (tb_exit=0x7fffffffd9a0, last_tb=<synthetic pointer>, tb=0x7fffe8025500 <code_gen_buffer+152787>, cpu=0x555555887b50)
at ../accel/tcg/cpu-exec.c:812
#3 cpu_exec (cpu=cpu@entry=0x555555887b50) at ../accel/tcg/cpu-exec.c:970
#4 0x00005555555eed28 in cpu_loop (env=0x55555588fe40) at ../linux-user/riscv/cpu_loop.c:37
#5 0x00005555555e2b81 in main (argc=<optimized out>, argv=0x7fffffffe1c8, envp=<optimized out>) at ../linux-user/main.c:885
riscv64 的系统模拟模式中也会发生类似的情况。
我很高兴将此报告为 qemu bug,但似乎更有可能我只是做错了什么。我做错了什么吗?
更新:
我附加到 gdb 存根,并且段错误发生在二进制文件中的动态转换上:
(gdb) bt
#0 __cxxabiv1::__dynamic_cast (src_ptr=0x40000e19e0 <(anonymous namespace)::ctype_c>, src_type=0x40000d8808 <typeinfo for std::locale::facet>, dst_type=0x40000d9ac0 <typeinfo for std::ctype<char>>, src2dst=0)
at ../../../../src_gcc/libstdc++-v3/libsupc++/dyncast.cc:74
#1 0x000000400005ed58 in std::has_facet<std::ctype<char> > (__loc=...) at /tmp/m1132/build/local/riscv64-linux-musl/obj_gcc/riscv64-linux-musl/libstdc++-v3/include/bits/locale_classes.tcc:110
#2 0x0000004000054be0 in std::basic_ios<char, std::char_traits<char> >::_M_cache_locale (this=this@entry=0x40000e0af8 <std::cout+8>, __loc=...)
at /tmp/m1132/build/local/riscv64-linux-musl/obj_gcc/riscv64-linux-musl/libstdc++-v3/include/bits/basic_ios.tcc:159
#3 0x0000004000054eaa in std::basic_ios<char, std::char_traits<char> >::init (this=this@entry=0x40000e0af8 <std::cout+8>, __sb=__sb@entry=0x40000e00d8 <__gnu_internal::buf_cout_sync>)
at /tmp/m1132/build/local/riscv64-linux-musl/obj_gcc/riscv64-linux-musl/libstdc++-v3/include/bits/basic_ios.tcc:132
#4 0x0000004000027ad2 in std::basic_ostream<char, std::char_traits<char> >::basic_ostream (__sb=<optimized out>, this=<optimized out>, __in_chrg=<optimized out>, __vtt_parm=<optimized out>)
at /tmp/m1132/build/local/riscv64-linux-musl/obj_gcc/riscv64-linux-musl/libstdc++-v3/include/ostream:85
#5 std::ios_base::Init::Init (this=<optimized out>) at ../../../../../src_gcc/libstdc++-v3/src/c++98/ios_init.cc:91
#6 std::ios_base::Init::Init (this=<optimized out>) at ../../../../../src_gcc/libstdc++-v3/src/c++98/ios_init.cc:78
#7 0x00000040000278c0 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at /home/jpkenny/src/riscv64-linux-musl-cross/riscv64-linux-musl/include/c++/11.2.1/iostream:74
#8 0x00000040000278fa in _GLOBAL__sub_I_main () at hello.cc:5
#9 0x000000400008fbfa in libc_start_init ()
Backtrace stopped: frame did not save the PC
根据 gdb,这发生在最后一个 asm 指令上:
000000000007d38e <__dynamic_cast>:
7d38e: c55d beqz a0,7d43c <__dynamic_cast+0xae>
7d390: 00053803 ld a6,0(a0)
7d394: 715d addi sp,sp,-80
7d396: fc26 sd s1,56(sp)
7d398: ff083703 ld a4,-16(a6)
7d39c: ff883783 ld a5,-8(a6)
7d3a0: 84b6 mv s1,a3
7d3a2: 972a add a4,a4,a0
7d3a4: 6314 ld a3,0(a4)
7d3a6: 4805 li a6,1
7d3a8: 1812 slli a6,a6,0x24
7d3aa: e802 sd zero,16(sp)
7d3ac: ec42 sd a6,24(sp)
7d3ae: e0a2 sd s0,64(sp)
7d3b0: 842a mv s0,a0
7d3b2: ff86b503 ld a0,-8(a3)
7d3b6: e486 sd ra,72(sp)
7d3b8: f84a sd s2,48(sp)
7d3ba: f44e sd s3,40(sp)
7d3bc: f052 sd s4,32(sp)
7d3be: e402 sd zero,8(sp)
7d3c0: 04f51663 bne a0,a5,7d40c <__dynamic_cast+0x7e>
7d3c4: 611c ld a5,0(a0)
I'm new to qemu and trying to run riscv binaries in user mode. Not sure if I'm running into a bug or just doing something wrong. System I'm using is pretty straightforward Fedora 35 on x86_64.
For reference, C++ hello world works fine for mipsel using prebuilt toolchain from musl.cc.
$ cat hello.cc
#include <iostream>
int main() {
std::cout << "Hello\n";
return 0;
}
$ mipsel-linux-musl-g++ -static -g -O0 hello.cc -o hello
$ qemu-mipsel hello
Hello
Likewise for C with riscv (32 or 64 doesn't seem to matter).
$ cat hello.c
#include<stdio.h>
int main(int argc, char **argv) {
printf("Hello\n");
return 0;
}
$ riscv32-linux-musl-gcc -static -g -Og hello.c -o hello
$ qemu-riscv32 hello
Hello
But for C++/riscv I get a segfault.
$ riscv32-linux-musl-g++ -static -g -Og hello.cc -o hello
$ qemu-riscv32 hello
Segmentation fault (core dumped)
Apparently coming from qemu itself
Thread 1 "qemu-riscv32" received signal SIGSEGV, Segmentation fault.
0x00007fffe802558e in code_gen_buffer ()
(gdb) bt
#0 0x00007fffe802558e in code_gen_buffer ()
#1 0x00005555556bb44e in cpu_tb_exec (cpu=0x555555887b50, itb=<optimized out>, tb_exit=0x7fffffffd9a0) at ../accel/tcg/cpu-exec.c:353
#2 0x00005555556bc2f9 in cpu_loop_exec_tb (tb_exit=0x7fffffffd9a0, last_tb=<synthetic pointer>, tb=0x7fffe8025500 <code_gen_buffer+152787>, cpu=0x555555887b50)
at ../accel/tcg/cpu-exec.c:812
#3 cpu_exec (cpu=cpu@entry=0x555555887b50) at ../accel/tcg/cpu-exec.c:970
#4 0x00005555555eed28 in cpu_loop (env=0x55555588fe40) at ../linux-user/riscv/cpu_loop.c:37
#5 0x00005555555e2b81 in main (argc=<optimized out>, argv=0x7fffffffe1c8, envp=<optimized out>) at ../linux-user/main.c:885
Something similar happens in system emulation mode for riscv64 as well.
I'm happy to report this as a qemu bug, but it seems more likely that I'm just doing something wrong. Am I doing something wrong?
Update:
I attached to the gdb stub and the segfault happens on a dynamic cast in the binary:
(gdb) bt
#0 __cxxabiv1::__dynamic_cast (src_ptr=0x40000e19e0 <(anonymous namespace)::ctype_c>, src_type=0x40000d8808 <typeinfo for std::locale::facet>, dst_type=0x40000d9ac0 <typeinfo for std::ctype<char>>, src2dst=0)
at ../../../../src_gcc/libstdc++-v3/libsupc++/dyncast.cc:74
#1 0x000000400005ed58 in std::has_facet<std::ctype<char> > (__loc=...) at /tmp/m1132/build/local/riscv64-linux-musl/obj_gcc/riscv64-linux-musl/libstdc++-v3/include/bits/locale_classes.tcc:110
#2 0x0000004000054be0 in std::basic_ios<char, std::char_traits<char> >::_M_cache_locale (this=this@entry=0x40000e0af8 <std::cout+8>, __loc=...)
at /tmp/m1132/build/local/riscv64-linux-musl/obj_gcc/riscv64-linux-musl/libstdc++-v3/include/bits/basic_ios.tcc:159
#3 0x0000004000054eaa in std::basic_ios<char, std::char_traits<char> >::init (this=this@entry=0x40000e0af8 <std::cout+8>, __sb=__sb@entry=0x40000e00d8 <__gnu_internal::buf_cout_sync>)
at /tmp/m1132/build/local/riscv64-linux-musl/obj_gcc/riscv64-linux-musl/libstdc++-v3/include/bits/basic_ios.tcc:132
#4 0x0000004000027ad2 in std::basic_ostream<char, std::char_traits<char> >::basic_ostream (__sb=<optimized out>, this=<optimized out>, __in_chrg=<optimized out>, __vtt_parm=<optimized out>)
at /tmp/m1132/build/local/riscv64-linux-musl/obj_gcc/riscv64-linux-musl/libstdc++-v3/include/ostream:85
#5 std::ios_base::Init::Init (this=<optimized out>) at ../../../../../src_gcc/libstdc++-v3/src/c++98/ios_init.cc:91
#6 std::ios_base::Init::Init (this=<optimized out>) at ../../../../../src_gcc/libstdc++-v3/src/c++98/ios_init.cc:78
#7 0x00000040000278c0 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at /home/jpkenny/src/riscv64-linux-musl-cross/riscv64-linux-musl/include/c++/11.2.1/iostream:74
#8 0x00000040000278fa in _GLOBAL__sub_I_main () at hello.cc:5
#9 0x000000400008fbfa in libc_start_init ()
Backtrace stopped: frame did not save the PC
According to gdb, this occurs on the last asm instruction here:
000000000007d38e <__dynamic_cast>:
7d38e: c55d beqz a0,7d43c <__dynamic_cast+0xae>
7d390: 00053803 ld a6,0(a0)
7d394: 715d addi sp,sp,-80
7d396: fc26 sd s1,56(sp)
7d398: ff083703 ld a4,-16(a6)
7d39c: ff883783 ld a5,-8(a6)
7d3a0: 84b6 mv s1,a3
7d3a2: 972a add a4,a4,a0
7d3a4: 6314 ld a3,0(a4)
7d3a6: 4805 li a6,1
7d3a8: 1812 slli a6,a6,0x24
7d3aa: e802 sd zero,16(sp)
7d3ac: ec42 sd a6,24(sp)
7d3ae: e0a2 sd s0,64(sp)
7d3b0: 842a mv s0,a0
7d3b2: ff86b503 ld a0,-8(a3)
7d3b6: e486 sd ra,72(sp)
7d3b8: f84a sd s2,48(sp)
7d3ba: f44e sd s3,40(sp)
7d3bc: f052 sd s4,32(sp)
7d3be: e402 sd zero,8(sp)
7d3c0: 04f51663 bne a0,a5,7d40c <__dynamic_cast+0x7e>
7d3c4: 611c ld a5,0(a0)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论