This is an archive of the discontinued LLVM Phabricator instance.

[libunwind] Unwind through Linux riscv sigreturn trampoline
ClosedPublic

Authored by wf520gg on Apr 17 2023, 12:31 AM.

Details

Summary

Similar to D90898 (Linux AArch64) and D124765 (SystemZ).

On an Arch Linux RISC-V (riscv64gc), the following code

#define _GNU_SOURCE
#include <dlfcn.h>
#include <libunwind.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

static void handler(int signo) {
  unw_context_t context;
  unw_cursor_t cursor;
  unw_getcontext(&context);
  unw_init_local(&cursor, &context);
  unw_word_t pc, sp;
  do {
    unw_get_reg(&cursor, UNW_REG_IP, &pc);
    unw_get_reg(&cursor, UNW_REG_SP, &sp);
    printf("pc=0x%016zx sp=0x%016zx", (size_t)pc, (size_t)sp);
    Dl_info info = {};
    if (dladdr((void *)pc, &info))
      printf(" %s:%s", info.dli_fname, info.dli_sname ? info.dli_sname : "");
    puts("");
  } while (unw_step(&cursor) > 0);
  exit(0);
}

int main() {
  signal(SIGUSR1, handler);
  raise(SIGUSR1);
  return 1;
}

linked with -Wl,--export-dynamic gives an output like

pc=0x0000000000010a82 sp=0x00007fffd8a0b910 ./b:
pc=0x00007fffa7e77800 sp=0x00007fffd8a0c520 linux-vdso.so.1:__vdso_rt_sigreturn
pc=0x00007fffa7d73bee sp=0x00007fffd8a0c960 /usr/lib/libc.so.6:
pc=0x00007fffa7d3ed66 sp=0x00007fffd8a0c9b0 /usr/lib/libc.so.6:gsignal
pc=0x0000000000010a3c sp=0x00007fffd8a0c9c0 ./b:main
pc=0x00007fffa7d2f1d4 sp=0x00007fffd8a0c9e0 /usr/lib/libc.so.6:
pc=0x00007fffa7d2f27c sp=0x00007fffd8a0cb10 /usr/lib/libc.so.6:__libc_start_main
pc=0x00000000000109a0 sp=0x00007fffd8a0cb60 ./b:_start

Co-Authored-By: Fangrui Song <i@maskray.me>

Diff Detail

Event Timeline

wf520gg created this revision.Apr 17 2023, 12:31 AM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptApr 17 2023, 12:31 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript
wf520gg requested review of this revision.Apr 17 2023, 12:31 AM
wf520gg updated this revision to Diff 514488.Apr 17 2023, 6:04 PM

Fix clang-format issue

wf520gg updated this revision to Diff 514794.Apr 18 2023, 5:31 PM

Remove redundant assignments

wf520gg updated this revision to Diff 514799.Apr 18 2023, 6:15 PM

Set PC reg

Do you know how to test this? The code looks reasonable, but I'd like to reproduce the issue... I may need a RISC-V image (with gcc,gdb,etc) which can run in qemu-system. On the non-riscv host I'll need some LLVM_ENABLE_RUNTIMES way to cross compile for RISC-V.

libunwind/src/UnwindCursor.hpp
2916

delete this blank line

Do you know how to test this? The code looks reasonable, but I'd like to reproduce the issue... I may need a RISC-V image (with gcc,gdb,etc) which can run in qemu-system. On the non-riscv host I'll need some LLVM_ENABLE_RUNTIMES way to cross compile for RISC-V.

Hi MaskRay,
Thanks for your review.This issue happend when I tested the bionic unwind test case in the RISC-V Android environment. The test case file is stack_unwinding_test.cpp based on gtest(path is bionic/test/), I upload some part of this file{F27186091}.Please check it. If you want to reporduce it, I can show the command.Thanks!

wf520gg updated this revision to Diff 514819.Apr 18 2023, 10:02 PM

Delete the blank line

wf520gg accepted this revision.Apr 20 2023, 5:43 PM
wf520gg marked an inline comment as done.
wf520gg added inline comments.
libunwind/src/UnwindCursor.hpp
2916

done

wf520gg marked an inline comment as done.Apr 20 2023, 5:43 PM
MaskRay requested changes to this revision.Apr 23 2023, 3:06 PM

Please adjust libunwind/test/signal_unwind.pass.cpp and ensure it passes.

libunwind/src/UnwindCursor.hpp
2899

Where is __default_sa_restorer defined? Isn't it only used by Linux arm?

2922

This causes
error: use of undeclared identifier 'siginfo_t'
on glibc riscv64.

This revision now requires changes to proceed.Apr 23 2023, 3:06 PM
wf520gg added inline comments.Apr 23 2023, 6:28 PM
libunwind/src/UnwindCursor.hpp
2899

Yes,you are right,just arm has this defination.There is some ambiguity about this comment, that should be "A signal frame will have a return address pointing to sigreturn syscall just like arm __default_sa_restorer."。

2922

I will add riscv arch for signal_unwind.pass.cpp. Could you tell me how to test it? or is there any doc about how to run the libunwind test?I haven't found it.Thanks.

I'm building and testing the code. After add test case will upload new patch. Thanks.

MaskRay added inline comments.Apr 24 2023, 4:35 PM
libunwind/src/UnwindCursor.hpp
2899

FYI: I tested the first a.c example on https://maskray.me/blog/2022-04-10-unwinding-through-signal-handler on a very new Arch Linux RISC-V qemu image and I don't find that this patch fixes the unwinding.

For Linux, IIUC newer kernel ports place the signal trampoline in vdso instead of libc. __vdso_rt_sigreturn is more accurate.

I change some part of a.c code accroding to my test case, and then the problem can be reproduced, please check the file{F27260437}.
Without this change, the back trace only get one layer.

wf520gg updated this revision to Diff 520023.May 5 2023, 7:53 PM

Modify some comment and

MaskRay updated this revision to Diff 520107.May 6 2023, 10:58 AM
MaskRay retitled this revision from [RISC-V libunwind]:Fix RISC-V backtrace issue to [libunwind] Unwind through Linux riscv64 sigreturn frame.
MaskRay edited the summary of this revision. (Show Details)

Fix link (prefer Linux kernel's to glibc's)
Don't set UNW_RISCV_X0
Use _registers.getSP()

MaskRay updated this revision to Diff 520108.May 6 2023, 11:00 AM

Move riscv code before s390x for an alphabetical order

MaskRay accepted this revision.May 6 2023, 11:12 AM

LGTM.

libunwind/src/UnwindCursor.hpp
2899

This is __vdso_rt_sigreturn, not __vdso_rt_sigteturn. I'll fix it.

The canonical term is sigreturn trampoline (used the most in the Linux kernel), not signal frame.

This revision is now accepted and ready to land.May 6 2023, 11:12 AM
MaskRay updated this revision to Diff 520110.May 6 2023, 11:12 AM
MaskRay retitled this revision from [libunwind] Unwind through Linux riscv64 sigreturn frame to [libunwind] Unwind through Linux riscv sigreturn trampoline.
MaskRay edited the summary of this revision. (Show Details)

Fix comment. Add an example to the description

This revision was landed with ongoing or failed builds.May 6 2023, 11:17 AM
This revision was automatically updated to reflect the committed changes.