Gtest-exc.c revision f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4
1830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant/* libunwind - a platform-independent unwind library
2830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant   Copyright (C) 2001-2003 Hewlett-Packard Co
3830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
5830713c63ecaf0a5d7690db92f83f2741754de15Howard HinnantPermission is hereby granted, free of charge, to any person obtaining
6830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnanta copy of this software and associated documentation files (the
7830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant"Software"), to deal in the Software without restriction, including
8830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantwithout limitation the rights to use, copy, modify, merge, publish,
9830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantdistribute, sublicense, and/or sell copies of the Software, and to
10830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantpermit persons to whom the Software is furnished to do so, subject to
11830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantthe following conditions:
12830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
13830713c63ecaf0a5d7690db92f83f2741754de15Howard HinnantThe above copyright notice and this permission notice shall be
14830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantincluded in all copies or substantial portions of the Software.
15830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
16830713c63ecaf0a5d7690db92f83f2741754de15Howard HinnantTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17830713c63ecaf0a5d7690db92f83f2741754de15Howard HinnantEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18830713c63ecaf0a5d7690db92f83f2741754de15Howard HinnantMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19830713c63ecaf0a5d7690db92f83f2741754de15Howard HinnantNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20830713c63ecaf0a5d7690db92f83f2741754de15Howard HinnantLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21830713c63ecaf0a5d7690db92f83f2741754de15Howard HinnantOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22830713c63ecaf0a5d7690db92f83f2741754de15Howard HinnantWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
23830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
24830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant/* This illustrates the basics of using the unwind interface for
25830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant   exception handling.  */
26830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
27830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant#include <stdio.h>
28830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant#include <stdlib.h>
29830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant#include <unistd.h>
30830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
31830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant#include <libunwind.h>
32830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
33830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant#define panic(args...)				\
34830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant	{ ++nerrors; fprintf (stderr, args); }
35830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
36830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantint nerrors = 0;
37830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantint verbose = 0;
38830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
39830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantstatic void b (void *);
40830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
41830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantstatic void
42830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantraise_exception (void *addr)
43830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{
44830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant  unw_cursor_t cursor;
45830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant  unw_word_t ip;
46830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant  unw_context_t uc;
47830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
48830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant  unw_getcontext (&uc);
49830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant  if (unw_init_local (&cursor, &uc) < 0)
50830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    {
51830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant      panic ("unw_init_local() failed!\n");
52830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant      return;
53830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    }
54830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
55830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant  /* unwind to frame b(): */
56830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant  if (unw_step (&cursor) < 0)
57830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    {
58830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant      panic ("unw_step() failed!\n");
59      return;
60    }
61
62  /* unwind to frame a(): */
63  if (unw_step (&cursor) < 0)
64    {
65      panic ("unw_step() failed!\n");
66      return;
67    }
68
69  unw_get_reg (&cursor, UNW_REG_IP, &ip);
70  if (verbose)
71    printf ("old ip = %lx, new ip = %p\n", (long) ip, addr);
72
73  if (unw_set_reg (&cursor, UNW_REG_IP, (unw_word_t) addr) < 0)
74    {
75      panic ("unw_set_reg() failed!\n");
76      return;
77    }
78
79  unw_resume (&cursor);	/* transfer control to exception handler */
80}
81
82#if !UNW_TARGET_IA64
83
84void *
85__builtin_ia64_bsp (void)
86{
87  return NULL;
88}
89
90#endif
91
92static int
93a (void)
94{
95  long stack;
96
97  if (verbose)
98    printf ("a: sp=%p bsp=%p\n", &stack, __builtin_ia64_bsp ());
99  b (&&handler);
100  panic ("FAILURE: unexpected return from func()!\n");
101
102#if UNW_TARGET_IA64
103  asm volatile ("1:");	/* force a new bundle */
104#endif
105 handler:
106  if (verbose)
107    {
108      printf ("exception handler: here we go (sp=%p, bsp=%p)...\n",
109	      &stack, __builtin_ia64_bsp ());
110      /* This call works around a bug in gcc (up-to pre3.4) which
111	 causes invalid assembly code to be generated when
112	 __builtin_ia64_bsp() gets predicated.  */
113      getpid ();
114    }
115  return 0;
116}
117
118static void
119b (void *addr)
120{
121  if (verbose)
122    printf ("b() calling raise_exception()\n");
123  raise_exception (addr);
124  panic ("FAILURE: b() returned from raise_exception()!!\n");
125}
126
127int
128main (int argc, char **argv)
129{
130  if (argc > 1)
131    ++verbose;
132
133  if (a () != 0 || nerrors > 0)
134    {
135      fprintf (stderr, "FAILURE: test failed; try again?\n");
136      exit (-1);
137    }
138
139  if (verbose)
140    printf ("SUCCESS!\n");
141  return 0;
142}
143