Ltest-nocalloc.c revision 65f936402d0dd0e62191ed249f86946203476e28
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* libunwind - a platform-independent unwind library 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Copyright (C) 2011 Google, Inc 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Contributed by Paul Pluzhnikov <ppluzhnikov@google.com> 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Permission is hereby granted, free of charge, to any person obtaining 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)a copy of this software and associated documentation files (the 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"Software"), to deal in the Software without restriction, including 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)without limitation the rights to use, copy, modify, merge, publish, 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)distribute, sublicense, and/or sell copies of the Software, and to 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)permit persons to whom the Software is furnished to do so, subject to 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)the following conditions: 1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)The above copyright notice and this permission notice shall be 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)included in all copies or substantial portions of the Software. 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define UNW_LOCAL_ONLY 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libunwind.h> 26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h> 2858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include <stdio.h> 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <dlfcn.h> 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <pthread.h> 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define panic(args...) \ 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { fprintf (stderr, args); exit (-1); } 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint num_mallocs; 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint num_callocs; 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint in_unwind; 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid * 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccicalloc(size_t n, size_t s) 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci{ 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void * (*func)(size_t, size_t); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifdef __GLIBC__ 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* In glibc, dlsym() calls calloc. Calling dlsym(RTLD_NEXT, "calloc") here 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) causes infinite recursion. Instead, we simply use it by its other 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name. */ 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extern void *__libc_calloc(size_t, size_t); 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci func = &__libc_calloc; 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#else 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(!func) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) func = dlsym(RTLD_NEXT, "calloc"); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (in_unwind) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_callocs++; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 59c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return func(n, s); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid * 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdochmalloc(size_t s) 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch{ 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void * (*func)(size_t); 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if(!func) 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) func = dlsym(RTLD_NEXT, "malloc"); 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (in_unwind) { 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) num_mallocs++; 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return NULL; 7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return func(s); 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic void 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)do_backtrace (void) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int num_levels = 100; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *pc[num_levels]; 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_unwind = 1; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unw_backtrace(pc, num_levels); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_unwind = 0; 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)foo3 (void) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) do_backtrace (); 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)foo2 (void) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) foo3 (); 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccifoo1 (void) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) foo2 (); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)main (void) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, num_errors; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Create (and leak) 100 TSDs, then call backtrace() 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) and check that it doesn't call malloc()/calloc(). */ 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < 100; ++i) { 117 pthread_key_t key; 118 if (pthread_key_create (&key, NULL)) 119 panic ("FAILURE: unable to create key %d\n", i); 120 } 121 /* Call backtrace right after thread creation, 122 * where we are sure that we're not inside malloc */ 123 do_backtrace(); 124 num_mallocs = num_callocs = 0; 125 foo1 (); 126 num_errors = num_mallocs + num_callocs; 127 if (num_errors > 0) 128 { 129 fprintf (stderr, 130 "FAILURE: detected %d error%s (malloc: %d, calloc: %d)\n", 131 num_errors, num_errors > 1 ? "s" : "", 132 num_mallocs, num_callocs); 133 exit (-1); 134 } 135 return 0; 136} 137