dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.48k stars 4.77k forks source link

armv6: Segmentation fault while running dotnet #71642

Open dernasherbrezon opened 2 years ago

dernasherbrezon commented 2 years ago

Description

Hi,

I can't run "dotnet" or any "dotnet"-related applications (i.e. GitHub self-hosted agent) on Debian 9/10 RaspberryPI 1 (arm1176jzf-s).

The CPU (ARMHF) is very important here because everything works fine when I unplug the SD card from old raspberry pi and put into the new one. Same card, same code, but different CPU / hardware.

Do you know how I can troubleshoot this error? Tried compiling dotnet, but ran out of disk space on raspberry pi. 32Gb was not enough.

Reproduction Steps

Run on CPU (arm1176jzf-s):

 ./dotnet --help

Expected behavior

Print help.

Actual behavior

Output from gdb:

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x004fb1c6 in ?? ()

Regression?

No response

Known Workarounds

Run on newer Raspberry PI.

Configuration

.NET version: Any v6.0.+ OS: Debian 9, Debian 10 Arch: armhf CPU: arm1176jzf-s

Other information

Tried:

 LD_DEBUG=all ./dotnet

Output:

       730: symbol=_dl_find_dso_for_object;  lookup in file=/lib/ld-linux-armhf.so.3 [0]
       730: binding file /lib/arm-linux-gnueabihf/libc.so.6 [0] to /lib/ld-linux-armhf.so.3 [0]: normal symbol `_dl_find_dso_for_object' [GLIBC_PRIVATE]
       730: symbol=__tunable_get_val;  lookup in file=./actions-runner/bin/Runner.Listener [0]
       730: symbol=__tunable_get_val;  lookup in file=/usr/lib/arm-linux-gnueabihf/libarmmem-v6l.so [0]
       730: symbol=__tunable_get_val;  lookup in file=/lib/arm-linux-gnueabihf/libpthread.so.0 [0]
       730: symbol=__tunable_get_val;  lookup in file=/lib/arm-linux-gnueabihf/libdl.so.2 [0]
       730: symbol=__tunable_get_val;  lookup in file=/lib/arm-linux-gnueabihf/libstdc++.so.6 [0]
       730: symbol=__tunable_get_val;  lookup in file=/lib/arm-linux-gnueabihf/libm.so.6 [0]
       730: symbol=__tunable_get_val;  lookup in file=/lib/arm-linux-gnueabihf/libgcc_s.so.1 [0]
       730: symbol=__tunable_get_val;  lookup in file=/lib/arm-linux-gnueabihf/libc.so.6 [0]
       730: symbol=__tunable_get_val;  lookup in file=/lib/ld-linux-armhf.so.3 [0]
       730: binding file /lib/arm-linux-gnueabihf/libc.so.6 [0] to /lib/ld-linux-armhf.so.3 [0]: normal symbol `__tunable_get_val' [GLIBC_PRIVATE]
       730: 
       730: calling init: /lib/arm-linux-gnueabihf/libdl.so.2
       730: 
       730: 
       730: calling init: /usr/lib/arm-linux-gnueabihf/libarmmem-v6l.so
       730: 
Segmentation fault

