segvcatch icon indicating copy to clipboard operation
segvcatch copied to clipboard

Do not work on ARMv8

Open rose-jinyang opened this issue 5 years ago • 3 comments

Hello How are you? Thanks for contributing this project. I tried to use this library on Jeston. Ubuntu 18.04 64 bit OS for armv8-aarch64 is installed on Jetson. gcc & g++ version are 7.5.0. I built both your library and test app successfully on Jetson. But when I run the test app, the app does not catch segmentation fault. I conformed that this library works well on Desktop Ubuntu 18.04 x64 and gcc 7.5.0. Please let me know the reason asap. Thanks

rose-jinyang avatar Aug 26 '20 15:08 rose-jinyang

I'm not surprised it doesn't work, as different architectures would require different implementations. This library only implements support for x86.

Unfortunately, I probably can't fix this. The library seemed abandonned, and I only exported it from Google Code to prevent it from disappearing. I do what maintenance I can do, but I'm not the original developer of this library, and I have little knowledge about how it works.

Plaristote avatar Jan 03 '21 14:01 Plaristote

I am trying to get the code working in ARM, but it seems the compiler removes the try catch block in some cases (look at the assembly) https://godbolt.org/z/hr3WcxE3f

Inserting a printf with some string the catch returns to the assembly: https://godbolt.org/z/v3TnbYW7c Inserting a call to a external function can solve this: https://godbolt.org/z/qEqMKTzfE

My standalone test code based on this project code, but for ARM

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <stdexcept>
#include <iostream>
#  include <signal.h>
#  include <unistd.h>
#  include <sys/syscall.h>
#include <execinfo.h>
#include <ucontext.h>
#include <stdio.h>
#include <stdlib.h>

// Signal handler function
void signal_handler(int signum, siginfo_t *info, void *ptr) {
    printf("Received signal: %d\n", signum);

    printf("Signal code: %d\n", info->si_code);
    printf("Sender PID: %d\n", info->si_pid);
    // Additional information from siginfo_t can be used here
}

ucontext_t main_context;


void handlersegfault() {
    throw std::runtime_error("erro sigsegv");
}


void signal_segv(int signum, siginfo_t *info, void *ptr) {
    printf("Received signal: %d %p\n", signum, &signum);

    printf("Signal code: %d\n", info->si_code);
    printf("Sender PID: %d\n", info->si_pid);
    // Additional information from siginfo_t can be used here

    ucontext_t *context = (ucontext_t *)ptr;

    // Restore the context to main_context
    //swapcontext(context, &main_context);


    context->uc_mcontext.pc = (uintptr_t)handlersegfault;

//setcontext(context);


}

static void unblock_signal(int signum __attribute__((__unused__)))
{
//#ifdef _POSIX_VERSION
    sigset_t sigs;
    sigemptyset(&sigs);
    sigaddset(&sigs, signum);
    sigprocmask(SIG_UNBLOCK, &sigs, NULL);
//#endif
}


#  define MAKE_THROW_FRAME(_exception)

#  define RESTORE(name, syscall) RESTORE2 (name, syscall)
#  define RESTORE2(name, syscall)			\
asm						\
  (						\
   ".text\n"					\
   ".byte 0\n" \
   ".align 16\n"				\
   "__" #name ":\n"				\
   "	mov x8, " #syscall "\n"		\
   "	svc 0\n"				\
   );

/* The return code for realtime-signals.  */
RESTORE (restore_rt, __NR_rt_sigreturn)
void restore_rt (void) asm ("__restore_rt")
  __attribute__ ((visibility ("hidden")));

extern "C" 
{
  struct kernel_sigaction 
  {
    void (*k_sa_sigaction)(int,siginfo_t *,void *);
    unsigned long k_sa_flags;
    void (*k_sa_restorer) (void);
    sigset_t k_sa_mask;
  };
}

static void _Jv_catch_segv(int signum, siginfo_t *,
                           void *_p __attribute__((__unused__))) {
ucontext_t *context = (ucontext_t *)_p;



    unblock_signal(SIGSEGV);
    //MAKE_THROW_FRAME(nullp);
   // handle_segv();
    printf("Received signal: %d %p\n", signum, &signum);


    printf("Old PC: %p\n", (void *)context->uc_mcontext.pc);
    // Restore the context to main_context


    context->uc_mcontext.pc = (uintptr_t)handlersegfault;
}

#  define INIT_SEGV						\
do								\
  {								\
    struct kernel_sigaction act;				\
    act.k_sa_sigaction = _Jv_catch_segv;			\
    sigemptyset (&act.k_sa_mask);				\
    act.k_sa_flags = SA_SIGINFO|0x4000000;			\
    act.k_sa_restorer = restore_rt;				\
    syscall (SYS_rt_sigaction, SIGSEGV, &act, NULL, _NSIG / 8);	\
  }								\
while (0)  

int main() {
    struct sigaction sa;

    // Set up the signal handler
    sa.sa_sigaction = &signal_handler;
    sa.sa_flags = SA_SIGINFO;
    sigemptyset(&sa.sa_mask);

    // Register signal handlers using sigaction
    if (sigaction(SIGINT, &sa, NULL) == -1) {
        perror("Unable to catch SIGINT");
        exit(EXIT_FAILURE);
    }

    if (sigaction(SIGTERM, &sa, NULL) == -1) {
        perror("Unable to catch SIGTERM");
        exit(EXIT_FAILURE);
    }

    INIT_SEGV;

    sleep(1);
//int a = 0;
//printf("ptr stack %p\n", &a);
try {
    *(int*)0 = 0;
} catch(const std::exception &e) {
std::cout << "Caught" << e.what() << std::endl;
}

    // Infinite loop to keep the program running
    printf("Signal handling example. Waiting for signals...\n");
    while(1) {
        sleep(1);
    }

    return 0;
}


Fabio3rs avatar Feb 25 '24 17:02 Fabio3rs

My test code in the lib https://github.com/Plaristote/segvcatch/pull/9

https://github.com/Fabio3rs/segvcatch/tree/testing-on-raspberrypi-aarch64

Fabio3rs avatar Feb 25 '24 20:02 Fabio3rs