Gtest-exc.c revision f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4
1f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm/* libunwind - a platform-independent unwind library
2f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm   Copyright (C) 2001-2003 Hewlett-Packard Co
3f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
5f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmPermission is hereby granted, free of charge, to any person obtaining
6f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidma copy of this software and associated documentation files (the
7f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm"Software"), to deal in the Software without restriction, including
8f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmwithout limitation the rights to use, copy, modify, merge, publish,
9f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmdistribute, sublicense, and/or sell copies of the Software, and to
10f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmpermit persons to whom the Software is furnished to do so, subject to
11f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmthe following conditions:
12f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
13f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmThe above copyright notice and this permission notice shall be
14f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmincluded in all copies or substantial portions of the Software.
15f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
16f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
23f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
24f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm/* This illustrates the basics of using the unwind interface for
25f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm   exception handling.  */
26f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
27f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm#include <stdio.h>
28f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm#include <stdlib.h>
29f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm#include <unistd.h>
30f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
31f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm#include <libunwind.h>
32f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
33f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm#define panic(args...)				\
34f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm	{ ++nerrors; fprintf (stderr, args); }
35f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
36f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmint nerrors = 0;
37f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmint verbose = 0;
38f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
39f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmstatic void b (void *);
40f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
41f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmstatic void
42f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmraise_exception (void *addr)
43f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm{
44f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  unw_cursor_t cursor;
45f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  unw_word_t ip;
46f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  unw_context_t uc;
47f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
48f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  unw_getcontext (&uc);
49f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  if (unw_init_local (&cursor, &uc) < 0)
50f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm    {
51f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm      panic ("unw_init_local() failed!\n");
52f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm      return;
53f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm    }
54f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
55f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  /* unwind to frame b(): */
56f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  if (unw_step (&cursor) < 0)
57f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm    {
58f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm      panic ("unw_step() failed!\n");
59f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm      return;
60f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm    }
61f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
62f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  /* unwind to frame a(): */
63f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  if (unw_step (&cursor) < 0)
64f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm    {
65f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm      panic ("unw_step() failed!\n");
66f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm      return;
67f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm    }
68f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
69f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  unw_get_reg (&cursor, UNW_REG_IP, &ip);
70f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  if (verbose)
71f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm    printf ("old ip = %lx, new ip = %p\n", (long) ip, addr);
72f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
73f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  if (unw_set_reg (&cursor, UNW_REG_IP, (unw_word_t) addr) < 0)
74f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm    {
75f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm      panic ("unw_set_reg() failed!\n");
76f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm      return;
77f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm    }
78f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
79f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  unw_resume (&cursor);	/* transfer control to exception handler */
80f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm}
81f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
82f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm#if !UNW_TARGET_IA64
83f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
84f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmvoid *
85f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm__builtin_ia64_bsp (void)
86f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm{
87f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  return NULL;
88f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm}
89f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
90f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm#endif
91f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
92f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmstatic int
93f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidma (void)
94f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm{
95f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  long stack;
96f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
97f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  if (verbose)
98f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm    printf ("a: sp=%p bsp=%p\n", &stack, __builtin_ia64_bsp ());
99f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  b (&&handler);
100f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  panic ("FAILURE: unexpected return from func()!\n");
101f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
102f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm#if UNW_TARGET_IA64
103f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  asm volatile ("1:");	/* force a new bundle */
104f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm#endif
105f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm handler:
106f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  if (verbose)
107f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm    {
108f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm      printf ("exception handler: here we go (sp=%p, bsp=%p)...\n",
109f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm	      &stack, __builtin_ia64_bsp ());
110f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm      /* This call works around a bug in gcc (up-to pre3.4) which
111f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm	 causes invalid assembly code to be generated when
112f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm	 __builtin_ia64_bsp() gets predicated.  */
113f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm      getpid ();
114f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm    }
115f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  return 0;
116f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm}
117f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
118f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmstatic void
119f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmb (void *addr)
120f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm{
121f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  if (verbose)
122f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm    printf ("b() calling raise_exception()\n");
123f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  raise_exception (addr);
124f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  panic ("FAILURE: b() returned from raise_exception()!!\n");
125f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm}
126f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
127f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmint
128f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmmain (int argc, char **argv)
129f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm{
130f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  if (argc > 1)
131f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm    ++verbose;
132f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
133f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  if (a () != 0 || nerrors > 0)
134f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm    {
135f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm      fprintf (stderr, "FAILURE: test failed; try again?\n");
136f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm      exit (-1);
137f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm    }
138f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm
139f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  if (verbose)
140f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm    printf ("SUCCESS!\n");
141f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm  return 0;
142f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm}
143