Output when I run on a newer RaspberryPI:

 667:   binding file /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 [0] to /lib/arm-linux-gnueabihf/libc.so.6 [0]: normal symbol `malloc' [GLIBC_2.4]
       667: symbol=_dl_find_dso_for_object;  lookup in file=./dotnet [0]
       667: symbol=_dl_find_dso_for_object;  lookup in file=/usr/lib/arm-linux-gnueabihf/libarmmem.so [0]
       667: symbol=_dl_find_dso_for_object;  lookup in file=/lib/arm-linux-gnueabihf/libpthread.so.0 [0]
       667: symbol=_dl_find_dso_for_object;  lookup in file=/lib/arm-linux-gnueabihf/libdl.so.2 [0]
       667: symbol=_dl_find_dso_for_object;  lookup in file=/usr/lib/arm-linux-gnueabihf/libstdc++.so.6 [0]
       667: symbol=_dl_find_dso_for_object;  lookup in file=/lib/arm-linux-gnueabihf/libm.so.6 [0]
       667: symbol=_dl_find_dso_for_object;  lookup in file=/lib/arm-linux-gnueabihf/libgcc_s.so.1 [0]
       667: symbol=_dl_find_dso_for_object;  lookup in file=/lib/arm-linux-gnueabihf/libc.so.6 [0]
       667: symbol=_dl_find_dso_for_object;  lookup in file=/lib/ld-linux-armhf.so.3 [0]
       667: binding file /lib/arm-linux-gnueabihf/libc.so.6 [0] to /lib/ld-linux-armhf.so.3 [0]: normal symbol `_dl_find_dso_for_object' [GLIBC_PRIVATE]
       667: 
       667: calling init: /lib/arm-linux-gnueabihf/libdl.so.2
       667: 
       667: 
       667: calling init: /usr/lib/arm-linux-gnueabihf/libarmmem.so
       667: 
       667: 
       667: initialize program: ./dotnet
       667: 
       667: symbol=_ZNSt6localeC1Ev;  lookup in file=./dotnet [0]
       667: symbol=_ZNSt6localeC1Ev;  lookup in file=/usr/lib/arm-linux-gnueabihf/libarmmem.so [0]
       667: symbol=_ZNSt6localeC1Ev;  lookup in file=/lib/arm-linux-gnueabihf/libpthread.so.0 [0]
       667: symbol=_ZNSt6localeC1Ev;  lookup in file=/lib/arm-linux-gnueabihf/libdl.so.2 [0]
       667: symbol=_ZNSt6localeC1Ev;  lookup in file=/usr/lib/arm-linux-gnueabihf/libstdc++.so.6 [0]
       667: binding file /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 [0] to /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 [0]: normal symbol `_ZNSt6localeC1Ev' [GLIBCXX_3.4]

strace when I run on old raspberry pi:

read(3, "A.\0\0\0aeabi\0\1$\0\0\0\0056\0\6\6\10\1\t\1\n\2\22\4\23\1\24"..., 47) = 47
fstat64(3, {st_mode=S_IFREG|0755, st_size=1234700, ...}) = 0
mmap2(NULL, 1303872, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb6b6d000
mprotect(0xb6c97000, 61440, PROT_NONE)  = 0
mmap2(0xb6ca6000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x129000) = 0xb6ca6000
mmap2(0xb6ca9000, 9536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb6ca9000
close(3)                                = 0
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb6f15000
set_tls(0xb6f154c0, 0xb6f15bb8, 0xb6f23050, 0xb6f154c0, 0xb6f23050) = 0
mprotect(0xb6ca6000, 8192, PROT_READ)   = 0
mprotect(0xb6cd7000, 4096, PROT_READ)   = 0
mprotect(0xb6d56000, 4096, PROT_READ)   = 0
mprotect(0xb6e97000, 20480, PROT_READ)  = 0
mprotect(0xb6eb1000, 4096, PROT_READ)   = 0
mprotect(0xb6ed8000, 4096, PROT_READ)   = 0
mprotect(0xb6edc000, 20480, PROT_READ|PROT_WRITE) = 0
mprotect(0xb6edc000, 20480, PROT_READ|PROT_EXEC) = 0
cacheflush(0xb6edc000, 0xb6ee1000, 0, 0x15, 0) = 0
mprotect(0xb6ef0000, 4096, PROT_READ)   = 0
mprotect(0x461000, 4096, PROT_READ)     = 0
mprotect(0xb6f22000, 4096, PROT_READ)   = 0
munmap(0xb6f17000, 29031)               = 0
set_tid_address(0xb6f15068)             = 616
set_robust_list(0xb6f15070, 12)         = 0
rt_sigaction(SIGRTMIN, {sa_handler=0xb6eb72b0, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0xb6b996c0}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {sa_handler=0xb6eb7390, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0xb6b996c0}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
ugetrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM_INFINITY}) = 0
brk(NULL)                               = 0x187a000
brk(0x189f000)                          = 0x189f000
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x4a91c6} ---

And when I run on newer Raspberry PI:

read(3, "A.\0\0\0aeabi\0\1$\0\0\0\0056\0\6\6\10\1\t\1\n\2\22\4\23\1\24"..., 47) = 47
fstat64(3, {st_mode=S_IFREG|0755, st_size=1234700, ...}) = 0
mmap2(NULL, 1303872, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x76c05000
mprotect(0x76d2f000, 61440, PROT_NONE)  = 0
mmap2(0x76d3e000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x129000) = 0x76d3e000
mmap2(0x76d41000, 9536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x76d41000
close(3)                                = 0
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76fae000
set_tls(0x76fae6e0, 0x76faedd8, 0x76fbb050, 0x76fae6e0, 0x76fbb050) = 0
mprotect(0x76d3e000, 8192, PROT_READ)   = 0
mprotect(0x76d6f000, 4096, PROT_READ)   = 0
mprotect(0x76dee000, 4096, PROT_READ)   = 0
mprotect(0x76f2f000, 20480, PROT_READ)  = 0
mprotect(0x76f49000, 4096, PROT_READ)   = 0
mprotect(0x76f70000, 4096, PROT_READ)   = 0
mprotect(0x76f74000, 20480, PROT_READ|PROT_WRITE) = 0
mprotect(0x76f74000, 20480, PROT_READ|PROT_EXEC) = 0
cacheflush(0x76f74000, 0x76f79000, 0, 0x15, 0) = 0
mprotect(0x76f88000, 4096, PROT_READ)   = 0
mprotect(0x429000, 4096, PROT_READ)     = 0
mprotect(0x76fba000, 4096, PROT_READ)   = 0
munmap(0x76fb0000, 29031)               = 0
set_tid_address(0x76fae288)             = 660
set_robust_list(0x76fae290, 12)         = 0
rt_sigaction(SIGRTMIN, {sa_handler=0x76f4f2b0, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x76c316c0}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {sa_handler=0x76f4f390, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0x76c316c0}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
ugetrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM_INFINITY}) = 0
brk(NULL)                               = 0x1cb5000
brk(0x1cda000)                          = 0x1cda000
futex(0x76f36290, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x76f36294, FUTEX_WAKE_PRIVATE, 2147483647) = 0
dotnet-issue-labeler[bot] commented 2 years ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

jkotas commented 2 years ago

Raspberry Pi 1 is arm v6. You need to build Mono for arm v6 to make this work - see https://github.com/dotnet/runtime/pull/62594.

cc @directhex

dernasherbrezon commented 2 years ago

Do you know why it is failing with sigserv and not with “illegal instruction set”? Just curious.

Should I build with “architecture” armhf or arm32v6? It’s a little bit confusing with the way arm mapped in Debian/gcc.

michaldobrodenka commented 1 year ago

If you want, I compiled net 7.0 with mono for ARMv6 and have it in docker which I use for building self contained apps for linux-armv6. It even supports asp. Net & kestrel

https://hub.docker.com/r/taphome/dotnet7armv6/tags