Ltest-nocalloc.c revision 7263a97cedae620a233420b35e35173005bfef54
17263a97cedae620a233420b35e35173005bfef54Tommi Rantala/* libunwind - a platform-independent unwind library
27263a97cedae620a233420b35e35173005bfef54Tommi Rantala   Copyright (C) 2011 Google, Inc
37263a97cedae620a233420b35e35173005bfef54Tommi Rantala	Contributed by Paul Pluzhnikov <ppluzhnikov@google.com>
47263a97cedae620a233420b35e35173005bfef54Tommi Rantala
57263a97cedae620a233420b35e35173005bfef54Tommi RantalaPermission is hereby granted, free of charge, to any person obtaining
67263a97cedae620a233420b35e35173005bfef54Tommi Rantalaa copy of this software and associated documentation files (the
77263a97cedae620a233420b35e35173005bfef54Tommi Rantala"Software"), to deal in the Software without restriction, including
87263a97cedae620a233420b35e35173005bfef54Tommi Rantalawithout limitation the rights to use, copy, modify, merge, publish,
97263a97cedae620a233420b35e35173005bfef54Tommi Rantaladistribute, sublicense, and/or sell copies of the Software, and to
107263a97cedae620a233420b35e35173005bfef54Tommi Rantalapermit persons to whom the Software is furnished to do so, subject to
117263a97cedae620a233420b35e35173005bfef54Tommi Rantalathe following conditions:
127263a97cedae620a233420b35e35173005bfef54Tommi Rantala
137263a97cedae620a233420b35e35173005bfef54Tommi RantalaThe above copyright notice and this permission notice shall be
147263a97cedae620a233420b35e35173005bfef54Tommi Rantalaincluded in all copies or substantial portions of the Software.
157263a97cedae620a233420b35e35173005bfef54Tommi Rantala
167263a97cedae620a233420b35e35173005bfef54Tommi RantalaTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
177263a97cedae620a233420b35e35173005bfef54Tommi RantalaEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
187263a97cedae620a233420b35e35173005bfef54Tommi RantalaMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
197263a97cedae620a233420b35e35173005bfef54Tommi RantalaNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
207263a97cedae620a233420b35e35173005bfef54Tommi RantalaLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
217263a97cedae620a233420b35e35173005bfef54Tommi RantalaOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
227263a97cedae620a233420b35e35173005bfef54Tommi RantalaWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
237263a97cedae620a233420b35e35173005bfef54Tommi Rantala
24d86155f72e0a2db73a6cf4b873d400536ed06486Arun Sharma#define UNW_LOCAL_ONLY
25d86155f72e0a2db73a6cf4b873d400536ed06486Arun Sharma#include <libunwind.h>
267263a97cedae620a233420b35e35173005bfef54Tommi Rantala
277263a97cedae620a233420b35e35173005bfef54Tommi Rantala#include <unistd.h>
287263a97cedae620a233420b35e35173005bfef54Tommi Rantala#include <stdio.h>
297263a97cedae620a233420b35e35173005bfef54Tommi Rantala#include <stdlib.h>
307263a97cedae620a233420b35e35173005bfef54Tommi Rantala#include <dlfcn.h>
317263a97cedae620a233420b35e35173005bfef54Tommi Rantala#include <pthread.h>
327263a97cedae620a233420b35e35173005bfef54Tommi Rantala
337263a97cedae620a233420b35e35173005bfef54Tommi Rantala#define panic(args...)				\
347263a97cedae620a233420b35e35173005bfef54Tommi Rantala	{ fprintf (stderr, args); exit (-1); }
357263a97cedae620a233420b35e35173005bfef54Tommi Rantala
367263a97cedae620a233420b35e35173005bfef54Tommi Rantalaint verbose;
377263a97cedae620a233420b35e35173005bfef54Tommi Rantalaint num_mallocs;
387263a97cedae620a233420b35e35173005bfef54Tommi Rantalaint num_callocs;
397263a97cedae620a233420b35e35173005bfef54Tommi Rantalaint in_unwind;
407263a97cedae620a233420b35e35173005bfef54Tommi Rantala
417263a97cedae620a233420b35e35173005bfef54Tommi Rantalavoid *
427263a97cedae620a233420b35e35173005bfef54Tommi Rantalacalloc(size_t n, size_t s)
437263a97cedae620a233420b35e35173005bfef54Tommi Rantala{
447263a97cedae620a233420b35e35173005bfef54Tommi Rantala  static void * (*func)();
457263a97cedae620a233420b35e35173005bfef54Tommi Rantala
467263a97cedae620a233420b35e35173005bfef54Tommi Rantala#ifdef __GLIBC__
477263a97cedae620a233420b35e35173005bfef54Tommi Rantala  /* In glibc, dlsym() calls calloc. Calling dlsym(RTLD_NEXT, "calloc") here
487263a97cedae620a233420b35e35173005bfef54Tommi Rantala     causes infinite recursion.  Instead, we simply use it by its other
497263a97cedae620a233420b35e35173005bfef54Tommi Rantala     name.  */
507263a97cedae620a233420b35e35173005bfef54Tommi Rantala  extern void *__libc_calloc();
517263a97cedae620a233420b35e35173005bfef54Tommi Rantala  func = &__libc_calloc;
527263a97cedae620a233420b35e35173005bfef54Tommi Rantala#else
537263a97cedae620a233420b35e35173005bfef54Tommi Rantala  if(!func)
547263a97cedae620a233420b35e35173005bfef54Tommi Rantala    func = (void *(*)()) dlsym(RTLD_NEXT, "calloc");
55d86155f72e0a2db73a6cf4b873d400536ed06486Arun Sharma#endif
567263a97cedae620a233420b35e35173005bfef54Tommi Rantala
577263a97cedae620a233420b35e35173005bfef54Tommi Rantala  if (in_unwind) {
587263a97cedae620a233420b35e35173005bfef54Tommi Rantala    num_callocs++;
597263a97cedae620a233420b35e35173005bfef54Tommi Rantala    return NULL;
607263a97cedae620a233420b35e35173005bfef54Tommi Rantala  } else {
617263a97cedae620a233420b35e35173005bfef54Tommi Rantala    return func(n, s);
627263a97cedae620a233420b35e35173005bfef54Tommi Rantala  }
637263a97cedae620a233420b35e35173005bfef54Tommi Rantala}
647263a97cedae620a233420b35e35173005bfef54Tommi Rantala
657263a97cedae620a233420b35e35173005bfef54Tommi Rantalavoid *
667263a97cedae620a233420b35e35173005bfef54Tommi Rantalamalloc(size_t s)
677263a97cedae620a233420b35e35173005bfef54Tommi Rantala{
687263a97cedae620a233420b35e35173005bfef54Tommi Rantala  static void * (*func)();
697263a97cedae620a233420b35e35173005bfef54Tommi Rantala
707263a97cedae620a233420b35e35173005bfef54Tommi Rantala  if(!func)
717263a97cedae620a233420b35e35173005bfef54Tommi Rantala    func = (void *(*)()) dlsym(RTLD_NEXT, "malloc");
727263a97cedae620a233420b35e35173005bfef54Tommi Rantala
737263a97cedae620a233420b35e35173005bfef54Tommi Rantala  if (in_unwind) {
747263a97cedae620a233420b35e35173005bfef54Tommi Rantala    num_mallocs++;
757263a97cedae620a233420b35e35173005bfef54Tommi Rantala    return NULL;
767263a97cedae620a233420b35e35173005bfef54Tommi Rantala  } else {
777263a97cedae620a233420b35e35173005bfef54Tommi Rantala    return func(s);
787263a97cedae620a233420b35e35173005bfef54Tommi Rantala  }
797263a97cedae620a233420b35e35173005bfef54Tommi Rantala}
807263a97cedae620a233420b35e35173005bfef54Tommi Rantala
817263a97cedae620a233420b35e35173005bfef54Tommi Rantalastatic void
827263a97cedae620a233420b35e35173005bfef54Tommi Rantalado_backtrace (void)
837263a97cedae620a233420b35e35173005bfef54Tommi Rantala{
847263a97cedae620a233420b35e35173005bfef54Tommi Rantala  const int num_levels = 100;
857263a97cedae620a233420b35e35173005bfef54Tommi Rantala  void *pc[num_levels];
867263a97cedae620a233420b35e35173005bfef54Tommi Rantala
877263a97cedae620a233420b35e35173005bfef54Tommi Rantala  in_unwind = 1;
887263a97cedae620a233420b35e35173005bfef54Tommi Rantala  unw_backtrace(pc, num_levels);
897263a97cedae620a233420b35e35173005bfef54Tommi Rantala  in_unwind = 0;
907263a97cedae620a233420b35e35173005bfef54Tommi Rantala}
917263a97cedae620a233420b35e35173005bfef54Tommi Rantala
927263a97cedae620a233420b35e35173005bfef54Tommi Rantalavoid
937263a97cedae620a233420b35e35173005bfef54Tommi Rantalafoo3 ()
947263a97cedae620a233420b35e35173005bfef54Tommi Rantala{
957263a97cedae620a233420b35e35173005bfef54Tommi Rantala  do_backtrace ();
967263a97cedae620a233420b35e35173005bfef54Tommi Rantala}
977263a97cedae620a233420b35e35173005bfef54Tommi Rantala
987263a97cedae620a233420b35e35173005bfef54Tommi Rantalavoid
997263a97cedae620a233420b35e35173005bfef54Tommi Rantalafoo2 ()
1007263a97cedae620a233420b35e35173005bfef54Tommi Rantala{
1017263a97cedae620a233420b35e35173005bfef54Tommi Rantala  foo3 ();
1027263a97cedae620a233420b35e35173005bfef54Tommi Rantala}
1037263a97cedae620a233420b35e35173005bfef54Tommi Rantala
1047263a97cedae620a233420b35e35173005bfef54Tommi Rantalavoid
1057263a97cedae620a233420b35e35173005bfef54Tommi Rantalafoo1 (void)
1067263a97cedae620a233420b35e35173005bfef54Tommi Rantala{
1077263a97cedae620a233420b35e35173005bfef54Tommi Rantala  foo2 ();
1087263a97cedae620a233420b35e35173005bfef54Tommi Rantala}
1097263a97cedae620a233420b35e35173005bfef54Tommi Rantala
1107263a97cedae620a233420b35e35173005bfef54Tommi Rantalaint
1117263a97cedae620a233420b35e35173005bfef54Tommi Rantalamain (void)
1127263a97cedae620a233420b35e35173005bfef54Tommi Rantala{
1137263a97cedae620a233420b35e35173005bfef54Tommi Rantala  int i, num_errors;
1147263a97cedae620a233420b35e35173005bfef54Tommi Rantala
1157263a97cedae620a233420b35e35173005bfef54Tommi Rantala  /* Create (and leak) 100 TSDs, then call backtrace()
1167263a97cedae620a233420b35e35173005bfef54Tommi Rantala     and check that it doesn't call malloc()/calloc().  */
1177263a97cedae620a233420b35e35173005bfef54Tommi Rantala  for (i = 0; i < 100; ++i) {
1187263a97cedae620a233420b35e35173005bfef54Tommi Rantala    pthread_key_t key;
1197263a97cedae620a233420b35e35173005bfef54Tommi Rantala    if (pthread_key_create (&key, NULL))
1207263a97cedae620a233420b35e35173005bfef54Tommi Rantala      panic ("FAILURE: unable to create key %d\n", i);
1217263a97cedae620a233420b35e35173005bfef54Tommi Rantala  }
1227263a97cedae620a233420b35e35173005bfef54Tommi Rantala  /* Call backtrace right after thread creation,
1237263a97cedae620a233420b35e35173005bfef54Tommi Rantala   * where we are sure that we're not inside malloc */
1247263a97cedae620a233420b35e35173005bfef54Tommi Rantala  do_backtrace();
1257263a97cedae620a233420b35e35173005bfef54Tommi Rantala  num_mallocs = num_callocs = 0;
1267263a97cedae620a233420b35e35173005bfef54Tommi Rantala  foo1 ();
1277263a97cedae620a233420b35e35173005bfef54Tommi Rantala  num_errors = num_mallocs + num_callocs;
1287263a97cedae620a233420b35e35173005bfef54Tommi Rantala  if (num_errors > 0)
1297263a97cedae620a233420b35e35173005bfef54Tommi Rantala    {
1307263a97cedae620a233420b35e35173005bfef54Tommi Rantala      fprintf (stderr,
1317263a97cedae620a233420b35e35173005bfef54Tommi Rantala	       "FAILURE: detected %d error%s (malloc: %d, calloc: %d)\n",
1327263a97cedae620a233420b35e35173005bfef54Tommi Rantala	       num_errors, num_errors > 1 ? "s" : "",
1337263a97cedae620a233420b35e35173005bfef54Tommi Rantala	       num_mallocs, num_callocs);
1347263a97cedae620a233420b35e35173005bfef54Tommi Rantala      exit (-1);
1357263a97cedae620a233420b35e35173005bfef54Tommi Rantala    }
1367263a97cedae620a233420b35e35173005bfef54Tommi Rantala  return 0;
1377263a97cedae620a233420b35e35173005bfef54Tommi Rantala}
138