From bd7031143b56cbbc5a058fee1ee0b987153dbea5 Mon Sep 17 00:00:00 2001 From: madhavi Date: Wed, 11 Mar 2009 10:53:35 -0500 Subject: [PATCH] Fix for (1) power deadlock problem due to incorrect lock implementation. We now use dyn_pthread_self to get threadID instead of DYNINSTthreadSelf (2) Sparc test1_33 failure. plt calls are incorrectly categorized as non returning which causes problem with CFG analysis. --- dyninstAPI/src/image-flowGraph.C | 7 +++- dyninstAPI_RT/rs6000-ibm-aix5.1/Makefile | 1 + dyninstAPI_RT/src/RTthread-index.c | 5 ++- dyninstAPI_RT/src/RTthread-power-asm.s | 19 ++++++--- dyninstAPI_RT/src/RTthread-power.c | 68 ++++++++++++++++++++++++++++++++ 5 files changed, 91 insertions(+), 9 deletions(-) create mode 100644 dyninstAPI_RT/src/RTthread-power.c diff --git a/dyninstAPI/src/image-flowGraph.C b/dyninstAPI/src/image-flowGraph.C index b6199a0..bfb0696 100644 --- a/dyninstAPI/src/image-flowGraph.C +++ b/dyninstAPI/src/image-flowGraph.C @@ -1190,8 +1190,11 @@ bool image_func::buildCFG( // the call insruction as an unconditional branch // link up the fallthrough edge unless we know for - // certain that the target function does not return - if(targetFunc && targetFunc->returnStatus() == RS_NORETURN) + // certain that the target function does not return, + // or if the target is an entry in the PLT (and not + // one of the special-case non-returning entries above) + if(targetFunc && targetFunc->returnStatus() == RS_NORETURN + && !(*pltFuncs).defines(target)) { parsing_printf("[%s:%u] not parsing past non-returning " "call at 0x%lx (to %s)\n", diff --git a/dyninstAPI_RT/rs6000-ibm-aix5.1/Makefile b/dyninstAPI_RT/rs6000-ibm-aix5.1/Makefile index ac7cc52..303a513 100644 --- a/dyninstAPI_RT/rs6000-ibm-aix5.1/Makefile +++ b/dyninstAPI_RT/rs6000-ibm-aix5.1/Makefile @@ -29,6 +29,7 @@ SRCS += ../src/RTposix.c \ ../src/RTheap.c \ ../src/RTheap-aix.c \ ../src/RTthread-power-asm.s \ + ../src/RTthread-power.c\ ../src/RTthread-index.c \ ../src/RTthread.c # ../src/RTmutatedBinary.c \ diff --git a/dyninstAPI_RT/src/RTthread-index.c b/dyninstAPI_RT/src/RTthread-index.c index bc74b77..8ff7ea2 100644 --- a/dyninstAPI_RT/src/RTthread-index.c +++ b/dyninstAPI_RT/src/RTthread-index.c @@ -113,9 +113,9 @@ unsigned DYNINSTthreadIndexSLOW(dyntid_t tid) unsigned retval = DYNINST_NOT_IN_HASHTABLE; int index, result; unsigned long tid_val = (unsigned long) tid; - result = tc_lock_lock(&DYNINST_index_lock); if (result == DYNINST_DEAD_LOCK) { + rtdebug_printf("%s[%d]: DEADLOCK HERE tid %lu \n", __FILE__, __LINE__, dyn_pthread_self()); /* We specifically return DYNINST_max_num_threads so that instrumentation has someplace safe to scribble in case of an error. */ /* DO NOT USE print statements here. That's horribly unsafe if we've instrumented @@ -219,6 +219,7 @@ unsigned DYNINST_alloc_index(dyntid_t tid) result = tc_lock_lock(&DYNINST_index_lock); if (result == DYNINST_DEAD_LOCK) { + rtdebug_printf("%s[%d]: DEADLOCK HERE tid %lu \n", __FILE__, __LINE__, dyn_pthread_self()); /* ERROR_HANDLING_BAD */ return DYNINST_max_num_threads; } @@ -283,7 +284,7 @@ int DYNINST_free_index(dyntid_t tid) result = tc_lock_lock(&DYNINST_index_lock); if (result == DYNINST_DEAD_LOCK) { - rtdebug_printf("%s[%d]: DEADLOCK HERE\n", __FILE__, __LINE__); + rtdebug_printf("%s[%d]: DEADLOCK HERE tid %lu \n", __FILE__, __LINE__, dyn_pthread_self()); return -1; } diff --git a/dyninstAPI_RT/src/RTthread-power-asm.s b/dyninstAPI_RT/src/RTthread-power-asm.s index db4d576..0fd7a4d 100644 --- a/dyninstAPI_RT/src/RTthread-power-asm.s +++ b/dyninstAPI_RT/src/RTthread-power-asm.s @@ -35,14 +35,23 @@ DYNINSTthreadSelf: DYNINSTthreadSelf_NOT_SPR: l 3,200(3) br - .globl tc_lock_lock - .globl .tc_lock_lock -tc_lock_lock: -.tc_lock_lock: + .globl compare_and_swap2 + .globl .compare_and_swap2 +compare_and_swap2: +.compare_and_swap2: + lwarx 5,0,3 + stwcx. 4,0,3 + bne- compare_and_swap2 + mr 3,5 + blr + .globl tc_lock_lock2 + .globl .tc_lock_lock2 +tc_lock_lock2: +.tc_lock_lock2: mflr 0 stw 0,8(1) mr 10,3 # &t in R10 - bl .DYNINSTthreadSelf + bl .dyn_pthread_self cror 31,31,31 lil 6,1 # r6 == 1 tc_lock_lock_loop: diff --git a/dyninstAPI_RT/src/RTthread-power.c b/dyninstAPI_RT/src/RTthread-power.c new file mode 100644 index 0000000..8ca69af --- /dev/null +++ b/dyninstAPI_RT/src/RTthread-power.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 1996-2004 Barton P. Miller + * + * We provide the Paradyn Parallel Performance Tools (below + * described as "Paradyn") on an AS IS basis, and do not warrant its + * validity or performance. We reserve the right to update, modify, + * or discontinue this software at any time. We shall have no + * obligation to supply such updates or modifications or any other + * form of support to you. + * + * This license is for research uses. For such uses, there is no + * charge. We define "research use" to mean you may freely use it + * inside your organization for whatever purposes you see fit. But you + * may not re-distribute Paradyn or parts of Paradyn, in any form + * source or binary (including derivatives), electronic or otherwise, + * to any other organization or entity without our permission. + * + * (for other uses, please contact us at paradyn@cs.wisc.edu) + * + * All warranties, including without limitation, any warranty of + * merchantability or fitness for a particular purpose, are hereby + * excluded. + * + * By your use of Paradyn, you understand and agree that we (or any + * other person or entity with proprietary rights in Paradyn) are + * under no obligation to provide either maintenance services, + * update services, notices of latent defects, or correction of + * defects for Paradyn. + * + * Even if advised of the possibility of such damages, under no + * circumstances shall we (or any other person or entity with + * proprietary rights in the software licensed hereunder) be liable + * to you or any third party for direct, indirect, or consequential + * damages of any character regardless of type of action, including, + * without limitation, loss of profits, loss of use, loss of good + * will, or computer failure or malfunction. You agree to indemnify + * us (and any other person or entity with proprietary rights in the + * software licensed hereunder) for any and all liability it may + * incur to third parties resulting from your use of Paradyn. + */ + +#include "dyninstAPI_RT/src/RTthread.h" + +extern int compare_and_swap2(tc_lock_t *, int, int); + +/** + * compare_and_swap2 will do the following atomically: + * if (*val == 0) { + * *val = 1; + * return 1; + * } + * return 0; + * + **/ + +int tc_lock_lock(tc_lock_t *t) { + dyntid_t me = dyn_pthread_self(); + int ret = 1; + while (ret == 1) { + /* Try to acquire the lock */ + ret = compare_and_swap2(&(t->mutex), 1, 0); + if (ret == 1) { + if (t->tid == me) return DYNINST_DEAD_LOCK; + } + } + t->tid = me; + return 0; +} -- 1.8.3.1