2 * Copyright (c) 1996-2004 Barton P. Miller
4 * We provide the Paradyn Parallel Performance Tools (below
5 * described as "Paradyn") on an AS IS basis, and do not warrant its
6 * validity or performance. We reserve the right to update, modify,
7 * or discontinue this software at any time. We shall have no
8 * obligation to supply such updates or modifications or any other
9 * form of support to you.
11 * This license is for research uses. For such uses, there is no
12 * charge. We define "research use" to mean you may freely use it
13 * inside your organization for whatever purposes you see fit. But you
14 * may not re-distribute Paradyn or parts of Paradyn, in any form
15 * source or binary (including derivatives), electronic or otherwise,
16 * to any other organization or entity without our permission.
18 * (for other uses, please contact us at paradyn@cs.wisc.edu)
20 * All warranties, including without limitation, any warranty of
21 * merchantability or fitness for a particular purpose, are hereby
24 * By your use of Paradyn, you understand and agree that we (or any
25 * other person or entity with proprietary rights in Paradyn) are
26 * under no obligation to provide either maintenance services,
27 * update services, notices of latent defects, or correction of
28 * defects for Paradyn.
30 * Even if advised of the possibility of such damages, under no
31 * circumstances shall we (or any other person or entity with
32 * proprietary rights in the software licensed hereunder) be liable
33 * to you or any third party for direct, indirect, or consequential
34 * damages of any character regardless of type of action, including,
35 * without limitation, loss of profits, loss of use, loss of good
36 * will, or computer failure or malfunction. You agree to indemnify
37 * us (and any other person or entity with proprietary rights in the
38 * software licensed hereunder) for any and all liability it may
39 * incur to third parties resulting from your use of Paradyn.
42 // $Id: BPatch.C,v 1.87 2005/02/10 20:39:16 jaw Exp $
49 #include "common/h/Pair.h"
50 #include "common/h/Vector.h"
51 #include "signalhandler.h"
54 #include "BPatch_typePrivate.h"
55 #include "BPatch_libInfo.h"
57 #include "BPatch_collections.h"
58 #include "BPatch_asyncEventHandler.h"
59 #include "common/h/timing.h"
61 #if defined(i386_unknown_nt4_0) || defined(mips_unknown_ce2_11) //ccw 20 july 2000 : 28 mar 2001
62 #include "nt_signal_emul.h"
65 extern bool dyninstAPI_init();
66 extern void loadNativeDemangler();
68 BPatch *BPatch::bpatch = NULL;
70 // global stat vars defined in stats.C
71 extern unsigned int trampBytes;
72 extern unsigned int pointsUsed;
73 extern unsigned int insnGenerated;
74 extern unsigned int totalMiniTramps;
75 extern unsigned int ptraceOtherOps;
76 extern unsigned int ptraceOps;
77 extern unsigned int ptraceBytes;
83 * Constructor for BPatch. Performs one-time initialization needed by the
89 dynLibraryCallback(NULL),
93 baseTrampDeletionOn(false),
94 trampRecursiveOn(false),
95 forceRelocation_NP(false),
96 autoRelocation_NP(true),
97 delayedParsing_(false),
103 memset(&stats, 0, sizeof(BPatch_stats));
106 // Save a pointer to the one-and-only bpatch object.
109 #ifdef mips_unknown_ce2_11 //ccw 10 aug 2000 : 28 mar 2001
110 rDevice = new remoteDevice(); //ccw 8 aug 2000
115 * (indicate an error somehow)
118 // XXX dyninstAPI_init returns success/failure -- should pass on somehow
120 initCyclesPerSecond();
123 * Create the library private info object.
125 info = new BPatch_libInfo;
128 * Create the "error" and "untyped" types.
130 type_Error = BPatch_type::createFake("<error>");
131 type_Untyped = BPatch_type::createFake("<no type>");
134 * Initialize hash table of standard types.
136 BPatch_type *newType;
137 stdTypes = new BPatch_typeCollection;
138 stdTypes->addType(newType = new BPatch_typeScalar(-1, sizeof(int), "int"));
139 newType->decrRefCount();
140 BPatch_type *charType = new BPatch_typeScalar(-2, sizeof(char), "char");
141 stdTypes->addType(charType);
142 stdTypes->addType(newType = new BPatch_typePointer(-3, charType, "char *"));
143 charType->decrRefCount();
144 newType->decrRefCount();
145 BPatch_type *voidType = new BPatch_typeScalar(-11, 0, "void");
146 stdTypes->addType(voidType);
147 stdTypes->addType(newType = new BPatch_typePointer(-4, voidType, "void *"));
148 voidType->decrRefCount();
149 newType->decrRefCount();
150 stdTypes->addType(newType = new BPatch_typeScalar(-12, sizeof(float), "float"));
151 newType->decrRefCount();
152 #if defined(i386_unknown_nt4_0)
153 stdTypes->addType(newType = new BPatch_typeScalar(-31, sizeof(LONGLONG), "long long"));
155 stdTypes->addType(newType = new BPatch_typeScalar(-31, sizeof(long long), "long long"));
157 newType->decrRefCount();
160 * Initialize hash table of API types.
162 APITypes = new BPatch_typeCollection;
165 * Initialize hash table of Built-in types.
166 * Negative type numbers defined in the gdb stab-docs
169 builtInTypes = new BPatch_builtInTypeCollection;
171 // NOTE: integral type mean twos-complement
172 // -1 int, 32 bit signed integral type
173 // in stab document, size specified in bits, system size is in bytes
174 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-1, 4, "int"));
175 newType->decrRefCount();
176 // -2 char, 8 bit type holding a character. GDB & dbx(AIX) treat as signed
177 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-2, 1, "char"));
178 newType->decrRefCount();
179 // -3 short, 16 bit signed integral type
180 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-3, 2, "short"));
181 newType->decrRefCount();
182 // -4 long, 32/64 bit signed integral type
183 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-4, sizeof(long), "long"));
184 newType->decrRefCount();
185 // -5 unsigned char, 8 bit unsigned integral type
186 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-5, 1, "unsigned char"));
187 newType->decrRefCount();
188 // -6 signed char, 8 bit signed integral type
189 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-6, 1, "signed char"));
190 newType->decrRefCount();
191 // -7 unsigned short, 16 bit unsigned integral type
192 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-7, 2, "unsigned short"));
193 newType->decrRefCount();
194 // -8 unsigned int, 32 bit unsigned integral type
195 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-8, 4, "unsigned int"));
196 newType->decrRefCount();
197 // -9 unsigned, 32 bit unsigned integral type
198 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-9, 4, "unsigned"));
199 newType->decrRefCount();
200 // -10 unsigned long, 32 bit unsigned integral type
201 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-10, sizeof(unsigned long), "unsigned long"));
202 newType->decrRefCount();
203 // -11 void, type indicating the lack of a value
204 // XXX-size may not be correct jdd 4/22/99
205 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-11, 0, "void"));
206 newType->decrRefCount();
207 // -12 float, IEEE single precision
208 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-12, sizeof(float), "float"));
209 newType->decrRefCount();
210 // -13 double, IEEE double precision
211 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-13, sizeof(double), "double"));
212 newType->decrRefCount();
213 // -14 long double, IEEE double precision, size may increase in future
214 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-14, sizeof(long double), "long double"));
215 newType->decrRefCount();
216 // -15 integer, 32 bit signed integral type
217 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-15, 4, "integer"));
218 newType->decrRefCount();
219 // -16 boolean, 32 bit type. GDB/GCC 0=False, 1=True, all other values
220 // have unspecified meaning
221 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-16, sizeof(bool), "boolean"));
222 newType->decrRefCount();
223 // -17 short real, IEEE single precision
224 // XXX-size may not be correct jdd 4/22/99
225 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-17, sizeof(float), "short real"));
226 newType->decrRefCount();
227 // -18 real, IEEE double precision XXX-size may not be correct jdd 4/22/99
228 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-18, sizeof(double), "real"));
229 newType->decrRefCount();
230 // -19 stringptr XXX- size of void * -- jdd 4/22/99
231 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-19, sizeof(void *), "stringptr"));
232 newType->decrRefCount();
233 // -20 character, 8 bit unsigned character type
234 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-20, 1, "character"));
235 newType->decrRefCount();
236 // -21 logical*1, 8 bit type (Fortran, used for boolean or unsigned int)
237 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-21, 1, "logical*1"));
238 newType->decrRefCount();
239 // -22 logical*2, 16 bit type (Fortran, some for boolean or unsigned int)
240 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-22, 2, "logical*2"));
241 newType->decrRefCount();
242 // -23 logical*4, 32 bit type (Fortran, some for boolean or unsigned int)
243 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-23, 4, "logical*4"));
244 newType->decrRefCount();
245 // -24 logical, 32 bit type (Fortran, some for boolean or unsigned int)
246 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-24, 4, "logical"));
247 newType->decrRefCount();
248 // -25 complex, consists of 2 IEEE single-precision floating point values
249 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-25, sizeof(float)*2, "complex"));
250 newType->decrRefCount();
251 // -26 complex, consists of 2 IEEE double-precision floating point values
252 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-26, sizeof(double)*2, "complex*16"));
253 newType->decrRefCount();
254 // -27 integer*1, 8 bit signed integral type
255 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-27, 1, "integer*1"));
256 newType->decrRefCount();
257 // -28 integer*2, 16 bit signed integral type
258 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-28, 2, "integer*2"));
259 newType->decrRefCount();
261 /* Quick hack to make integer*4 compatible with int for Fortran
264 // This seems questionable - let's try removing that hack - jmo 05/21/04
266 builtInTypes->addBuiltInType(newType = new BPatch_type("int",-29,
267 BPatch_built_inType, 4));
268 newType->decrRefCount();
270 // -29 integer*4, 32 bit signed integral type
271 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-29, 4, "integer*4"));
272 newType->decrRefCount();
273 // -30 wchar, Wide character, 16 bits wide, unsigned (unknown format)
274 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-30, 2, "wchar"));
275 newType->decrRefCount();
276 #ifdef i386_unknown_nt4_0
277 // -31 long long, 64 bit signed integral type
278 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-31, sizeof(LONGLONG), "long long"));
279 newType->decrRefCount();
280 // -32 unsigned long long, 64 bit unsigned integral type
281 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-32, sizeof(ULONGLONG), "unsigned long long"));
282 newType->decrRefCount();
284 // -31 long long, 64 bit signed integral type
285 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-31, sizeof(long long), "long long"));
286 newType->decrRefCount();
287 // -32 unsigned long long, 64 bit unsigned integral type
288 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-32, sizeof(unsigned long long), "unsigned long long"));
289 newType->decrRefCount();
291 // -33 logical*8, 64 bit unsigned integral type
292 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-33, 8, "logical*8"));
293 newType->decrRefCount();
294 // -34 integer*8, 64 bit signed integral type
295 builtInTypes->addBuiltInType(newType = new BPatch_typeScalar(-34, 8, "integer*8"));
296 newType->decrRefCount();
298 // default callbacks are null
299 postForkCallback = NULL;
300 preForkCallback = NULL;
302 dynLibraryCallback = NULL;
305 oneTimeCodeCallback = NULL;
307 #ifdef IBM_BPATCH_COMPAT
308 RPCdoneCallback = NULL;
311 loadNativeDemangler();
313 eventHandler = new BPatch_asyncEventHandler();
314 #if !defined (os_windows) && !defined (arch_ia64) && !defined (os_osf) && !defined (os_irix)
315 if (!eventHandler->initialize()) {
316 // not much else we can do in the ctor, except complain (should we abort?)
317 bperr("%s[%d]: failed to initialize eventHandler, possibly fatal\n",
327 * Destructor for BPatch. Free allocated memory.
329 void BPatch::BPatch_dtor()
333 type_Error->decrRefCount();
334 type_Untyped->decrRefCount();
341 bool BPatch::isTypeCheckedInt()
345 void BPatch::setTypeCheckingInt(bool x)
349 bool BPatch::parseDebugInfoInt()
353 bool BPatch::delayedParsingOnInt()
355 return delayedParsing_;
357 void BPatch::setDebugParsingInt(bool x)
361 bool BPatch::baseTrampDeletionInt()
363 return baseTrampDeletionOn;
365 void BPatch::setBaseTrampDeletionInt(bool x)
367 baseTrampDeletionOn = x;
369 bool BPatch::isTrampRecursiveInt()
371 return trampRecursiveOn;
373 void BPatch::setTrampRecursiveInt(bool x)
375 trampRecursiveOn = x;
377 bool BPatch::hasForcedRelocation_NPInt()
379 return forceRelocation_NP;
381 void BPatch::setForcedRelocation_NPInt(bool x)
383 forceRelocation_NP = x;
385 bool BPatch::autoRelocationOnInt()
387 return autoRelocation_NP;
389 void BPatch::setAutoRelocation_NPInt(bool x)
391 autoRelocation_NP = x;
393 void BPatch::setDelayedParsingInt(bool x)
402 * BPatch::registerErrorCallbackInt
404 * Registers a function that is to be called by the library when an error
405 * occurs or when there is status to report. Returns the address of the
406 * previously registered error callback function.
408 * function The function to be called.
410 BPatchErrorCallback BPatch::registerErrorCallbackInt(BPatchErrorCallback function)
412 BPatchErrorCallback ret;
415 errorHandler = function;
422 * BPatch::registerPostForkCallback
424 * Registers a function that is to be called by the library when a new
425 * process has been forked off by an mutatee process.
427 * function The function to be called.
429 BPatchForkCallback BPatch::registerPostForkCallbackInt(BPatchForkCallback func)
431 #if defined(i386_unknown_nt4_0)
432 reportError(BPatchWarning, 0,
433 "postfork callbacks not implemented on this platform\n");
436 BPatchForkCallback ret;
438 ret = postForkCallback;
439 postForkCallback = func;
446 * BPatch::registerPreForkCallback
448 * Registers a function that is to be called by the library when a process
449 * is about to fork a new process
451 * function The function to be called.
453 BPatchForkCallback BPatch::registerPreForkCallbackInt(BPatchForkCallback func)
455 #if defined(i386_unknown_nt4_0)
456 reportError(BPatchWarning, 0,
457 "prefork callbacks not implemented on this platform\n");
460 BPatchForkCallback ret;
462 ret = preForkCallback;
463 preForkCallback = func;
470 * BPatch::registerExecCallback
472 * Registers a function that is to be called by the library when a
473 * process has just completed an exec* call
475 * func The function to be called.
477 BPatchExecCallback BPatch::registerExecCallbackInt(BPatchExecCallback func)
480 #if defined(i386_unknown_nt4_0)
481 reportError(BPatchWarning, 0,
482 "exec callbacks not implemented on this platform\n");
485 BPatchExecCallback ret;
495 * BPatch::registerExecCallback
497 * Registers a function that is to be called by the library when a
498 * process has just called the exit system call
500 * func The function to be called.
502 BPatchExitCallback BPatch::registerExitCallbackInt(BPatchExitCallback func)
504 BPatchExitCallback ret;
513 * BPatch::registerOneTimeCodeCallback
515 * Registers a function that is to be called by the library when a
516 * oneTimeCode (inferior RPC) is completed.
518 * func The function to be called.
520 BPatchOneTimeCodeCallback BPatch::registerOneTimeCodeCallbackInt(BPatchOneTimeCodeCallback func)
522 BPatchOneTimeCodeCallback ret;
524 ret = oneTimeCodeCallback;
525 oneTimeCodeCallback = func;
530 #ifdef IBM_BPATCH_COMPAT
531 BPatchExitCallback BPatch::registerExitCallbackInt(BPatchThreadEventCallback func)
534 BPatchExitCallback ret;
537 exitCallback = (BPatchExitCallback) func;
545 * BPatch::registerDynLibraryCallback
547 * Registers a function that is to be called by the library when a dynamically
548 * loaded library is loaded or unloaded by a process under the API's control.
549 * Returns the address of the previously registered callback function.
551 * function The function to be called.
553 BPatchDynLibraryCallback
554 BPatch::registerDynLibraryCallbackInt(BPatchDynLibraryCallback function)
556 BPatchDynLibraryCallback ret;
558 ret = dynLibraryCallback;
559 dynLibraryCallback = function;
566 * BPatch::getEnglishErrorString
568 * Returns the descriptive error string for the passed error number.
570 * number The number that identifies the error.
572 const char *BPatch::getEnglishErrorString(int /* number */)
579 * BPatch::reportError
581 * Report an error using the callback mechanism.
583 * severity The severity level of the error.
584 * number Identifies the error.
585 * str A string to pass as the first element of the list of strings
586 * given to the callback function.
588 void BPatch::reportError(BPatchErrorLevel severity, int number, const char *str)
590 assert(bpatch != NULL);
592 // don't log BPatchWarning or BPatchInfo messages as "errors"
593 if ((severity == BPatchFatal) || (severity == BPatchSerious))
594 bpatch->lastError = number;
596 if (bpatch->errorHandler != NULL) {
597 bpatch->errorHandler(severity, number, &str);
598 } else if ((severity == BPatchFatal) || (severity == BPatchSerious)){
599 fprintf(stdout, "DYNINST ERROR: %s\n", str);
606 * BPatch::formatErrorString
608 * Takes a format string with an error message (obtained from
609 * getEnglishErrorString) and an array of parameters that were passed to an
610 * error callback function, and creates a string with the parameters
611 * substituted into it.
613 * dst The address into which the formatted string should be copied.
614 * size If the formatted string is equal to or longer than this number
615 * of characters, then it will be truncated to size-1 characters
616 * and terminated with a nul ('\0').
617 * fmt The format string (returned by a function such as
618 * getEnglishErrorString).
619 * params The array of parameters that were passed to an error callback
622 void BPatch::formatErrorString(char *dst, int size,
623 const char *fmt, const char **params)
627 while (size > 1 && *fmt) {
629 if (fmt[1] == '\0') {
631 } else if (fmt[1] == '%') {
634 } else if (fmt[1] == 's') {
635 char *p = const_cast<char *>(params[cur_param++]);
636 while (size > 1 && *p) {
658 * BPatch::getThreadByPid
660 * Given a process ID, this function returns a pointer to the associated
661 * BPatch_thread object (or NULL if there is none). Since a process may be
662 * registered provisionally with a thread object pointer of NULL, the boolean
663 * pointed to by the parameter "exists" is set to true if the pid exists in
664 * the table of processes, and false if it does not.
666 * pid The pid to look up.
667 * exists A pointer to a boolean to fill in with true if the pid exists
668 * in the table and false if it does not. NULL may be passed in
669 * if this information is not required.
671 BPatch_thread *BPatch::getThreadByPid(int pid, bool *exists)
673 if (info->threadsByPid.defines(pid)) {
674 if (exists) *exists = true;
675 return info->threadsByPid[pid];
677 if (exists) *exists = false;
686 * Returns a vector of all threads that are currently defined. Includes
687 * threads created directly using the library and those created with UNIX fork
688 * or Windows NT spawn system calls. The caller is responsible for deleting
689 * the vector when it is no longer needed.
691 BPatch_Vector<BPatch_thread *> *BPatch::getThreadsInt()
693 BPatch_Vector<BPatch_thread *> *result = new BPatch_Vector<BPatch_thread *>;
695 dictionary_hash_iter<int, BPatch_thread *> ti(info->threadsByPid);
698 BPatch_thread *thread;
700 while (ti.next(pid, thread))
701 result->push_back(thread);
708 * BPatch::registerProvisionalThread
710 * Register a new process that is not yet associated with a thread.
711 * (this function is called only by createProcess).
713 * pid The pid of the process to register.
715 void BPatch::registerProvisionalThread(int pid)
717 assert(!info->threadsByPid.defines(pid));
718 info->threadsByPid[pid] = NULL;
723 * BPatch::registerForkedThread
725 * Register a new process that is not yet associated with a thread.
726 * (this function is an upcall when a new process is created).
728 * parentPid the pid of the parent process.
729 * childPid The pid of the process to register.
730 * proc lower lever handle to process specific stuff
733 void BPatch::registerForkedThread(int parentPid, int childPid, process *proc)
735 assert(!info->threadsByPid.defines(childPid));
737 BPatch_thread *parent = info->threadsByPid[parentPid];
740 info->threadsByPid[childPid] = new BPatch_thread(childPid, proc);
742 #if !defined (os_osf) && !defined(os_windows) && !defined (arch_ia64) && !defined(os_irix)
743 if (!eventHandler->connectToProcess(info->threadsByPid[childPid])) {
744 bperr("%s[%d]: eventHandler->connectToProcess failed\n", __FILE__, __LINE__);
748 if (postForkCallback) {
749 postForkCallback(parent, info->threadsByPid[childPid]);
751 // We don't want to touch the bpatch threads here, as they may have been
752 // deleted in the callback
753 // TODO: figure out if they have and remove them from the info list
757 * BPatch::registerForkingThread
759 * Perform whatever processing is necessary when a thread enters
760 * a fork system call. Previously the preForkCallback was made directly.
762 * forkingPid pid of the forking process
763 * proc lower lever handle to process specific stuff
766 void BPatch::registerForkingThread(int forkingPid, process * /*proc*/)
768 BPatch_thread *forking = info->threadsByPid[forkingPid];
769 // Wouldn't this be the same as proc->thread?
772 if (preForkCallback) {
773 preForkCallback(forking, NULL);
779 * BPatch::registerExec
781 * Register a process that has just done an exec call.
783 * thread thread that has just performed the exec
786 void BPatch::registerExec(BPatch_thread *thread)
788 // build a new BPatch_image for this one
789 thread->image = new BPatch_image(thread);
792 execCallback(thread);
796 void BPatch::registerNormalExit(BPatch_thread *thread, int exitcode)
798 thread->setExitCode(exitcode);
799 thread->setExitedNormally();
801 exitCallback(thread, ExitedNormally);
805 void BPatch::registerSignalExit(BPatch_thread *thread, int signalnum)
807 thread->setExitedViaSignal(signalnum);
809 exitCallback(thread, ExitedViaSignal);
816 * BPatch::registerThread
818 * Register a new BPatch_thread object with the BPatch library (this function
819 * is called only by the constructor for BPatch_thread).
821 * thread A pointer to the thread to register.
823 void BPatch::registerThread(BPatch_thread *thread)
825 assert(!info->threadsByPid.defines(thread->getPid()) ||
826 info->threadsByPid[thread->getPid()] == NULL);
827 info->threadsByPid[thread->getPid()] = thread;
832 * BPatch::unRegisterThread
834 * Remove the BPatch_thread associated with a given pid from the list of
835 * threads being managed by the library.
837 * pid The pid of the thread to be removed.
839 void BPatch::unRegisterThread(int pid)
841 assert(info->threadsByPid.defines(pid));
842 info->threadsByPid.undef(pid);
847 * BPatch::createProcessInt
849 * Create a process and return a BPatch_thread representing it.
850 * Returns NULL upon failure.
852 * path The pathname of the executable for the new process.
853 * argv A list of the arguments for the new process, terminated by a
855 * envp A list of values that make up the environment for the new
856 * process, terminated by a NULL. If envp is NULL, the new
857 * new process will inherit the environemnt of the parent.
858 * stdin_fd file descriptor to use for stdin for the application
859 * stdout_fd file descriptor to use for stdout for the application
860 * stderr_fd file descriptor to use for stderr for the application
863 BPatch_thread *BPatch::createProcessInt(const char *path, const char *argv[], const char *envp[],
864 int stdin_fd, int stdout_fd, int stderr_fd)
869 new BPatch_thread(path, const_cast<char **>(argv), const_cast<char **>(envp),
870 stdin_fd, stdout_fd, stderr_fd);
873 (ret->proc->status() != stopped) ||
874 !ret->proc->isBootstrappedYet()) {
876 reportError(BPatchFatal, 68, "create process failed bootstrap");
879 #if !defined (os_osf) && !defined (os_windows) && !defined(arch_ia64) && !defined(os_irix)
880 if (!eventHandler->connectToProcess(ret)) {
881 bpfatal("%s[%d]: eventHandler->connectToProcess failed\n", __FILE__, __LINE__);
882 fprintf(stderr,"%s[%d]: eventHandler->connectToProcess failed\n", __FILE__, __LINE__);
887 ret->proc->collectSaveWorldData = false;
888 //ccw 23 jan 2002 : this forces the user to call
889 //BPatch_thread::enableDumpPatchedImage() if they want to use the save the world
896 * BPatch::attachProcess
898 * Attach to a running process and return a BPatch_thread representing it.
899 * Returns NULL upon failure.
901 * path The pathname of the executable for the process.
902 * pid The id of the process to attach to.
904 BPatch_thread *BPatch::attachProcessInt(const char *path, int pid)
908 BPatch_thread *ret = new BPatch_thread(path, pid);
911 (ret->proc->status() != stopped) ||
912 !ret->proc->isBootstrappedYet()) {
913 // It would be considerate to (attempt to) leave the process running
914 // at this point (*before* deleting the BPatch_thread handle for it!),
915 // even though it might be in bad shape after the attempted attach.
917 sprintf(msg,"attachProcess failed: process %d may now be killed!",pid);
918 reportError(BPatchWarning, 26, msg);
922 #if !defined (os_osf) && !defined (os_windows) && !defined(os_irix) && !defined (arch_ia64)
923 if (!eventHandler->connectToProcess(ret)) {
924 bperr("%s[%d]: eventHandler->connectToProcess failed\n", __FILE__, __LINE__);
928 ret->proc->collectSaveWorldData = false;
929 //ccw 31 jan 2003 : this forces the user to call
930 //BPatch_thread::enableDumpPatchedImage() if they want to use the save the world
937 * BPatch::getThreadEvent
939 * Checks for changes in any child process, and optionally blocks until such a
940 * change has occurred. Also performs housekeeping on behalf of Dyninst:
941 * - Launches pending oneTimeCode calls (aka inferior RPCs)
942 * - Updates the process object representing each process for which a
943 * change is detected.
945 * The return value is true if a change was detected, otherwise it is false.
947 * block Set this parameter to true to block waiting for a change,
948 * set to false to poll and return immediately, whether or not a
951 bool BPatch::getThreadEvent(bool block)
953 launchDeferredOneTimeCode();
955 return getThreadEventOnly(block);
959 * BPatch::getThreadEventOnly
961 * Like getThreadEvent (which actually calls this function), this function
962 * checks for changes in any child process, optionally blocking until such a
963 * change occurs. It also updates the process objects with information about
964 * such changes. Unlike getThreadEvent, it does not perform any additional
965 * housekeeping like launching deferred RPCs.
967 * Returns true if a change was detected, otherwise returns false.
969 * block Set this parameter to true to block waiting for a change,
970 * set to false to poll and return immediately, whether or not a
973 bool BPatch::getThreadEventOnly(bool block)
977 // Handles all process (object)-level events.
979 pdvector<procevent *> events;
980 result = getSH()->checkForProcessEvents(&events, -1, block);
982 pdvector<procevent *> unhandledEvents = getSH()->handleProcessEvents(events);
984 for(unsigned i=0; i < unhandledEvents.size(); i++)
986 // The only thing we expect to see in here is a SIGSTOP from DYNINSTbreakPoint...
987 procevent *cur_event = unhandledEvents[i];
988 process *proc = cur_event->proc;
989 procSignalWhy_t why = cur_event->why;
990 procSignalWhat_t what = cur_event->what;
993 BPatch_thread *thread = getThreadByPid(proc->getPid(), &exists);
994 if (thread == NULL) {
996 bperr("Warning: event on an existing thread, but can't find thread handle\n");
998 bperr( "Warning - wait returned status of an unknown process (%d)\n",
1002 else { // found a thread
1003 #if !defined(os_windows)
1004 if (didProcReceiveSignal(why)) {
1005 thread->lastSignal = what;
1006 #if defined(os_irix)
1007 unsigned int stop_sig = SIGEMT;
1009 unsigned int stop_sig = SIGSTOP;
1011 if (what != stop_sig) {
1012 forwardSigToProcess(*cur_event);
1015 thread->setUnreportedStop(true);
1019 // bperr( "Unhandled event (why %d, what %d) on process %d\n",
1020 // why, what, proc->getPid());
1021 thread->setUnreportedStop(true);
1025 thread->setUnreportedStop(true);
1028 delete unhandledEvents[i];
1038 * Returns true if any thread has stopped or terminated and that fact hasn't
1039 * been reported to the user of the library. Otherwise, returns false.
1041 bool BPatch::havePendingEvent()
1043 #if defined(i386_unknown_nt4_0) || defined(mips_unknown_ce2_11) //ccw 20 july 2001 : 28 mar 2001
1044 // On NT, we need to poll for events as often as possible, so that we can
1046 if (getThreadEvent(false))
1050 // For now, we'll do it by iterating over the threads and checking them,
1051 // and we'll change it to something more efficient later on.
1052 dictionary_hash_iter<int, BPatch_thread *> ti(info->threadsByPid);
1055 BPatch_thread *thread;
1057 while (ti.next(pid, thread)) {
1058 if (thread != NULL &&
1059 (thread->pendingUnreportedStop() ||
1060 thread->pendingUnreportedTermination())) {
1069 * pollForStatusChange
1071 * Checks for unreported changes to the status of any child process, and
1072 * returns true if any are detected. Returns false otherwise.
1074 * This function is declared as a friend of BPatch_thread so that it can use
1075 * the BPatch_thread::getThreadEvent call to check for status changes.
1077 bool BPatch::pollForStatusChangeInt()
1079 if (havePendingEvent())
1082 // No changes were previously detected, so check for new changes
1083 return getThreadEvent(false);
1088 * waitForStatusChange
1090 * Blocks waiting for a change to occur in the running status of a child
1091 * process. Returns true upon success, false upon failure.
1093 * This function is declared as a friend of BPatch_thread so that it can use
1094 * the BPatch_thread::getThreadEvent call to check for status changes.
1096 bool BPatch::waitForStatusChange()
1098 if (havePendingEvent()) {
1102 // No changes were previously detected, so wait for a new change
1103 return getThreadEvent(true);
1109 * This function is a wrapper for the BPatch_type constructors for API/User
1112 * It returns a pointer to a BPatch_type that was added to the APITypes
1115 BPatch_type * BPatch::createEnumInt( const char * name,
1116 BPatch_Vector<char *> elementNames,
1117 BPatch_Vector<int> elementIds)
1120 if (elementNames.size() != elementIds.size()) {
1124 BPatch_fieldListType * newType = new BPatch_typeEnum(name);
1125 if (!newType) return NULL;
1127 APITypes->addType(newType);
1129 // ADD components to type
1130 for (unsigned int i=0; i < elementNames.size(); i++) {
1131 newType->addField(elementNames[i], elementIds[i]);
1141 * This function is a wrapper for the BPatch_type constructors for API/User
1142 * created types. The user has left element id specification to us
1144 * It returns a pointer to a BPatch_type that was added to the APITypes
1147 BPatch_type * BPatch::createEnumAutoId( const char * name,
1148 BPatch_Vector<char *> elementNames)
1150 BPatch_fieldListType * newType = new BPatch_typeEnum(name);
1152 if (!newType) return NULL;
1154 APITypes->addType(newType);
1156 // ADD components to type
1157 for (unsigned int i=0; i < elementNames.size(); i++) {
1158 newType->addField(elementNames[i], i);
1167 * This function is a wrapper for the BPatch_type constructors for API/User
1170 * It returns a pointer to a BPatch_type that was added to the APITypes
1174 BPatch_type * BPatch::createStructInt( const char * name,
1175 BPatch_Vector<char *> fieldNames,
1176 BPatch_Vector<BPatch_type *> fieldTypes)
1182 if (fieldNames.size() != fieldTypes.size()) {
1186 //Compute the size of the struct
1187 for (i=0; i < fieldNames.size(); i++) {
1188 BPatch_type *type = fieldTypes[i];
1189 size = type->getSize();
1193 BPatch_fieldListType *newType = new BPatch_typeStruct(name);
1194 if (!newType) return NULL;
1196 APITypes->addType(newType);
1198 // ADD components to type
1200 for (i=0; i < fieldNames.size(); i++) {
1201 BPatch_type *type = fieldTypes[i];
1202 size = type->getSize();
1203 newType->addField(fieldNames[i], type->getDataClass(), type, offset, size);
1205 // Calculate next offset (in bits) into the struct
1206 offset += (size * 8);
1215 * This function is a wrapper for the BPatch_type constructors for API/User
1218 * It returns a pointer to a BPatch_type that was added to the APITypes
1222 BPatch_type * BPatch::createUnionInt( const char * name,
1223 BPatch_Vector<char *> fieldNames,
1224 BPatch_Vector<BPatch_type *> fieldTypes)
1227 int offset, size, newsize;
1228 offset = size = newsize = 0;
1230 if (fieldNames.size() != fieldTypes.size()) {
1234 // Compute the size of the union
1235 for (i=0; i < fieldTypes.size(); i++) {
1236 BPatch_type *type = fieldTypes[i];
1237 newsize = type->getSize();
1238 if(size < newsize) size = newsize;
1241 BPatch_fieldListType * newType = new BPatch_typeUnion(name);
1242 if (!newType) return NULL;
1244 APITypes->addType(newType);
1246 // ADD components to type
1247 for (i=0; i < fieldNames.size(); i++) {
1248 BPatch_type *type = fieldTypes[i];
1249 size = type->getSize();
1250 newType->addField(fieldNames[i], type->getDataClass(), type, offset, size);
1257 * createArray for Arrays and SymTypeRanges
1259 * This function is a wrapper for the BPatch_type constructors for API/User
1262 * It returns a pointer to a BPatch_type that was added to the APITypes
1265 BPatch_type * BPatch::createArrayInt( const char * name, BPatch_type * ptr,
1266 unsigned int low, unsigned int hi)
1269 BPatch_type * newType;
1274 newType = new BPatch_typeArray(ptr, low, hi, name);
1275 if (!newType) return NULL;
1278 APITypes->addType(newType);
1284 * createPointer for BPatch_pointers
1286 * This function is a wrapper for the BPatch_type constructors for API/User
1289 * It returns a pointer to a BPatch_type that was added to the APITypes
1292 BPatch_type * BPatch::createPointerInt(const char * name, BPatch_type * ptr,
1296 BPatch_type * newType = new BPatch_typePointer(ptr, name);
1297 if(!newType) return NULL;
1299 APITypes->addType(newType);
1305 * createScalar for scalars with a size and no range
1307 * This function is a wrapper for the BPatch_type constructors for API/User
1310 * It returns a pointer to a BPatch_type that was added to the APITypes
1314 BPatch_type * BPatch::createScalarInt( const char * name, int size)
1316 BPatch_type * newType = new BPatch_typeScalar(size, name);
1317 if (!newType) return NULL;
1319 APITypes->addType(newType);
1325 * createType for typedefs
1327 * This function is a wrapper for the BPatch_type constructors for API/User
1330 * It returns a pointer to a BPatch_type that was added to the APITypes
1333 BPatch_type * BPatch::createTypedefInt( const char * name, BPatch_type * ptr)
1335 BPatch_type * newType = new BPatch_typeTypedef(ptr, name);
1337 if (!newType) return NULL;
1339 APITypes->addType(newType);
1344 bool BPatch::waitUntilStopped(BPatch_thread *appThread){
1345 while (!appThread->isStopped() && !appThread->isTerminated())
1346 this->waitForStatusChange();
1348 if (!appThread->isStopped())
1350 cerr << "ERROR : process did not signal mutator via stop"
1354 #if defined(i386_unknown_nt4_0) || \
1355 defined(mips_unknown_ce2_11)
1356 else if((appThread->stopSignal() != EXCEPTION_BREAKPOINT) &&
1357 (appThread->stopSignal() != -1))
1359 cerr << "ERROR : process stopped on signal different"
1360 << " than SIGTRAP" << endl;
1364 else if ((appThread->stopSignal() != SIGSTOP) &&
1365 #if defined(bug_irix_broken_sigstop)
1366 (appThread->stopSignal() != SIGEMT) &&
1368 (appThread->stopSignal() != SIGHUP)) {
1369 cerr << "ERROR : process stopped on signal "
1370 << "different than SIGSTOP" << endl;
1377 #ifdef IBM_BPATCH_COMPAT
1380 * Register a function to call when an RPC (i.e. oneshot) is done.
1382 * dyninst version is a callback that is defined for BPatch_thread
1385 BPatchThreadEventCallback BPatch::registerRPCTerminationCallbackInt(BPatchThreadEventCallback func)
1387 BPatchThreadEventCallback ret;
1389 ret = RPCdoneCallback;
1390 RPCdoneCallback = func;
1395 void setLogging_NP(BPatchLoggingCallback, int)
1400 int BPatch::getLastErrorCodeInt()
1404 BPatchThreadEventCallback BPatch::registerDetachDoneCallbackInt(BPatchThreadEventCallback)
1408 BPatchThreadEventCallback BPatch::registerSnippetRemovedCallbackInt(BPatchThreadEventCallback)
1415 * BPatch::launchDeferredOneTimeCode
1417 * Launch any deferred oneTimeCode calls (aka inferior RPCs) that might exist,
1418 * if it is now okay to do so.
1420 void BPatch::launchDeferredOneTimeCode()
1422 for (unsigned int p = 0; p < processVec.size(); p++) {
1423 process *proc = processVec[p];
1428 if (!proc->isAttached() ||
1429 proc->status() == neonatal)
1432 proc->getRpcMgr()->launchRPCs(proc->status() == running);
1436 BPatch_stats &BPatch::getBPatchStatisticsInt()
1441 // updateStats() -- an internal function called before returning
1442 // statistics buffer to caller of BPatch_getStatistics(),
1443 // -- just copies global variable statistics counters into
1444 // the buffer which is returned to the user.
1445 void BPatch::updateStats()
1447 stats.pointsUsed = pointsUsed;
1448 stats.totalMiniTramps = totalMiniTramps;
1449 stats.trampBytes = trampBytes;
1450 stats.ptraceOtherOps = ptraceOtherOps;
1451 stats.ptraceOps = ptraceOps;
1452 stats.ptraceBytes = ptraceBytes;
1453 stats.insnGenerated = insnGenerated;