Gtest-trace.c revision e4593e2493923f93dfa6c92ee5327b4ce577a818
19e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura/* libunwind - a platform-independent unwind library 23b9fd99cb78383e0ce8cd1a31e3b824a30ef965eLassi Tuura Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY 39e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 49e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi TuuraPermission is hereby granted, free of charge, to any person obtaining 59e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuuraa copy of this software and associated documentation files (the 69e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura"Software"), to deal in the Software without restriction, including 79e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuurawithout limitation the rights to use, copy, modify, merge, publish, 89e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuuradistribute, sublicense, and/or sell copies of the Software, and to 99e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuurapermit persons to whom the Software is furnished to do so, subject to 109e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuurathe following conditions: 119e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 129e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi TuuraThe above copyright notice and this permission notice shall be 139e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuuraincluded in all copies or substantial portions of the Software. 149e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 159e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi TuuraTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 169e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi TuuraEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 179e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi TuuraMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 189e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi TuuraNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 199e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi TuuraLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 209e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi TuuraOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 219e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi TuuraWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 229e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 239e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#ifdef HAVE_CONFIG_H 249e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura# include "config.h" 259e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#endif 269e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 279e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#include <errno.h> 289e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#if HAVE_EXECINFO_H 299e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura# include <execinfo.h> 309e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#else 319e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura extern int backtrace (void **, int); 329e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#endif 339e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#include <signal.h> 349e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#include <stdio.h> 359e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#include <stdlib.h> 369e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#include <string.h> 379e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#include <unistd.h> 389e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#include <libunwind.h> 399e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 409e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#define panic(args...) \ 419e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura { fprintf (stderr, args); exit (-1); } 429e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 439e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#ifndef HAVE_SIGHANDLER_T 449e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuuratypedef RETSIGTYPE (*sighandler_t) (int); 459e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#endif 469e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 47e4593e2493923f93dfa6c92ee5327b4ce577a818Ken Werner#define SIG_STACK_SIZE 0x100000 48e4593e2493923f93dfa6c92ee5327b4ce577a818Ken Werner 499e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuuraint verbose; 509e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuuraint num_errors; 519e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 529e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura/* These variables are global because they 539e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura * cause the signal stack to overflow */ 549e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuurachar buf[512], name[256]; 555f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuuravoid *addresses[3][128]; 569e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuuraunw_cursor_t cursor; 579e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuuraucontext_t uc; 589e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 599e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuurastatic void 609e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuurado_backtrace (void) 619e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura{ 629e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura unw_word_t ip; 639e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura int ret = -UNW_ENOINFO; 645f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura int depth = 0; 655f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura int i, n, m; 669e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 679e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura if (verbose) 685f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura printf ("\tnormal trace:\n"); 699e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 709e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura unw_getcontext (&uc); 719e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura if (unw_init_local (&cursor, &uc) < 0) 729e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura panic ("unw_init_local failed!\n"); 739e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 745f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura do 759e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura { 769e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura unw_get_reg (&cursor, UNW_REG_IP, &ip); 775f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura addresses[0][depth] = (void *) ip; 789e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura } 795f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura while ((ret = unw_step (&cursor)) > 0 && ++depth < 128); 809e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 819e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura if (ret < 0) 829e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura { 835f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura unw_get_reg (&cursor, UNW_REG_IP, &ip); 845f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura printf ("FAILURE: unw_step() returned %d for ip=%lx\n", ret, (long) ip); 855f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura ++num_errors; 869e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura } 879e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 889e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura if (verbose) 899e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura for (i = 0; i < depth; ++i) 909e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura printf ("\t #%-3d ip=%p\n", i, addresses[0][i]); 919e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 929e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura if (verbose) 939e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura printf ("\n\tvia backtrace():\n"); 949e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 959e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura n = backtrace (addresses[1], 128); 969e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 979e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura if (verbose) 989e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura for (i = 0; i < n; ++i) 999e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura printf ("\t #%-3d ip=%p\n", i, addresses[1][i]); 1009e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 1015f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura if (verbose) 1025f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura printf ("\n\tvia unw_backtrace():\n"); 1035f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura 1045f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura m = unw_backtrace (addresses[2], 128); 1055f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura 1065f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura if (verbose) 1075f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura for (i = 0; i < m; ++i) 1085f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura printf ("\t #%-3d ip=%p\n", i, addresses[2][i]); 1095f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura 1105f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura if (m != depth+1) 1119e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura { 1125f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura printf ("FAILURE: unw_step() loop and unw_backtrace() depths differ: %d vs. %d\n", depth, m); 1139e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura ++num_errors; 1149e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura } 1155f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura 1165f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura if (n != depth+1) 1175f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura { 1185f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura printf ("FAILURE: unw_step() loop and backtrace() depths differ: %d vs. %d\n", depth, n); 1195f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura ++num_errors; 1205f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura } 1215f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura 1225f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura if (n == m) 1235f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura for (i = 1; i < n; ++i) 1245f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura /* Allow one in difference in comparison, trace returns adjusted addresses. */ 1255f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura if (labs((unw_word_t) addresses[1][i] - (unw_word_t) addresses[2][i]) > 1) 1265f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura { 1275f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura printf ("FAILURE: backtrace() and unw_backtrace() addresses differ at %d: %p vs. %p\n", 1285f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura i, addresses[1][n], addresses[2][n]); 1295f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura ++num_errors; 1305f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura } 1315f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura 1325f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura if (n == depth+1) 1339e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura for (i = 1; i < depth; ++i) 1349e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura /* Allow one in difference in comparison, trace returns adjusted addresses. */ 1359e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura if (labs((unw_word_t) addresses[0][i] - (unw_word_t) addresses[1][i]) > 1) 1369e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura { 1375f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura printf ("FAILURE: unw_step() loop and backtrace() addresses differ at %d: %p vs. %p\n", 1389e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura i, addresses[0][n], addresses[1][n]); 1399e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura ++num_errors; 1409e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura } 1419e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura} 1429e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 1439e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuuravoid 1449e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuurafoo (long val) 1459e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura{ 1469e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura do_backtrace (); 1479e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura} 1489e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 1499e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuuravoid 1509e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuurabar (long v) 1519e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura{ 1529e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura extern long f (long); 1539e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura int arr[v]; 1549e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 1559e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura /* This is a vain attempt to use up lots of registers to force 1569e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura the frame-chain info to be saved on the memory stack on ia64. 1579e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura It happens to work with gcc v3.3.4 and gcc v3.4.1 but perhaps 1589e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura not with any other compiler. */ 1599e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura foo (f (arr[0]) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) 1609e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) 1619e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) 1629e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) 1639e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) 1649e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) 1659e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) 1669e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) 1679e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) 1689e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) 1699e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) 1709e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) 1719e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) 1729e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) 1739e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) 1749e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) 1759e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + f (v)) 1769e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) 1779e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura ))))))))))))))))))))))))))))))))))))))))))))))))))))))); 1789e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura} 1799e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 1809e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuuravoid 1819e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuurasighandler (int signal, void *siginfo, void *context) 1829e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura{ 1839e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura ucontext_t *uc = context; 1849e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura int sp; 1859e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 1869e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura if (verbose) 1879e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura { 1889e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura printf ("sighandler: got signal %d, sp=%p", signal, &sp); 1899e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#if UNW_TARGET_IA64 1909e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura# if defined(__linux__) 1919e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura printf (" @ %lx", uc->uc_mcontext.sc_ip); 1929e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura# else 1939e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura { 1949e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura uint16_t reason; 1959e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura uint64_t ip; 1969e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 1979e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura __uc_get_reason (uc, &reason); 1989e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura __uc_get_ip (uc, &ip); 1999e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura printf (" @ %lx (reason=%d)", ip, reason); 2009e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura } 2019e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura# endif 2029e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#elif UNW_TARGET_X86 2039e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#if defined __linux__ 2049e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_EIP]); 2059e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#elif defined __FreeBSD__ 2069e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_eip); 2079e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#endif 2089e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#elif UNW_TARGET_X86_64 2099e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#if defined __linux__ 2109e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_RIP]); 2119e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#elif defined __FreeBSD__ 2129e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_rip); 2139e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#endif 2149e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#endif 2159e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura printf ("\n"); 2169e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura } 2179e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura do_backtrace(); 2189e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura} 2199e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 2209e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuuraint 2219e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuuramain (int argc, char **argv) 2229e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura{ 2239e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura struct sigaction act; 2249e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura stack_t stk; 2259e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 2269e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura verbose = (argc > 1); 2279e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 2289e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura if (verbose) 2299e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura printf ("Normal backtrace:\n"); 2309e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 2319e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura bar (1); 2329e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 2339e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura memset (&act, 0, sizeof (act)); 2349e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura act.sa_handler = (void (*)(int)) sighandler; 2359e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura act.sa_flags = SA_SIGINFO; 2369e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura if (sigaction (SIGTERM, &act, NULL) < 0) 2379e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura panic ("sigaction: %s\n", strerror (errno)); 2389e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 2399e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura if (verbose) 2409e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura printf ("\nBacktrace across signal handler:\n"); 2419e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura kill (getpid (), SIGTERM); 2429e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 2439e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura if (verbose) 2449e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura printf ("\nBacktrace across signal handler on alternate stack:\n"); 245e4593e2493923f93dfa6c92ee5327b4ce577a818Ken Werner stk.ss_sp = malloc (SIG_STACK_SIZE); 2469e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura if (!stk.ss_sp) 247e4593e2493923f93dfa6c92ee5327b4ce577a818Ken Werner panic ("failed to allocate %u bytes\n", SIG_STACK_SIZE); 248e4593e2493923f93dfa6c92ee5327b4ce577a818Ken Werner stk.ss_size = SIG_STACK_SIZE; 2499e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura stk.ss_flags = 0; 2509e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura if (sigaltstack (&stk, NULL) < 0) 2519e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura panic ("sigaltstack: %s\n", strerror (errno)); 2529e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 2539e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura memset (&act, 0, sizeof (act)); 2549e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura act.sa_handler = (void (*)(int)) sighandler; 2559e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura act.sa_flags = SA_ONSTACK | SA_SIGINFO; 2569e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura if (sigaction (SIGTERM, &act, NULL) < 0) 2579e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura panic ("sigaction: %s\n", strerror (errno)); 2589e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura kill (getpid (), SIGTERM); 2599e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 2609e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura if (num_errors > 0) 2619e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura { 2629e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura fprintf (stderr, "FAILURE: detected %d errors\n", num_errors); 2639e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura exit (-1); 2649e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura } 2659e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura 2669e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura if (verbose) 2679e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura printf ("SUCCESS.\n"); 2689e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura return 0; 2699e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura} 270