From 67b0b0e40468831db04073595b86f38de5601bf1 Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Fri, 10 May 2002 21:03:56 +0000 Subject: [PATCH] Modify the startup mechanism so that any call into valgrind's libpthread.so will start up valgrind if it is not already running. This more or less sidesteps the problem that sometimes valgrind.so isn't init'd first by the dynamic linker. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@257 --- coregrind/arch/x86-linux/vg_libpthread.c | 43 ++++++++++-------------- coregrind/vg_libpthread.c | 43 ++++++++++-------------- coregrind/vg_startup.S | 14 +++++++- vg_libpthread.c | 43 ++++++++++-------------- vg_startup.S | 14 +++++++- 5 files changed, 80 insertions(+), 77 deletions(-) diff --git a/coregrind/arch/x86-linux/vg_libpthread.c b/coregrind/arch/x86-linux/vg_libpthread.c index a8665fadf4..015b9f73b3 100644 --- a/coregrind/arch/x86-linux/vg_libpthread.c +++ b/coregrind/arch/x86-linux/vg_libpthread.c @@ -95,30 +95,18 @@ void myexit ( int arg ) } -/* Give up without using printf etc, since they seem to give - segfaults. */ +/* We need this guy -- it's in valgrind.so. */ +extern void VG_(startup) ( void ); + + +/* Just start up Valgrind if it's not already going. VG_(startup)() + detects and ignores second and subsequent calls. */ static __inline__ void ensure_valgrind ( char* caller ) { char* str; - int is_valgrind = RUNNING_ON_VALGRIND; - if (!is_valgrind) { - str = "\nvalgrind's libpthread.so: " - "pthread call when\n"; - write(2, str, strlen(str)); - str = "not running on valgrind; aborting! " - "This is probably a bug in\n"; - write(2, str, strlen(str)); - str = "valgrind. Please report it to me at: " - "jseward@acm.org. Thanks.\n"; - write(2, str, strlen(str)); - str = "unexpectedly called function is: "; - write(2, str, strlen(str)); - write(2, caller, strlen(caller)); - str = "\n\n"; - write(2, str, strlen(str)); - myexit(1); - } + int is_valgrind; + VG_(startup)(); } @@ -162,6 +150,8 @@ static void kludged ( char* msg ) static void not_inside ( char* msg ) { + VG_(startup)(); + return; if (get_pt_trace_level() >= 0) { char* ig = "valgrind's libpthread.so: NOT INSIDE VALGRIND " "during call to: "; @@ -343,6 +333,7 @@ int __pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) case PTHREAD_MUTEX_TIMED_NP: case PTHREAD_MUTEX_ADAPTIVE_NP: # endif + case PTHREAD_MUTEX_FAST_NP: case PTHREAD_MUTEX_RECURSIVE_NP: case PTHREAD_MUTEX_ERRORCHECK_NP: attr->__mutexkind = type; @@ -606,7 +597,7 @@ static pthread_mutex_t massacre_mx = PTHREAD_MUTEX_INITIALIZER; void __pthread_kill_other_threads_np ( void ) { int i, res, me; - pthread_mutex_lock(&massacre_mx); + __pthread_mutex_lock(&massacre_mx); me = pthread_self(); for (i = 1; i < VG_N_THREADS; i++) { if (i == me) continue; @@ -614,7 +605,7 @@ void __pthread_kill_other_threads_np ( void ) if (0 && res == 0) printf("----------- NUKED %d\n", i); } - pthread_mutex_unlock(&massacre_mx); + __pthread_mutex_unlock(&massacre_mx); } @@ -675,18 +666,20 @@ int __pthread_once ( pthread_once_t *once_control, int res; ensure_valgrind("pthread_once"); - res = pthread_mutex_lock(&once_masterlock); + res = __pthread_mutex_lock(&once_masterlock); - if (res != 0) + if (res != 0) { + printf("res = %d\n",res); barf("pthread_once: Looks like your program's " "init routine calls back to pthread_once() ?!"); + } if (*once_control == 0) { *once_control = 1; init_routine(); } - pthread_mutex_unlock(&once_masterlock); + __pthread_mutex_unlock(&once_masterlock); return 0; } diff --git a/coregrind/vg_libpthread.c b/coregrind/vg_libpthread.c index a8665fadf4..015b9f73b3 100644 --- a/coregrind/vg_libpthread.c +++ b/coregrind/vg_libpthread.c @@ -95,30 +95,18 @@ void myexit ( int arg ) } -/* Give up without using printf etc, since they seem to give - segfaults. */ +/* We need this guy -- it's in valgrind.so. */ +extern void VG_(startup) ( void ); + + +/* Just start up Valgrind if it's not already going. VG_(startup)() + detects and ignores second and subsequent calls. */ static __inline__ void ensure_valgrind ( char* caller ) { char* str; - int is_valgrind = RUNNING_ON_VALGRIND; - if (!is_valgrind) { - str = "\nvalgrind's libpthread.so: " - "pthread call when\n"; - write(2, str, strlen(str)); - str = "not running on valgrind; aborting! " - "This is probably a bug in\n"; - write(2, str, strlen(str)); - str = "valgrind. Please report it to me at: " - "jseward@acm.org. Thanks.\n"; - write(2, str, strlen(str)); - str = "unexpectedly called function is: "; - write(2, str, strlen(str)); - write(2, caller, strlen(caller)); - str = "\n\n"; - write(2, str, strlen(str)); - myexit(1); - } + int is_valgrind; + VG_(startup)(); } @@ -162,6 +150,8 @@ static void kludged ( char* msg ) static void not_inside ( char* msg ) { + VG_(startup)(); + return; if (get_pt_trace_level() >= 0) { char* ig = "valgrind's libpthread.so: NOT INSIDE VALGRIND " "during call to: "; @@ -343,6 +333,7 @@ int __pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) case PTHREAD_MUTEX_TIMED_NP: case PTHREAD_MUTEX_ADAPTIVE_NP: # endif + case PTHREAD_MUTEX_FAST_NP: case PTHREAD_MUTEX_RECURSIVE_NP: case PTHREAD_MUTEX_ERRORCHECK_NP: attr->__mutexkind = type; @@ -606,7 +597,7 @@ static pthread_mutex_t massacre_mx = PTHREAD_MUTEX_INITIALIZER; void __pthread_kill_other_threads_np ( void ) { int i, res, me; - pthread_mutex_lock(&massacre_mx); + __pthread_mutex_lock(&massacre_mx); me = pthread_self(); for (i = 1; i < VG_N_THREADS; i++) { if (i == me) continue; @@ -614,7 +605,7 @@ void __pthread_kill_other_threads_np ( void ) if (0 && res == 0) printf("----------- NUKED %d\n", i); } - pthread_mutex_unlock(&massacre_mx); + __pthread_mutex_unlock(&massacre_mx); } @@ -675,18 +666,20 @@ int __pthread_once ( pthread_once_t *once_control, int res; ensure_valgrind("pthread_once"); - res = pthread_mutex_lock(&once_masterlock); + res = __pthread_mutex_lock(&once_masterlock); - if (res != 0) + if (res != 0) { + printf("res = %d\n",res); barf("pthread_once: Looks like your program's " "init routine calls back to pthread_once() ?!"); + } if (*once_control == 0) { *once_control = 1; init_routine(); } - pthread_mutex_unlock(&once_masterlock); + __pthread_mutex_unlock(&once_masterlock); return 0; } diff --git a/coregrind/vg_startup.S b/coregrind/vg_startup.S index a0bb4eab79..63ee590153 100644 --- a/coregrind/vg_startup.S +++ b/coregrind/vg_startup.S @@ -54,11 +54,23 @@ call VG_(startup) .section .fini call VG_(shutdown) + +.section .data +valgrind_already_initted: + .word 0 + .section .text - +.global VG_(startup) VG_(startup): + cmpl $0, valgrind_already_initted + je really_start_up + ret + +really_start_up: + movl $1, valgrind_already_initted + # Record %esp as it was when we got here. This is because argv/c # and envp[] are passed as args to this function, and we need to see # envp so we can get at the env var VG_ARGS without help from libc. diff --git a/vg_libpthread.c b/vg_libpthread.c index a8665fadf4..015b9f73b3 100644 --- a/vg_libpthread.c +++ b/vg_libpthread.c @@ -95,30 +95,18 @@ void myexit ( int arg ) } -/* Give up without using printf etc, since they seem to give - segfaults. */ +/* We need this guy -- it's in valgrind.so. */ +extern void VG_(startup) ( void ); + + +/* Just start up Valgrind if it's not already going. VG_(startup)() + detects and ignores second and subsequent calls. */ static __inline__ void ensure_valgrind ( char* caller ) { char* str; - int is_valgrind = RUNNING_ON_VALGRIND; - if (!is_valgrind) { - str = "\nvalgrind's libpthread.so: " - "pthread call when\n"; - write(2, str, strlen(str)); - str = "not running on valgrind; aborting! " - "This is probably a bug in\n"; - write(2, str, strlen(str)); - str = "valgrind. Please report it to me at: " - "jseward@acm.org. Thanks.\n"; - write(2, str, strlen(str)); - str = "unexpectedly called function is: "; - write(2, str, strlen(str)); - write(2, caller, strlen(caller)); - str = "\n\n"; - write(2, str, strlen(str)); - myexit(1); - } + int is_valgrind; + VG_(startup)(); } @@ -162,6 +150,8 @@ static void kludged ( char* msg ) static void not_inside ( char* msg ) { + VG_(startup)(); + return; if (get_pt_trace_level() >= 0) { char* ig = "valgrind's libpthread.so: NOT INSIDE VALGRIND " "during call to: "; @@ -343,6 +333,7 @@ int __pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) case PTHREAD_MUTEX_TIMED_NP: case PTHREAD_MUTEX_ADAPTIVE_NP: # endif + case PTHREAD_MUTEX_FAST_NP: case PTHREAD_MUTEX_RECURSIVE_NP: case PTHREAD_MUTEX_ERRORCHECK_NP: attr->__mutexkind = type; @@ -606,7 +597,7 @@ static pthread_mutex_t massacre_mx = PTHREAD_MUTEX_INITIALIZER; void __pthread_kill_other_threads_np ( void ) { int i, res, me; - pthread_mutex_lock(&massacre_mx); + __pthread_mutex_lock(&massacre_mx); me = pthread_self(); for (i = 1; i < VG_N_THREADS; i++) { if (i == me) continue; @@ -614,7 +605,7 @@ void __pthread_kill_other_threads_np ( void ) if (0 && res == 0) printf("----------- NUKED %d\n", i); } - pthread_mutex_unlock(&massacre_mx); + __pthread_mutex_unlock(&massacre_mx); } @@ -675,18 +666,20 @@ int __pthread_once ( pthread_once_t *once_control, int res; ensure_valgrind("pthread_once"); - res = pthread_mutex_lock(&once_masterlock); + res = __pthread_mutex_lock(&once_masterlock); - if (res != 0) + if (res != 0) { + printf("res = %d\n",res); barf("pthread_once: Looks like your program's " "init routine calls back to pthread_once() ?!"); + } if (*once_control == 0) { *once_control = 1; init_routine(); } - pthread_mutex_unlock(&once_masterlock); + __pthread_mutex_unlock(&once_masterlock); return 0; } diff --git a/vg_startup.S b/vg_startup.S index a0bb4eab79..63ee590153 100644 --- a/vg_startup.S +++ b/vg_startup.S @@ -54,11 +54,23 @@ call VG_(startup) .section .fini call VG_(shutdown) + +.section .data +valgrind_already_initted: + .word 0 + .section .text - +.global VG_(startup) VG_(startup): + cmpl $0, valgrind_already_initted + je really_start_up + ret + +really_start_up: + movl $1, valgrind_already_initted + # Record %esp as it was when we got here. This is because argv/c # and envp[] are passed as args to this function, and we need to see # envp so we can get at the env var VG_ARGS without help from libc. -- 2.47.2