Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not work on ARMv8 #7

Open
rose-jinyang opened this issue Aug 26, 2020 · 3 comments
Open

Do not work on ARMv8 #7

rose-jinyang opened this issue Aug 26, 2020 · 3 comments

Comments

@rose-jinyang
Copy link

rose-jinyang commented Aug 26, 2020

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

@Plaristote
Copy link
Owner

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.

@Fabio3rs
Copy link

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
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants