test-async-sig.c revision 459b2a5ba89c3ae0002e741cadbc723e4b1dd0a6
14471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm/* libunwind - a platform-independent unwind library 24471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm Copyright (C) 2004 Hewlett-Packard Co 34471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm Contributed by David Mosberger-Tang <davidm@hpl.hp.com> 44471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 54471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmPermission is hereby granted, free of charge, to any person obtaining 64471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidma copy of this software and associated documentation files (the 74471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm"Software"), to deal in the Software without restriction, including 84471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmwithout limitation the rights to use, copy, modify, merge, publish, 94471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmdistribute, sublicense, and/or sell copies of the Software, and to 104471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmpermit persons to whom the Software is furnished to do so, subject to 114471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmthe following conditions: 124471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 134471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmThe above copyright notice and this permission notice shall be 144471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmincluded in all copies or substantial portions of the Software. 154471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 164471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 174471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 184471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 194471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 204471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 214471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 224471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 234471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 244471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm/* Check whether basic unwinding truly is async-signal safe. */ 254471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 26459b2a5ba89c3ae0002e741cadbc723e4b1dd0a6Konstantin Belousov#ifdef HAVE_CONFIG_H 27459b2a5ba89c3ae0002e741cadbc723e4b1dd0a6Konstantin Belousov#include "config.h" 28459b2a5ba89c3ae0002e741cadbc723e4b1dd0a6Konstantin Belousov#endif 29459b2a5ba89c3ae0002e741cadbc723e4b1dd0a6Konstantin Belousov 30459b2a5ba89c3ae0002e741cadbc723e4b1dd0a6Konstantin Belousov#include <signal.h> 314471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm#include <stdio.h> 324471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm#include <stdlib.h> 334471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm#include <string.h> 344471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm#include <unistd.h> 354471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 364471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm#include <sys/time.h> 374471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 384471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm#define UNW_LOCAL_ONLY 394471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm#include <libunwind.h> 404471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 415f3d29562d53b5e144787fbf1abe598c6822b20dDavid Mosberger-Tangstatic const int nerrors_max = 100; 425f3d29562d53b5e144787fbf1abe598c6822b20dDavid Mosberger-Tang 434471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmstruct itimerval interval = 444471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm { 454471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm .it_interval = { .tv_sec = 0, .tv_usec = 0 }, 464471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm .it_value = { .tv_sec = 0, .tv_usec = 1000 } 474471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm }; 484471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 494471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmint verbose; 504471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmint nerrors; 514471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmint sigcount; 524471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 53b7e3444fea7f19f05e1fe033b96efad394ab9b4aPaul Pluzhnikov#ifndef CONFIG_BLOCK_SIGNALS 54b7e3444fea7f19f05e1fe033b96efad394ab9b4aPaul Pluzhnikov/* When libunwind is configured with --enable-block-signals=no, the caller 55b7e3444fea7f19f05e1fe033b96efad394ab9b4aPaul Pluzhnikov is responsible for preventing recursion via signal handlers. 56b7e3444fea7f19f05e1fe033b96efad394ab9b4aPaul Pluzhnikov We use a simple global here. In a multithreaded program, one would use 57b7e3444fea7f19f05e1fe033b96efad394ab9b4aPaul Pluzhnikov a thread-local variable. */ 58b7e3444fea7f19f05e1fe033b96efad394ab9b4aPaul Pluzhnikovint recurcount; 59b7e3444fea7f19f05e1fe033b96efad394ab9b4aPaul Pluzhnikov#endif 60b7e3444fea7f19f05e1fe033b96efad394ab9b4aPaul Pluzhnikov 614471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm#define panic(args...) \ 624471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm { ++nerrors; fprintf (stderr, args); return; } 634471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 644471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmstatic void 654471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmdo_backtrace (int may_print, int get_proc_name) 664471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm{ 674471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm char buf[512], name[256]; 684471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm unw_cursor_t cursor; 694471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm unw_word_t ip, sp, off; 704471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm unw_context_t uc; 714471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm int ret; 72a72abd4e46eb6e92747412fb036d0fb8279350acJan Kratochvil int depth = 0; 734471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 74b7e3444fea7f19f05e1fe033b96efad394ab9b4aPaul Pluzhnikov#ifndef CONFIG_BLOCK_SIGNALS 75b7e3444fea7f19f05e1fe033b96efad394ab9b4aPaul Pluzhnikov if (recurcount > 0) 76b7e3444fea7f19f05e1fe033b96efad394ab9b4aPaul Pluzhnikov return; 77b7e3444fea7f19f05e1fe033b96efad394ab9b4aPaul Pluzhnikov recurcount += 1; 78b7e3444fea7f19f05e1fe033b96efad394ab9b4aPaul Pluzhnikov#endif 79b7e3444fea7f19f05e1fe033b96efad394ab9b4aPaul Pluzhnikov 804471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm unw_getcontext (&uc); 814471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm if (unw_init_local (&cursor, &uc) < 0) 824471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm panic ("unw_init_local failed!\n"); 834471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 844471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm do 854471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm { 864471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm unw_get_reg (&cursor, UNW_REG_IP, &ip); 874471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm unw_get_reg (&cursor, UNW_REG_SP, &sp); 884471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 894471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm buf[0] = '\0'; 904471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm if (get_proc_name || (may_print && verbose)) 914471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm { 924471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm if (unw_get_proc_name (&cursor, name, sizeof (name), &off) == 0) 934471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm { 944471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm if (off) 954471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm snprintf (buf, sizeof (buf), "<%s+0x%lx>", name, (long) off); 964471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm else 974471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm { 984471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm size_t len = strlen (name); 994471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm buf[0] = '<'; 1004471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm memcpy (buf + 1, name, len); 1014471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm buf[len + 1] = '>'; 1024471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm buf[len + 2] = '\0'; 1034471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm } 1044471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm } 1054471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm } 1064471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 1074471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm if (may_print && verbose) 1084471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm printf ("%016lx %-32s (sp=%016lx)\n", (long) ip, buf, (long) sp); 1094471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 1104471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm ret = unw_step (&cursor); 1114471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm if (ret < 0) 1124471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm { 1134471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm unw_get_reg (&cursor, UNW_REG_IP, &ip); 1144471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm panic ("FAILURE: unw_step() returned %d for ip=%lx\n", 1154471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm ret, (long) ip); 1164471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm } 117a72abd4e46eb6e92747412fb036d0fb8279350acJan Kratochvil if (depth++ > 100) 118a72abd4e46eb6e92747412fb036d0fb8279350acJan Kratochvil { 119a72abd4e46eb6e92747412fb036d0fb8279350acJan Kratochvil panic ("FAILURE: unw_step() looping over %d iterations\n", depth); 120a72abd4e46eb6e92747412fb036d0fb8279350acJan Kratochvil break; 121a72abd4e46eb6e92747412fb036d0fb8279350acJan Kratochvil } 1224471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm } 1234471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm while (ret > 0); 124b7e3444fea7f19f05e1fe033b96efad394ab9b4aPaul Pluzhnikov 125b7e3444fea7f19f05e1fe033b96efad394ab9b4aPaul Pluzhnikov#ifndef CONFIG_BLOCK_SIGNALS 126b7e3444fea7f19f05e1fe033b96efad394ab9b4aPaul Pluzhnikov recurcount -= 1; 127b7e3444fea7f19f05e1fe033b96efad394ab9b4aPaul Pluzhnikov#endif 1284471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm} 1294471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 1304471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmvoid 1314471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmsighandler (int signal) 1324471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm{ 1334471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm if (verbose) 1344471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm printf ("sighandler(signal=%d, count=%d)\n", signal, sigcount); 1354471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 1364471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm do_backtrace (1, 1); 1374471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 1384471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm ++sigcount; 1394471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 1404471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm if (sigcount == 100) 1414471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL); 1424471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm else if (sigcount == 200) 1434471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD); 144a72abd4e46eb6e92747412fb036d0fb8279350acJan Kratochvil else if (sigcount == 300 || nerrors > nerrors_max) 1454471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm { 146a72abd4e46eb6e92747412fb036d0fb8279350acJan Kratochvil if (nerrors > nerrors_max) 147a72abd4e46eb6e92747412fb036d0fb8279350acJan Kratochvil panic ("Too many errors (%d)\n", nerrors); 1484471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm if (nerrors) 1494471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm { 1504471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); 1514471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm exit (-1); 1524471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm } 1534471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm if (verbose) 1544471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm printf ("SUCCESS.\n"); 1554471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm exit (0); 1564471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm } 1574471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm setitimer (ITIMER_VIRTUAL, &interval, NULL); 1584471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm} 1594471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 1604471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmint 1614471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidmmain (int argc, char **argv) 1624471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm{ 1634471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm struct sigaction act; 1644471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm long i = 0; 1654471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 1664471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm if (argc > 1) 1674471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm verbose = 1; 1684471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 1694471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE); 1704471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 1714471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm memset (&act, 0, sizeof (act)); 1724471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm act.sa_handler = sighandler; 1734471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm act.sa_flags = SA_SIGINFO; 1744471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm sigaction (SIGVTALRM, &act, NULL); 1754471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 1764471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm setitimer (ITIMER_VIRTUAL, &interval, NULL); 1774471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm 1784471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm while (1) 1794471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm { 1804471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm if (0 && verbose) 1814471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm printf ("%s: starting backtrace\n", __FUNCTION__); 1824471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm do_backtrace (0, (i++ % 100) == 0); 183a72abd4e46eb6e92747412fb036d0fb8279350acJan Kratochvil if (nerrors > nerrors_max) 184a72abd4e46eb6e92747412fb036d0fb8279350acJan Kratochvil { 185a72abd4e46eb6e92747412fb036d0fb8279350acJan Kratochvil panic ("Too many errors (%d)\n", nerrors); 186a72abd4e46eb6e92747412fb036d0fb8279350acJan Kratochvil exit (-1); 187a72abd4e46eb6e92747412fb036d0fb8279350acJan Kratochvil } 1884471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm } 189459b2a5ba89c3ae0002e741cadbc723e4b1dd0a6Konstantin Belousov return (0); 1904471c1e8c3958dc55e4abb0de5c5a8e69fe0a765mostang.com!davidm} 191