| /* -*- Mode: C++; tab-width: 4 indent-tabs-mode: nil -*- |
| * |
| * Copyright (c) 2015 Nest Labs, Inc. |
| * All rights reserved. |
| * |
| * This document is the property of Nest. It is considered |
| * confidential and proprietary information. |
| * |
| * This document may not be reproduced or transmitted in any form, |
| * in whole or in part, without the express written permission of |
| * Nest. |
| * |
| * Description: |
| * This is the source file used to hook into gtest framework to |
| * catch exceptions of fatal error. |
| * |
| */ |
| |
| #include <signal.h> |
| #include <ostream> |
| #include <stdexcept> |
| #include <execinfo.h> |
| |
| #include "gtest.h" |
| #include "nlgtest-exceptions.h" |
| |
| using namespace std; |
| |
| static void gtest_error_handler(int signum, siginfo_t *sig_info, void *context); |
| |
| void gtest_register_error_handlers() { |
| struct sigaction error_actions; |
| |
| sigemptyset(&error_actions.sa_mask); |
| error_actions.sa_sigaction = gtest_error_handler; |
| error_actions.sa_flags = SA_SIGINFO; |
| |
| assert(sigaction(SIGSEGV, &error_actions,NULL) == 0); |
| } |
| |
| static void gtest_error_handler(int signum, siginfo_t *sig_info, void *context) { |
| sigset_t x; |
| /* |
| int trace_size; |
| void *buffer[100]; |
| char **strings = (char **)NULL; |
| |
| trace_size = backtrace(buffer, 100); |
| printf("Received error signal %d. Backtrace() returned %d addresses\n", signum, trace_size); |
| |
| strings = backtrace_symbols(buffer, trace_size); |
| if (strings == NULL) { |
| printf("backtrace_symbols failed!!!"); |
| goto done; |
| } |
| |
| for (int i = 0; i < trace_size; i++) { |
| char syscom[256]; |
| printf("#%d, strings %s, trace %d\n", i, strings[i], buffer[i]); |
| |
| sprintf(syscom,"addr2line %p -e sighandler", buffer[i]); //last parameter is the name of this app |
| system(syscom); |
| sprintf(syscom,"addr2line %p -e aaaaaaa", buffer[i]); //last parameter is the name of this app |
| system(syscom); |
| } |
| |
| free(strings); |
| printf("Received error signal %s. At address %x \n", signum == SIGSEGV ? "SIGSEGV" : "unknown", sig_info->si_addr); |
| */ |
| printf("Received error signal %s.\n", signum == SIGSEGV ? "SIGSEGV" : "unknown"); |
| sigemptyset (&x); |
| sigaddset(&x, SIGSEGV); |
| sigprocmask(SIG_UNBLOCK, &x, NULL); |
| |
| FAILURE_NO_MSG; |
| } |
| |
| void gtest_unregister_error_handlers() { |
| struct sigaction default_actions; |
| |
| default_actions.sa_handler = SIG_DFL; |
| default_actions.sa_flags = 0; |
| |
| assert(sigaction(SIGSEGV, &default_actions,NULL) == 0); |
| } |