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