1576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma/* libunwind - a platform-independent unwind library 2576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma Copyright (C) 2009 Google, Inc 3576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma Contributed by Arun Sharma <arun.sharma@google.com> 4576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma 5576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun SharmaPermission is hereby granted, free of charge, to any person obtaining 6576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmaa copy of this software and associated documentation files (the 7576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma"Software"), to deal in the Software without restriction, including 8576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmawithout limitation the rights to use, copy, modify, merge, publish, 9576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmadistribute, sublicense, and/or sell copies of the Software, and to 10576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmapermit persons to whom the Software is furnished to do so, subject to 11576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmathe following conditions: 12576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma 13576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun SharmaThe above copyright notice and this permission notice shall be 14576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmaincluded in all copies or substantial portions of the Software. 15576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma 16576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun SharmaTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun SharmaEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun SharmaMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun SharmaNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun SharmaLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun SharmaOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun SharmaWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma 24576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <unistd.h> 25576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <stdio.h> 26576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <stdlib.h> 27576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <dlfcn.h> 28576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <libunwind.h> 29576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma 30576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#define panic(args...) \ 31576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma { fprintf (stderr, args); exit (-1); } 32576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma 33576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmaint verbose; 34576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmaint num_errors; 35576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmaint in_unwind; 36576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma 37576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmavoid * 38576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmamalloc(size_t s) 39576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma{ 40576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma static void * (*func)(); 41576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma 42576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma if(!func) 43576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma func = (void *(*)()) dlsym(RTLD_NEXT, "malloc"); 44576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma 45576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma if (in_unwind) { 46576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma num_errors++; 47576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma return NULL; 48576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma } else { 49576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma return func(s); 50576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma } 51576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma} 52576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma 53576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmastatic void 54576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmado_backtrace (void) 55576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma{ 56576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma unw_word_t ip, sp; 57576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma unw_cursor_t cursor; 58576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma unw_context_t uc; 59576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma int ret; 60576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma 61576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma in_unwind = 1; 62576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma unw_getcontext (&uc); 63576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma if (unw_init_local (&cursor, &uc) < 0) 64576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma panic ("unw_init_local failed!\n"); 65576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma 66576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma do 67576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma { 68576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma unw_get_reg (&cursor, UNW_REG_IP, &ip); 69576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma unw_get_reg (&cursor, UNW_REG_SP, &sp); 70576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma 71576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma ret = unw_step (&cursor); 72576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma if (ret < 0) 73576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma { 74576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma ++num_errors; 75576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma } 76576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma } 77576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma while (ret > 0); 78576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma in_unwind = 0; 79576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma} 80576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma 81576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmavoid 82e9f161a677087dfdf8e543b9e70c7131ac3fd942Tommi Rantalafoo3 (void) 83576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma{ 84576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma do_backtrace (); 85576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma} 86576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma 87576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmavoid 88e9f161a677087dfdf8e543b9e70c7131ac3fd942Tommi Rantalafoo2 (void) 89576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma{ 90576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma foo3 (); 91576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma} 92576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma 93576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmavoid 94e9f161a677087dfdf8e543b9e70c7131ac3fd942Tommi Rantalafoo1 (void) 95576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma{ 96576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma foo2 (); 97576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma} 98576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma 99576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmaint 10047a99b6f0007c69959d7d56e52243c1780102d80Tommi Rantalamain (void) 101576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma{ 102576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma foo1(); 103576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma 104576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma if (num_errors > 0) 105576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma { 106576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma fprintf (stderr, "FAILURE: detected %d errors\n", num_errors); 107576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma exit (-1); 108576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma } 109576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma return 0; 110576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma} 111