1186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm/* libunwind - a platform-independent unwind library
2186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm   Copyright (C) 2001-2004 Hewlett-Packard Co
3186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
5186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmPermission is hereby granted, free of charge, to any person obtaining
6186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidma copy of this software and associated documentation files (the
7186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm"Software"), to deal in the Software without restriction, including
8186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmwithout limitation the rights to use, copy, modify, merge, publish,
9186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmdistribute, sublicense, and/or sell copies of the Software, and to
10186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmpermit persons to whom the Software is furnished to do so, subject to
11186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmthe following conditions:
12186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
13186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmThe above copyright notice and this permission notice shall be
14186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmincluded in all copies or substantial portions of the Software.
15186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
16186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
23186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
24186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm#ifdef HAVE_CONFIG_H
25186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm# include "config.h"
26186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm#endif
27186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
280c838c4d4406ddfcc38c9cbaa088ab60570d4cc0Tommi Rantala#include "compiler.h"
290c838c4d4406ddfcc38c9cbaa088ab60570d4cc0Tommi Rantala
30186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm#include <errno.h>
31186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm#if HAVE_EXECINFO_H
32186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm# include <execinfo.h>
33186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm#else
34186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  extern int backtrace (void **, int);
35186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm#endif
36186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm#include <signal.h>
37186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm#include <stdio.h>
38186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm#include <stdlib.h>
39186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm#include <string.h>
40186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm#include <unistd.h>
41186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm#include <libunwind.h>
42186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
43186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm#define panic(args...)				\
44186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	{ fprintf (stderr, args); exit (-1); }
45186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
46e4593e2493923f93dfa6c92ee5327b4ce577a818Ken Werner#define SIG_STACK_SIZE 0x100000
47e4593e2493923f93dfa6c92ee5327b4ce577a818Ken Werner
48186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmint verbose;
49186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmint num_errors;
50186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
5124112f6d9b87554fe18b1ca0f939f30c76ac38faArun Sharma/* These variables are global because they
5224112f6d9b87554fe18b1ca0f939f30c76ac38faArun Sharma * cause the signal stack to overflow */
5324112f6d9b87554fe18b1ca0f939f30c76ac38faArun Sharmachar buf[512], name[256];
5424112f6d9b87554fe18b1ca0f939f30c76ac38faArun Sharmaunw_cursor_t cursor;
554bf1b7195223ea68c7ed6a24f4f826be02d8bec0Tommi Rantalaunw_context_t uc;
5624112f6d9b87554fe18b1ca0f939f30c76ac38faArun Sharma
57186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmstatic void
58186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmdo_backtrace (void)
59186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm{
60186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  unw_word_t ip, sp, off;
61186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  unw_proc_info_t pi;
62186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  int ret;
63186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
641ee6b0ac74da477a52ce589bed83db3908dcc4f7mostang.com!davidm  if (verbose)
651ee6b0ac74da477a52ce589bed83db3908dcc4f7mostang.com!davidm    printf ("\texplicit backtrace:\n");
661ee6b0ac74da477a52ce589bed83db3908dcc4f7mostang.com!davidm
67186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  unw_getcontext (&uc);
68186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  if (unw_init_local (&cursor, &uc) < 0)
69186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm    panic ("unw_init_local failed!\n");
70186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
71186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  do
72186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm    {
73186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm      unw_get_reg (&cursor, UNW_REG_IP, &ip);
74186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm      unw_get_reg (&cursor, UNW_REG_SP, &sp);
75186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm      buf[0] = '\0';
76186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm      if (unw_get_proc_name (&cursor, name, sizeof (name), &off) == 0)
77186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	{
78186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	  if (off)
79186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	    snprintf (buf, sizeof (buf), "<%s+0x%lx>", name, (long) off);
80186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	  else
81186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	    snprintf (buf, sizeof (buf), "<%s>", name);
82186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	}
83186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm      if (verbose)
84186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	{
85186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	  printf ("%016lx %-32s (sp=%016lx)\n", (long) ip, buf, (long) sp);
86186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
871c1dbbe2966b0dd8c2cf259b0ff61d0f99f6c2dfTommi Rantala	  if (unw_get_proc_info (&cursor, &pi) == 0)
881c1dbbe2966b0dd8c2cf259b0ff61d0f99f6c2dfTommi Rantala	    {
891c1dbbe2966b0dd8c2cf259b0ff61d0f99f6c2dfTommi Rantala	      printf ("\tproc=0x%lx-0x%lx\n\thandler=0x%lx lsda=0x%lx gp=0x%lx",
90186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm		  (long) pi.start_ip, (long) pi.end_ip,
91186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm		  (long) pi.handler, (long) pi.lsda, (long) pi.gp);
921c1dbbe2966b0dd8c2cf259b0ff61d0f99f6c2dfTommi Rantala	    }
93186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
94186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm#if UNW_TARGET_IA64
95186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	  {
96186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	    unw_word_t bsp;
97186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
98186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	    unw_get_reg (&cursor, UNW_IA64_BSP, &bsp);
99186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	    printf (" bsp=%lx", bsp);
100186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	  }
101186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm#endif
102186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	  printf ("\n");
103186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	}
104186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
105186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm      ret = unw_step (&cursor);
106186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm      if (ret < 0)
107186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	{
108186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	  unw_get_reg (&cursor, UNW_REG_IP, &ip);
109186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	  printf ("FAILURE: unw_step() returned %d for ip=%lx\n",
110186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm		  ret, (long) ip);
111186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	  ++num_errors;
112186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	}
113186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm    }
114186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  while (ret > 0);
1151ee6b0ac74da477a52ce589bed83db3908dcc4f7mostang.com!davidm
1161ee6b0ac74da477a52ce589bed83db3908dcc4f7mostang.com!davidm  {
1171ee6b0ac74da477a52ce589bed83db3908dcc4f7mostang.com!davidm    void *buffer[20];
1181ee6b0ac74da477a52ce589bed83db3908dcc4f7mostang.com!davidm    int i, n;
1191ee6b0ac74da477a52ce589bed83db3908dcc4f7mostang.com!davidm
1201ee6b0ac74da477a52ce589bed83db3908dcc4f7mostang.com!davidm    if (verbose)
1211ee6b0ac74da477a52ce589bed83db3908dcc4f7mostang.com!davidm      printf ("\n\tvia backtrace():\n");
1221ee6b0ac74da477a52ce589bed83db3908dcc4f7mostang.com!davidm    n = backtrace (buffer, 20);
1231ee6b0ac74da477a52ce589bed83db3908dcc4f7mostang.com!davidm    if (verbose)
1241ee6b0ac74da477a52ce589bed83db3908dcc4f7mostang.com!davidm      for (i = 0; i < n; ++i)
1251ee6b0ac74da477a52ce589bed83db3908dcc4f7mostang.com!davidm	printf ("[%d] ip=%p\n", i, buffer[i]);
1261ee6b0ac74da477a52ce589bed83db3908dcc4f7mostang.com!davidm  }
127186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm}
128186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
129186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmvoid
1306b55e0ab51eee7dbea679fda2b37ecf61f0025e5Tommi Rantalafoo (long val UNUSED)
131186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm{
132186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  do_backtrace ();
133186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm}
134186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
135186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmvoid
136186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmbar (long v)
137186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm{
138186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  extern long f (long);
139186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  int arr[v];
140186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
141186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  /* This is a vain attempt to use up lots of registers to force
142186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm     the frame-chain info to be saved on the memory stack on ia64.
143186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm     It happens to work with gcc v3.3.4 and gcc v3.4.1 but perhaps
144186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm     not with any other compiler.  */
145186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  foo (f (arr[0]) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v)
146186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm       + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v)
147186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm       + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v)
148186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm       + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v)
149186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm       + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v)
150186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm       + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v)
151186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm       + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v)
152186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm       + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v)
153186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm       + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v)
154186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm       + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v)
155186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm       + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v)
156186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm       + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v)
157186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm       + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v)
158186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm       + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v)
159186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm       + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v)
160186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm       + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v)
161186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm       + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + f (v))
162186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm       ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
163186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm       )))))))))))))))))))))))))))))))))))))))))))))))))))))));
164186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm}
165186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
166186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmvoid
1676b55e0ab51eee7dbea679fda2b37ecf61f0025e5Tommi Rantalasighandler (int signal, void *siginfo UNUSED, void *context)
168186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm{
1690c838c4d4406ddfcc38c9cbaa088ab60570d4cc0Tommi Rantala  ucontext_t *uc UNUSED;
170186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  int sp;
171186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
1720c838c4d4406ddfcc38c9cbaa088ab60570d4cc0Tommi Rantala  uc = context;
1730c838c4d4406ddfcc38c9cbaa088ab60570d4cc0Tommi Rantala
174186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  if (verbose)
175186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm    {
176186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm      printf ("sighandler: got signal %d, sp=%p", signal, &sp);
177186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm#if UNW_TARGET_IA64
178186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm# if defined(__linux__)
179186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm      printf (" @ %lx", uc->uc_mcontext.sc_ip);
180186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm# else
181186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm      {
182186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	uint16_t reason;
183186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	uint64_t ip;
184186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
185186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	__uc_get_reason (uc, &reason);
186186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	__uc_get_ip (uc, &ip);
187186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm	printf (" @ %lx (reason=%d)", ip, reason);
188186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm      }
189186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm# endif
190186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm#elif UNW_TARGET_X86
1913b026a7ed8e4c03e7d0177ac198b2649427f80d1Konstantin Belousov#if defined __linux__
192186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm      printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_EIP]);
1933b026a7ed8e4c03e7d0177ac198b2649427f80d1Konstantin Belousov#elif defined __FreeBSD__
1943b026a7ed8e4c03e7d0177ac198b2649427f80d1Konstantin Belousov      printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_eip);
195186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm#endif
19624112f6d9b87554fe18b1ca0f939f30c76ac38faArun Sharma#elif UNW_TARGET_X86_64
1979bb9c972e6f0a776740ad17ee230973bdefad553Konstantin Belousov#if defined __linux__
19824112f6d9b87554fe18b1ca0f939f30c76ac38faArun Sharma      printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_RIP]);
1999bb9c972e6f0a776740ad17ee230973bdefad553Konstantin Belousov#elif defined __FreeBSD__
2009bb9c972e6f0a776740ad17ee230973bdefad553Konstantin Belousov      printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_rip);
2019bb9c972e6f0a776740ad17ee230973bdefad553Konstantin Belousov#endif
202d7377096400e73db989ebb6b0985a84754a413caKonstantin Belousov#endif
203186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm      printf ("\n");
204186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm    }
205186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  do_backtrace();
206186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm}
207186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
208186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidmint
2096b55e0ab51eee7dbea679fda2b37ecf61f0025e5Tommi Rantalamain (int argc, char **argv UNUSED)
210186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm{
211186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  struct sigaction act;
212186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  stack_t stk;
213186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
214186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  verbose = (argc > 1);
215186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
216186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  if (verbose)
217186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm    printf ("Normal backtrace:\n");
218186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
219186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  bar (1);
220186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
221186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  memset (&act, 0, sizeof (act));
222186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  act.sa_handler = (void (*)(int)) sighandler;
223186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  act.sa_flags = SA_SIGINFO;
224186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  if (sigaction (SIGTERM, &act, NULL) < 0)
225186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm    panic ("sigaction: %s\n", strerror (errno));
226186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
227186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  if (verbose)
228186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm    printf ("\nBacktrace across signal handler:\n");
229186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  kill (getpid (), SIGTERM);
230186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
231186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  if (verbose)
232186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm    printf ("\nBacktrace across signal handler on alternate stack:\n");
233e4593e2493923f93dfa6c92ee5327b4ce577a818Ken Werner  stk.ss_sp = malloc (SIG_STACK_SIZE);
234186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  if (!stk.ss_sp)
235e4593e2493923f93dfa6c92ee5327b4ce577a818Ken Werner    panic ("failed to allocate %u bytes\n", SIG_STACK_SIZE);
236e4593e2493923f93dfa6c92ee5327b4ce577a818Ken Werner  stk.ss_size = SIG_STACK_SIZE;
237186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  stk.ss_flags = 0;
238186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  if (sigaltstack (&stk, NULL) < 0)
239186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm    panic ("sigaltstack: %s\n", strerror (errno));
240186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
241186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  memset (&act, 0, sizeof (act));
242186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  act.sa_handler = (void (*)(int)) sighandler;
243186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  act.sa_flags = SA_ONSTACK | SA_SIGINFO;
244186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  if (sigaction (SIGTERM, &act, NULL) < 0)
245186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm    panic ("sigaction: %s\n", strerror (errno));
246186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  kill (getpid (), SIGTERM);
247186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm
248186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  if (num_errors > 0)
249186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm    {
250186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm      fprintf (stderr, "FAILURE: detected %d errors\n", num_errors);
251186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm      exit (-1);
252186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm    }
253186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  if (verbose)
254186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm    printf ("SUCCESS.\n");
2550d7738ed4f7dae1b6b77d1a4dd25c5ea765de81fTommi Rantala
2560d7738ed4f7dae1b6b77d1a4dd25c5ea765de81fTommi Rantala  signal (SIGTERM, SIG_DFL);
2570d7738ed4f7dae1b6b77d1a4dd25c5ea765de81fTommi Rantala  stk.ss_flags = SS_DISABLE;
2580d7738ed4f7dae1b6b77d1a4dd25c5ea765de81fTommi Rantala  sigaltstack (&stk, NULL);
2590d7738ed4f7dae1b6b77d1a4dd25c5ea765de81fTommi Rantala  free (stk.ss_sp);
2600d7738ed4f7dae1b6b77d1a4dd25c5ea765de81fTommi Rantala
261186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm  return 0;
262186cbb2957d4ffc4269fe788bf8650ee3b629d27hp.com!davidm}
263