Changeset 4585
- Timestamp:
- 11/05/08 14:58:19 (2 months ago)
- Files:
-
- trunk/src/charon/daemon.c (modified) (5 diffs)
- trunk/src/libstrongswan/Makefile.am (modified) (1 diff)
- trunk/src/libstrongswan/utils/backtrace.c (added)
- trunk/src/libstrongswan/utils/backtrace.h (added)
- trunk/src/libstrongswan/utils/leak_detective.c (modified) (19 diffs)
- trunk/src/libstrongswan/utils/leak_detective.h (modified) (1 diff)
- trunk/src/libstrongswan/utils/mutex.c (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/charon/daemon.c
r4553 r4585 17 17 */ 18 18 19 #ifdef HAVE_DLADDR20 # define _GNU_SOURCE21 # include <dlfcn.h>22 #endif /* HAVE_DLADDR */23 24 19 #include <stdio.h> 25 20 #include <sys/prctl.h> … … 35 30 #include <pwd.h> 36 31 #include <grp.h> 37 #ifdef HAVE_BACKTRACE38 # include <execinfo.h>39 #endif /* HAVE_BACKTRACE */40 32 #ifdef CAPABILITIES 41 33 #include <sys/capability.h> … … 45 37 46 38 #include <library.h> 39 #include <utils/backtrace.h> 47 40 #include <config/traffic_selector.h> 48 41 #include <config/proposal.h> … … 434 427 static void segv_handler(int signal) 435 428 { 436 #ifdef HAVE_BACKTRACE 437 void *array[20]; 438 size_t size; 439 char **strings; 440 size_t i; 441 442 size = backtrace(array, 20); 443 strings = backtrace_symbols(array, size); 444 445 DBG1(DBG_JOB, "thread %u received %s. Dumping %d frames from stack:", 446 pthread_self(), signal == SIGSEGV ? "SIGSEGV" : "SIGILL", size); 447 448 for (i = 0; i < size; i++) 449 { 450 #ifdef HAVE_DLADDR 451 Dl_info info; 452 453 if (dladdr(array[i], &info)) 454 { 455 void *ptr = array[i]; 456 if (strstr(info.dli_fname, ".so")) 457 { 458 ptr = (void*)(array[i] - info.dli_fbase); 459 } 460 DBG1(DBG_DMN, " %s [%p]", info.dli_fname, ptr); 461 } 462 else 463 { 464 #endif /* HAVE_DLADDR */ 465 DBG1(DBG_DMN, " %s", strings[i]); 466 #ifdef HAVE_DLADDR 467 } 468 #endif /* HAVE_DLADDR */ 469 } 470 free (strings); 471 #else /* !HAVE_BACKTRACE */ 472 DBG1(DBG_DMN, "thread %u received %s", 473 pthread_self(), signal == SIGSEGV ? "SIGSEGV" : "SIGILL"); 474 #endif /* HAVE_BACKTRACE */ 429 backtrace_t *backtrace; 430 431 DBG1(DBG_DMN, "thread %u received %d", pthread_self(), signal); 432 backtrace = backtrace_create(2); 433 backtrace->log(backtrace, stderr); 434 backtrace->destroy(backtrace); 435 475 436 DBG1(DBG_DMN, "killing ourself, received critical signal"); 476 437 raise(SIGKILL); … … 535 496 sigaction(SIGSEGV, &action, NULL); 536 497 sigaction(SIGILL, &action, NULL); 498 sigaction(SIGBUS, &action, NULL); 537 499 action.sa_handler = SIG_IGN; 538 500 sigaction(SIGPIPE, &action, NULL); trunk/src/libstrongswan/Makefile.am
r4455 r4585 51 51 utils/optionsfrom.c utils/optionsfrom.h \ 52 52 utils/mutex.c utils/mutex.h \ 53 utils/backtrace.c utils/backtrace.h \ 53 54 plugins/plugin_loader.c plugins/plugin_loader.h plugins/plugin.h 54 55 trunk/src/libstrongswan/utils/leak_detective.c
r4311 r4585 15 15 * $Id$ 16 16 */ 17 18 #ifdef HAVE_DLADDR19 # define _GNU_SOURCE20 # include <dlfcn.h>21 #endif /* HAVE_DLADDR */22 17 23 18 #include <stddef.h> … … 29 24 #include <netinet/in.h> 30 25 #include <arpa/inet.h> 31 #include <dlfcn.h>32 26 #include <unistd.h> 33 27 #include <syslog.h> … … 36 30 #include <printf.h> 37 31 #include <locale.h> 38 #ifdef HAVE_BACKTRACE39 # include <execinfo.h>40 #endif /* HAVE_BACKTRACE */41 32 42 33 #include "leak_detective.h" … … 44 35 #include <library.h> 45 36 #include <debug.h> 37 #include <utils/backtrace.h> 46 38 47 39 typedef struct private_leak_detective_t private_leak_detective_t; … … 107 99 108 100 /** 109 * Stack frames at the time of allocation110 */111 void *stack_frames[STACK_FRAMES_COUNT];112 113 /**114 * Number of stacks frames obtained in stack_frames115 */116 int stack_frame_count;117 118 /**119 101 * Pointer to previous entry in linked list 120 102 */ … … 125 107 */ 126 108 memory_header_t *next; 109 110 /** 111 * backtrace taken during (re-)allocation 112 */ 113 backtrace_t *backtrace; 127 114 128 115 /** … … 152 139 magic: MEMORY_HEADER_MAGIC, 153 140 bytes: 0, 154 stack_frame_count: 0,141 backtrace: NULL, 155 142 previous: NULL, 156 143 next: NULL … … 161 148 */ 162 149 static bool installed = FALSE; 163 164 /**165 * log stack frames queried by backtrace()166 * TODO: Dump symbols of static functions. This could be done with167 * the addr2line utility or the GNU BFD Library...168 */169 static void log_stack_frames(void **stack_frames, int stack_frame_count)170 {171 #ifdef HAVE_BACKTRACE172 size_t i;173 char **strings;174 175 strings = backtrace_symbols(stack_frames, stack_frame_count);176 177 fprintf(stderr, " dumping %d stack frame addresses:\n", stack_frame_count);178 for (i = 0; i < stack_frame_count; i++)179 {180 #ifdef HAVE_DLADDR181 Dl_info info;182 183 if (dladdr(stack_frames[i], &info))184 {185 char cmd[1024];186 FILE *output;187 char c;188 void *ptr = stack_frames[i];189 190 if (strstr(info.dli_fname, ".so"))191 {192 ptr = (void*)(stack_frames[i] - info.dli_fbase);193 }194 snprintf(cmd, sizeof(cmd), "addr2line -e %s %p", info.dli_fname, ptr);195 if (info.dli_sname)196 {197 fprintf(stderr, " \e[33m%s\e[0m @ %p (\e[31m%s\e[0m+0x%x) [%p]\n",198 info.dli_fname, info.dli_fbase, info.dli_sname,199 stack_frames[i] - info.dli_saddr, stack_frames[i]);200 }201 else202 {203 fprintf(stderr, " \e[33m%s\e[0m @ %p [%p]\n", info.dli_fname,204 info.dli_fbase, stack_frames[i]);205 }206 fprintf(stderr, " -> \e[32m");207 output = popen(cmd, "r");208 if (output)209 {210 while (TRUE)211 {212 c = getc(output);213 if (c == '\n' || c == EOF)214 {215 break;216 }217 fputc(c, stderr);218 }219 }220 else221 {222 #endif /* HAVE_DLADDR */223 fprintf(stderr, " %s\n", strings[i]);224 #ifdef HAVE_DLADDR225 }226 fprintf(stderr, "\n\e[0m");227 }228 #endif /* HAVE_DLADDR */229 }230 free (strings);231 #endif /* HAVE_BACKTRACE */232 }233 150 234 151 /** … … 239 156 */ 240 157 char *whitelist[] = { 158 /* backtraces, including own */ 159 "backtrace_create", 241 160 /* pthread stuff */ 242 161 "pthread_create", … … 285 204 * check if a stack frame contains functions listed above 286 205 */ 287 static bool is_whitelisted(void **stack_frames, int stack_frame_count) 288 { 289 int i, j; 290 291 #ifdef HAVE_DLADDR 292 for (i=0; i< stack_frame_count; i++) 293 { 294 Dl_info info; 295 296 if (dladdr(stack_frames[i], &info) && info.dli_sname) 297 { 298 for (j = 0; j < sizeof(whitelist)/sizeof(char*); j++) 299 { 300 if (streq(info.dli_sname, whitelist[j])) 301 { 302 return TRUE; 303 } 304 } 206 static bool is_whitelisted(backtrace_t *backtrace) 207 { 208 int i; 209 for (i = 0; i < sizeof(whitelist)/sizeof(char*); i++) 210 { 211 if (backtrace->contains_function(backtrace, whitelist[i])) 212 { 213 return TRUE; 305 214 } 306 215 } 307 #endif /* HAVE_DLADDR */308 216 return FALSE; 309 217 } … … 319 227 for (hdr = first_header.next; hdr != NULL; hdr = hdr->next) 320 228 { 321 if (is_whitelisted(hdr-> stack_frames, hdr->stack_frame_count))229 if (is_whitelisted(hdr->backtrace)) 322 230 { 323 231 whitelisted++; … … 327 235 fprintf(stderr, "Leak (%d bytes at %p):\n", hdr->bytes, hdr + 1); 328 236 /* skip the first frame, contains leak detective logic */ 329 log_stack_frames(hdr->stack_frames + 1, hdr->stack_frame_count - 1);237 hdr->backtrace->log(hdr->backtrace, stderr); 330 238 leaks++; 331 239 } … … 404 312 hdr->magic = MEMORY_HEADER_MAGIC; 405 313 hdr->bytes = bytes; 406 hdr-> stack_frame_count = backtrace(hdr->stack_frames, STACK_FRAMES_COUNT);314 hdr->backtrace = backtrace_create(3); 407 315 tail->magic = MEMORY_TAIL_MAGIC; 408 316 install_hooks(); … … 427 335 void free_hook(void *ptr, const void *caller) 428 336 { 429 void *stack_frames[STACK_FRAMES_COUNT];430 int stack_frame_count;431 337 memory_header_t *hdr; 432 338 memory_tail_t *tail; 339 backtrace_t *backtrace; 433 340 pthread_t thread_id = pthread_self(); 434 341 int oldpolicy; … … 456 363 "header magic 0x%x, tail magic 0x%x:\n", 457 364 ptr, hdr->magic, tail->magic); 458 stack_frame_count = backtrace(stack_frames, STACK_FRAMES_COUNT); 459 log_stack_frames(stack_frames, stack_frame_count); 365 backtrace = backtrace_create(3); 366 backtrace->log(backtrace, stderr); 367 backtrace->destroy(backtrace); 460 368 } 461 369 else … … 467 375 } 468 376 hdr->previous->next = hdr->next; 469 377 hdr->backtrace->destroy(hdr->backtrace); 378 470 379 /* clear MAGIC, set mem to something remarkable */ 471 380 memset(hdr, MEMORY_FREE_PATTERN, hdr->bytes + sizeof(memory_header_t)); 472 381 473 382 free(hdr); 474 383 } … … 484 393 { 485 394 memory_header_t *hdr; 486 void *stack_frames[STACK_FRAMES_COUNT];487 int stack_frame_count;488 395 memory_tail_t *tail; 396 backtrace_t *backtrace; 489 397 pthread_t thread_id = pthread_self(); 490 398 int oldpolicy; … … 513 421 "header magic 0x%x, tail magic 0x%x:\n", 514 422 old, hdr->magic, tail->magic); 515 stack_frame_count = backtrace(stack_frames, STACK_FRAMES_COUNT); 516 log_stack_frames(stack_frames, stack_frame_count); 423 backtrace = backtrace_create(3); 424 backtrace->log(backtrace, stderr); 425 backtrace->destroy(backtrace); 517 426 } 518 427 /* clear tail magic, allocate, set tail magic */ … … 524 433 /* update statistics */ 525 434 hdr->bytes = bytes; 526 hdr->stack_frame_count = backtrace(hdr->stack_frames, STACK_FRAMES_COUNT); 435 hdr->backtrace->destroy(hdr->backtrace); 436 hdr->backtrace = backtrace_create(3); 527 437 528 438 /* update header of linked list neighbours */ trunk/src/libstrongswan/utils/leak_detective.h
r3589 r4585 21 21 #ifndef LEAK_DETECTIVE_H_ 22 22 #define LEAK_DETECTIVE_H_ 23 24 /**25 * Maximum depth stack frames to register26 */27 #define STACK_FRAMES_COUNT 2028 23 29 24 typedef struct leak_detective_t leak_detective_t; trunk/src/libstrongswan/utils/mutex.c
r4575 r4585 20 20 #include <library.h> 21 21 #include <debug.h> 22 #include <utils/backtrace.h> 22 23 23 24 #include <pthread.h> … … 54 55 55 56 /** 56 * creator of the mutex 57 */ 58 void *stack[10]; 59 60 /** 61 * number of pointers in stack 62 */ 63 int stack_size; 57 * backtrace where mutex has been created 58 */ 59 backtrace_t *backtrace; 64 60 #endif /* LOCK_PROFILER */ 65 61 … … 112 108 113 109 /** 114 * print mutex locking statistics 115 */ 116 static void print_stats(private_mutex_t *this) 117 { 118 int i; 119 120 DBG1("waited %d.%06ds in mutex, created at:", 121 this->waited.tv_sec, this->waited.tv_usec); 122 for (i = 0; i < this->stack_size; i++) 123 { 124 DBG1(" %p", this->stack[i]); 125 } 126 } 127 128 static void init_stats(private_mutex_t *this) 129 { 130 this->stack_size = backtrace(this->stack, countof(this->stack)); 110 * Print and cleanup mutex profiler 111 */ 112 static void profiler_cleanup(private_mutex_t *this) 113 { 114 fprintf(stderr, "waited %d.%06ds in mutex, created at:", 115 this->waited.tv_sec, this->waited.tv_usec); 116 this->backtrace->log(this->backtrace, stderr); 117 this->backtrace->destroy(this->backtrace); 118 } 119 120 /** 121 * Initialize mutex profiler 122 */ 123 static void profiler_init(private_mutex_t *this) 124 { 125 this->backtrace = backtrace_create(3); 131 126 timerclear(&this->waited); 132 127 } … … 152 147 153 148 /** dummy implementations */ 154 static void pr int_stats(private_mutex_t *this) {}155 static void init_stats(private_mutex_t *this) {}149 static void profiler_cleanup(private_mutex_t *this) {} 150 static void profiler_init(private_mutex_t *this) {} 156 151 157 152 /** … … 225 220 static void mutex_destroy(private_mutex_t *this) 226 221 { 227 pr int_stats(this);222 profiler_cleanup(this); 228 223 pthread_mutex_destroy(&this->mutex); 229 224 free(this); … … 235 230 static void mutex_destroy_r(private_r_mutex_t *this) 236 231 { 237 pr int_stats(&this->generic);232 profiler_cleanup(&this->generic); 238 233 pthread_mutex_destroy(&this->generic.mutex); 239 234 pthread_key_delete(this->times); … … 259 254 pthread_key_create(&this->times, NULL); 260 255 this->generic.recursive = TRUE; 261 init_stats(&this->generic);256 profiler_init(&this->generic); 262 257 this->thread = 0; 263 258 … … 275 270 pthread_mutex_init(&this->mutex, NULL); 276 271 this->recursive = FALSE; 277 init_stats(this);272 profiler_init(this); 278 273 279 274 return &this->public;
