2 * Copyright (c) 1996 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.
43 * process.h - interface to manage a process in execution. A process is a kernel
44 * visible unit with a seperate code and data space. It might not be
45 * the only unit running the code, but it is only one changed when
46 * ptrace updates are applied to the text space.
54 #include "rtinst/h/rtinst.h"
56 #include "util/h/String.h"
57 #include "util/h/vectorSet.h"
58 #include "util/h/Dictionary.h"
59 #include "util/h/Types.h"
60 #include "util/h/Timer.h"
64 #include "dyninstRPC.xdr.h"
65 #include "showerror.h"
67 #include "symtab.h" // internalSym
70 #include "fastInferiorHeapMgr.h"
71 #include "fastInferiorHeap.h"
72 #include "fastInferiorHeapHKs.h"
73 #ifdef sparc_sun_sunos4_1_3
79 #include "sharedobject.h"
80 #include "dynamiclinking.h"
82 extern unsigned activeProcesses; // number of active processes
83 // how about just processVec.size() instead? At least, this should be made
84 // a (static) member vrble of class process
91 // TODO a kludge - to prevent recursive includes
94 typedef enum { neonatal, running, stopped, exited } processState;
95 typedef enum { HEAPfree, HEAPallocated } heapStatus;
96 typedef enum { textHeap=0, dataHeap=1 } inferiorHeapType;
97 typedef vector<unsigned> unsigVecType;
102 addr =0; length = 0; status = HEAPfree;
104 heapItem(const heapItem *h) {
105 addr = h->addr; length = h->length; status = h->status;
113 // an item on the heap that we are trying to free.
117 disabledItem() { pointer = 0; }
118 disabledItem(unsigned iPointer, inferiorHeapType iHeapType, const vector<unsigVecType> &iPoints) : pointsToCheck(iPoints) {
120 whichHeap = iHeapType;
122 disabledItem(const disabledItem &src) : pointsToCheck(src.pointsToCheck) {
123 pointer = src.pointer;
124 whichHeap = src.whichHeap;
127 disabledItem &operator=(const disabledItem &src) {
128 if (&src == this) return *this; // the usual check for x=x
130 pointer = src.pointer;
131 whichHeap = src.whichHeap;
132 pointsToCheck = src.pointsToCheck;
136 unsigned getPointer() const {return pointer;}
137 inferiorHeapType getHeapType() const {return whichHeap;}
138 const vector<unsigVecType> &getPointsToCheck() const {return pointsToCheck;}
139 vector<unsigVecType> &getPointsToCheck() {return pointsToCheck;}
142 unsigned pointer; // address in heap
143 inferiorHeapType whichHeap; // which heap is it in
144 vector<unsigVecType> pointsToCheck; // range of addrs to check
150 inferiorHeap(): heapActive(addrHash16) {
151 freed = 0; disabledListTotalMem = 0; totalFreeMemAvailable = 0;
153 inferiorHeap(const inferiorHeap &src); // create a new heap that is a copy of src.
155 dictionary_hash<unsigned, heapItem*> heapActive; // active part of heap
156 vector<heapItem*> heapFree; // free block of data inferior heap
157 vector<disabledItem> disabledList; // items waiting to be freed.
158 int disabledListTotalMem; // total size of item waiting to free
159 int totalFreeMemAvailable; // total free memory in the heap
160 int freed; // total reclaimed (over time)
164 static inline unsigned ipHash(instPoint * const &ip)
166 // assume all addresses are 4-byte aligned
167 unsigned result = (unsigned)ip;
170 // how about %'ing by a huge prime number? Nah, x % y == x when x < y
171 // so we don't want the number to be huge.
175 static inline unsigned instInstanceHash(instInstance * const &inst) {
176 unsigned result = (unsigned)inst;
178 return result; // how about %'ing by a huge prime number?
179 // return ((unsigned)inst);
186 friend class ptraceKludge;
189 process(int iPid, image *iImage, int iTraceLink, int iIoLink
191 , key_t theShmSegKey,
192 const vector<fastInferiorHeapMgr::oneHeapStats> &iShmHeapStats
195 // this is the "normal" ctor
197 process(int iPid, image *iSymbols,
198 int afterAttach // 1 --> pause, 2 --> run, 0 --> leave as is
200 , key_t theShmSegKey,
201 const vector<fastInferiorHeapMgr::oneHeapStats> &iShmHeapStats
204 // this is the "attach" ctor
206 process(const process &parentProc, int iPid, int iTrace_fd
208 , key_t theShmSegKey,
210 const vector<fastInferiorHeapMgr::oneHeapStats> &iShmHeapStats
213 // this is the "fork" ctor
216 void registerInferiorAttachedSegs(void *inferiorAttachedAtPtr);
217 // Where the inferior attached was left undefined in the constructor;
218 // this routine fills it in (tells paradynd where, in the inferior proc's addr
219 // space, the shm seg was attached. The attaching was done in DYNINSTinit)
222 vector<Address> walkStack(bool noPause=false);
225 // getActiveFrame and readDataFromFrame are platform dependant
227 bool getActiveFrame(int *fp, int *pc);
228 bool readDataFromFrame(int currentFP, int *previousFP, int *rtn,
229 bool uppermost=false);
233 unsigned long long getInferiorProcessCPUtime() const;
234 // returns user+sys time from the u or proc area of the inferior process, which in
235 // turn is presumably obtained by mmapping it (sunos) or by using a /proc ioctl
236 // to obtain it (solaris). It is hoped that the implementation would not have to
237 // pause the inferior process (and then unpause it) in order to obtain the result,
238 // since pausing and unpausing are extremely slow (I've seen ~70ms).
241 processState status() const { return status_;}
242 string getStatusAsString() const; // useful for debug printing etc.
244 void continueAfterNextStop() { continueAfterNextStop_ = true; }
248 // the following 2 vrbles probably belong in a different class:
249 static string programName; // the name of paradynd (more specifically, its argv[0])
250 static vector<string> arg_list; // the arguments of paradynd
252 internalSym *findInternalSymbol(const string &name, bool warn) {
254 return symbols->findInternalSymbol(name, warn);
256 Address findInternalAddress(const string &name, bool warn, bool &err) const {
258 return symbols->findInternalAddress(name, warn, err);
263 bool symbol_info(const string &name, Symbol &ret) {
265 return symbols->symbol_info(name, ret);
267 image *getImage() const {
273 struct inferiorRPCtoDo {
274 // This structure keeps track of an inferiorRPC that we will start sometime
275 // in the (presumably near) future. There is a different structure for RPCs
276 // which have been launched and which we're waiting to finish. Don't confuse
280 bool noCost; // if true, cost model isn't updated by generated code.
281 void (*callbackFunc)(process *, void *userData, unsigned result);
284 vectorSet<inferiorRPCtoDo> RPCsWaitingToStart;
286 struct inferiorRPCinProgress {
287 // This structure keeps track of an inferiorRPC that has been launched and
288 // for which we're waiting to complete. Don't confuse with 'inferiorRPCtoDo',
289 // which is more of a wait queue of RPCs to start launching.
290 // Also note: It's only safe for 1 RPC to be in progress at a time.
291 // If you _really_ want to launch multiple RPCs at the same time, it's actually
292 // easy to do...just do one inferiorRPC with a sequenceNode AST! (neat, eh?)
293 // (Admittedly, that does confuse the semantics of callback functions. So
294 // the official line remains: only 1 inferior RPC per process can be ongoing.)
295 void (*callbackFunc)(process *, void *userData, unsigned result);
298 void *savedRegs; // crucial!
300 bool wasRunning; // were we running when we launched the inferiorRPC?
302 unsigned firstInstrAddr; // start location of temp tramp
304 unsigned stopForResultAddr;
305 // location of the TRAP or ILL which marks point where paradynd should grab the
306 // result register. Undefined if no callback fn.
307 unsigned justAfter_stopForResultAddr; // undefined if no callback fn.
308 reg resultRegister; // undefined if no callback fn.
310 unsigned resultValue; // undefined until we stop-for-result, at which time we
311 // fill this in. The callback fn (which takes in this value)
312 // isn't invoked until breakAddr (the final break)
315 // location of the TRAP or ILL insn which marks the end of the inferiorRPC
317 vectorSet<inferiorRPCinProgress> currRunningRPCs;
318 // see para above for reason why this 'vector' can have at most 1 elem!
321 bool deferredContinueProc;
322 void postRPCtoDo(AstNode *, bool noCost,
323 void (*)(process *, void *, unsigned), void *);
324 bool existsRPCreadyToLaunch() const;
325 bool existsRPCinProgress() const;
326 bool launchRPCifAppropriate(bool wasRunning);
327 // returns true iff anything was launched.
328 // asynchronously launches iff RPCsWaitingToStart.size() > 0 AND
329 // if currRunningRPCs.size()==0 (the latter for safety)
330 // If we're gonna launch, then we'll stop the process (a necessity).
331 // Pass wasRunning as true iff you want the process to continue after
332 // receiving the TRAP signifying completion of the RPC.
334 bool handleTrapIfDueToRPC();
335 // look for curr PC reg value in 'trapInstrAddr' of 'currRunningRPCs'. Return
336 // true iff found. Also, if true is being returned, then additionally does
337 // a 'launchRPCifAppropriate' to fire off the next waiting RPC, if any.
340 // The follwing 5 routines are implemented in an arch-specific .C file
341 bool emitInferiorRPCheader(void *, unsigned &base);
342 bool emitInferiorRPCtrailer(void *, unsigned &base,
343 unsigned &breakOffset,
345 unsigned &stopForResultOffset,
346 unsigned &justAfter_stopForResultOffset);
348 unsigned createRPCtempTramp(AstNode *action,
349 bool noCost, bool careAboutResult,
351 unsigned &stopForResultAddr,
352 unsigned &justAfter_stopForResultAddr,
355 // The parameter syscall is only used for hpux platform right now
356 // Can "syscall" be embedded into the opaque type?
357 void *getRegisters(bool &syscall);
358 // ptrace-GETREGS and ptrace-GETFPREGS. Result is returned in an opaque type
359 // which is allocated with new[]
361 bool changePC(unsigned addr,
362 const void *savedRegs // returned by getRegisters()
364 bool changePC(unsigned addr);
366 bool restoreRegisters(void *buffer);
367 // input is the opaque type returned by getRegisters()
369 unsigned read_inferiorRPC_result_register(reg);
372 void installBootstrapInst();
373 void installInstrRequests(const vector<instMapping*> &requests);
375 // These member vrbles should be made private!
376 int traceLink; /* pipe to transfer traces data over */
377 int ioLink; /* pipe to transfer stdout/stderr over */
378 processState status_; /* running, stopped, etc. */
379 vector<Thread *> threads; /* threads belonging to this process */
380 bool continueAfterNextStop_;
381 // on some platforms we use one heap for text and data so textHeapFree is not
383 bool splitHeaps; /* are the inferior heap split I/D ? */
384 inferiorHeap heaps[2]; /* the heaps text and data */
385 resource *rid; /* handle to resource for this process */
387 /* map an inst point to its base tramp */
388 dictionary_hash<const instPoint*, trampTemplate *> baseMap;
390 // the following 3 are used in perfStream.C
395 time64 wallTimeLastTrampSample;
396 time64 timeLastTrampSample;
398 bool reachedFirstBreak; // should be renamed 'reachedInitialTRAP'
400 int getPid() const { return pid;}
402 void initInferiorHeap(bool textHeap);
403 // true --> text heap, else data heap
405 bool writeDataSpace(void *inTracedProcess,
406 int amount, const void *inSelf);
407 bool readDataSpace(const void *inTracedProcess, int amount,
408 void *inSelf, bool displayErrMsg);
410 bool writeTextSpace(void *inTracedProcess, int amount, const void *inSelf);
411 bool writeTextWord(caddr_t inTracedProcess, int data);
415 bool dumpCore(const string coreFile);
416 bool detach(const bool paused); // why the param?
418 string getProcessStatus() const;
420 static string tryToFindExecutable(const string &progpath, int pid);
421 // os-specific implementation. Returns empty string on failure.
422 // Otherwise, returns a full-path-name for the file. Tries every
423 // trick to determine the full-path-name, even though "progpath" may
424 // be unspecified (empty string)
426 bool continueWithForwardSignal(int sig); // arch-specific implementation
428 // forkProcess: this function should be called when a process we are tracing
429 // forks a child process.
430 // This function returns a new process object associated with the child.
431 // It also writes to "map" s.t. for each instInstance in the parent, we have the
432 // corresponding instInstance in the child.
433 static process *forkProcess(const process *parent, pid_t childPid,
434 dictionary_hash<instInstance*,instInstance*> &map,
438 void *applAttachedAtPtr
442 // get and set info. specifying if this is a dynamic executable
443 void setDynamicLinking(){ dynamiclinking = true;}
444 bool isDynamicallyLinked() { return (dynamiclinking); }
446 // handleStartProcess: this function is called when an appplication
447 // starts executing. It is used to insert instrumentation necessary
448 // to handle dynamic linking
449 static bool handleStartProcess(process *pid);
451 bool handleStopDueToExecEntry();
453 // getSharedObjects: This routine is called before main() to get and
454 // process all shared objects that have been mapped into the process's
456 bool getSharedObjects();
458 // addASharedObject: This routine is called whenever a new shared object
459 // has been loaded by the run-time linker after the process starts running
460 // It processes the image, creates new resources
461 bool addASharedObject(shared_object &);
463 // findOneFunction: returns the function associated with function "func"
464 // and module "mod". This routine checks both the a.out image and any
465 // shared object images for this function
466 pdFunction *findOneFunction(resource *func,resource *mod);
468 // findOneFunction: returns the function associated with function "func_name"
469 // This routine checks both the a.out image and any shared object images
471 pdFunction *findOneFunction(const string &func_name);
473 // findFunctionIn: returns the function which contains this address
474 // This routine checks both the a.out image and any shared object images
476 pdFunction *findFunctionIn(Address adr);
478 // findModule: returns the module associated with "mod_name"
479 // this routine checks both the a.out image and any shared object
480 // images for this module
481 module *findModule(const string &mod_name);
483 // getSymbolInfo: get symbol info of symbol associated with name n
484 // this routine starts looking a.out for symbol and then in shared objects
485 bool getSymbolInfo(string &n, Symbol &info);
487 // getAllFunctions: returns a vector of all functions defined in the
488 // a.out and in the shared objects
489 vector<pdFunction *> *getAllFunctions();
491 // getAllModules: returns a vector of all modules defined in the
492 // a.out and in the shared objects
493 vector<module *> *getAllModules();
495 // getIncludedFunctions: returns a vector of all functions defined in the
496 // a.out and in shared objects that are not excluded by an mdl option
497 vector<pdFunction *> *getIncludedFunctions();
499 // getIncludedModules: returns a vector of all functions defined in the
500 // a.out and in shared objects that are not excluded by an mdl option
501 vector<module *> *getIncludedModules();
503 // getBaseAddress: sets baseAddress to the base address of the
504 // image corresponding to which. It returns true if image is mapped
505 // in processes address space, otherwise it returns 0
506 bool getBaseAddress(const image *which, u_int &baseAddress);
508 // these routines are for testing, setting, and clearing the
509 // waiting_for_resources flag, if this flag is true a process is not
510 // started until all outstanding resourceInfoResponses have been received
511 void setWaitingForResources(){ waiting_for_resources = true; }
512 // called by perfStream.C on SIGSTOP if there are any
513 // resource::num_outstanding_creates,
514 // and process::handleStartProcess, also if there are any
515 // resource::num_outstanding_creates.
516 void clearWaitingForResources(){ waiting_for_resources = false; }
517 bool isWaitingForResources(){ return(waiting_for_resources); }
519 // findSignalHandler: if signal_handler is 0, then it checks all images
520 // associtated with this process for the signal handler function.
521 // Otherwise, the signal handler function has already been found
522 void findSignalHandler();
524 // continueProcessIfWaiting: if the waiting_for_resources flag
525 // is set then continue the process; in any event, clear that flag
526 void continueProcessIfWaiting(){
527 if(waiting_for_resources){
530 waiting_for_resources = false;
533 // wasExeced: returns true is the process did an exec...this is set
535 bool wasExeced(){ return execed_;}
538 bool cleanUpInstrumentation(bool wasRunning); // called on exit (also exec?)
543 int getProcFileDescriptor(){ return proc_fd;}
545 static int waitProcs(int *status);
546 const process *getParent() const {return parent;}
548 #if defined(hppa1_1_hp_hpux)
553 key_t getShmKeyUsed() const {return inferiorHeapMgr.getShmKey();}
554 bool doMajorShmSample(unsigned long long currWallTime);
555 bool doMinorShmSample();
557 const fastInferiorHeap<intCounterHK, intCounter> &getInferiorIntCounters() const {
558 return inferiorIntCounters;
560 const fastInferiorHeap<wallTimerHK, tTimer> &getInferiorWallTimers() const {
561 return inferiorWallTimers;
563 const fastInferiorHeap<processTimerHK, tTimer> &getInferiorProcessTimers() const {
564 return inferiorProcessTimers;
567 fastInferiorHeap<intCounterHK, intCounter> &getInferiorIntCounters() {
568 return inferiorIntCounters;
570 fastInferiorHeap<wallTimerHK, tTimer> &getInferiorWallTimers() {
571 return inferiorWallTimers;
573 fastInferiorHeap<processTimerHK, tTimer> &getInferiorProcessTimers() {
574 return inferiorProcessTimers;
577 unsigned getShmHeapTotalNumBytes() {
578 return inferiorHeapMgr.getHeapTotalNumBytes();
581 void *getObsCostLowAddrInApplicSpace() {
582 void *result = inferiorHeapMgr.getObsCostAddrInApplicSpace();
585 unsigned *getObsCostLowAddrInParadyndSpace() {
586 unsigned *result = inferiorHeapMgr.getObsCostAddrInParadyndSpace();
589 void processCost(unsigned obsCostLow,
590 unsigned long long wallTime, unsigned long long processTime);
593 #ifdef sparc_sun_sunos4_1_3
594 static user *tryToMapChildUarea(int pid);
597 #endif /* shm_sampling */
599 bool isBootstrappedYet() const {
600 return hasBootstrapped;
602 bool extractBootstrapStruct(DYNINST_bootstrapStruct *);
603 int procStopFromDYNINSTinit();
604 // returns 0 if not processed, 1 for the usual processed case (process is
605 // now paused), or 2 for the processed-but-still-running-inferiorRPC case
607 void handleCompletionOfDYNINSTinit(bool fromAttach);
608 // called by above routine. Reads bs_record from applic, takes action.
610 static void DYNINSTinitCompletionCallback(process *, void *, unsigned);
611 // inferiorRPC callback routine.
614 // Since we don't define these, 'private' makes sure they're not used:
615 process(const process &); // copy ctor
616 process &operator=(const process &); // assign oper
618 bool hasBootstrapped;
619 // set to true when we get callback from inferiorRPC call to DYNINSTinit
621 const process *parent; /* parent of this proces */
622 image *symbols; /* information related to the process */
623 int pid; /* id of this process */
626 // New components of the conceptual "inferior heap"
627 fastInferiorHeapMgr inferiorHeapMgr;
628 fastInferiorHeap<intCounterHK, intCounter> inferiorIntCounters;
629 fastInferiorHeap<wallTimerHK, tTimer> inferiorWallTimers;
630 fastInferiorHeap<processTimerHK, tTimer> inferiorProcessTimers;
632 #ifdef sparc_sun_sunos4_1_3
640 trampTableEntry trampTable[TRAMPTABLESZ];
641 unsigned trampTableItems;
643 unsigned currentPC() {
647 else if (getActiveFrame(&fp, &pc)) {
648 currentPC_ = (unsigned) pc;
654 void setNewPC(unsigned newPC) {
659 inline int costAddr() const { return costAddr_; } // why an integer?
660 void getObservedCostAddr();
663 bool createdViaAttach;
664 // set in the ctor. True iff this process was created with an attach,
665 // as opposed to being fired up by paradynd. On fork, has the value of
666 // the parent process. On exec, no change.
667 // This vrble is important because it tells us what to do when we exit.
668 // If we created via attach, we should (presumably) detach but not fry
669 // the application; otherwise, a kill(pid, 9) is called for.
670 // the following 2 are defined only if 'createdViaAttach' is true; action is taken
671 // on these vrbles once DYNINSTinit completes.
673 bool wasRunningWhenAttached;
674 bool needToContinueAfterDYNINSTinit;
679 // for processing observed cost (see method processCost())
680 unsigned long long cumObsCost; // in cycles
681 unsigned lastObsCostLow; // in cycles
683 int costAddr_; // why an integer?
684 bool execed_; // true if this process does an exec...set in handleExec
686 // deal with system differences for ptrace
687 bool writeDataSpace_(void *inTracedProcess, int amount, const void *inSelf);
688 bool readDataSpace_(const void *inTracedProcess, int amount, void *inSelf);
690 bool writeTextWord_(caddr_t inTracedProcess, int data);
691 bool writeTextSpace_(void *inTracedProcess, int amount, const void *inSelf);
693 bool continueProc_();
694 bool dumpCore_(const string coreFile);
696 bool attach_(); // low-level attach; called by attach() (formerly OS::osAttach())
697 bool stop_(); // formerly OS::osStop
700 bool loopUntilStopped();
702 // returns true iff ok to do a ptrace; false (and prints a warning) if not
705 int proc_fd; // file descriptor for platforms that use /proc file system.
707 dynamic_linking *dyn; // platform specific dynamic linking routines & data
709 bool dynamiclinking; // if true this a.out has a .dynamic section
710 vector<shared_object *> *shared_objects; // list of dynamically linked libs
712 // The set of all functions and modules in the a.out and in the shared objects
713 vector<pdFunction *> *all_functions;
714 vector<module *> *all_modules;
715 // these are a restricted set of functions and modules which are those
716 // from shared objects that are not excluded through an mdl "exclude_library"
717 // option: these are used to satisfy foci that are not refined on the
719 vector<module *> *some_modules;
720 vector<pdFunction *> *some_functions;
721 bool waiting_for_resources; // true if waiting for resourceInfoResponse
722 pdFunction *signal_handler; // signal handler function (for stack walking)
724 // needToAddALeafFrame: returns true if the between the current frame
725 // and the next frame there is a leaf function (this occurs when the
726 // current frame is the signal handler)
727 bool needToAddALeafFrame(Frame current_frame, Address &leaf_pc);
729 bool isRunning_() const;
730 // needed to initialize the 'wasRunningWhenAttached' member vrble. Determines
731 // whether the process is running by doing a low-level OS check, not by checking
732 // member vrbles like status_. May assume that process::attach() has already run,
733 // but can't assume anything else. May barf with a not-yet-implemented error on a
734 // given platform if the platform doesn't yet support attaching to a running process.
735 // But there's no reason why we shouldn't be able to implement this on any platform;
736 // after all, the output from the "ps" command can be used (T --> return false,
737 // S or R --> return true, other --> return ?)
739 #if defined(sparc_sun_solaris2_4) || defined(i386_unknown_solaris2_5)
740 // some very useful items gathered from /proc (initialized in attach() [solaris.C],
741 // as soon as /proc fd is opened)
742 string argv0; // argv[0] of program, at the time it started up
743 string pathenv; // path env var of program, at the time it started up
744 string cwdenv; // curr working directory of program, at the time it started up
746 // string fullPathToExecutable_;
747 // very useful, especially on attach (need this to parse the symbol table)
750 const string &getArgv0() const {return argv0;}
751 const string &getPathEnv() const {return pathenv;}
752 const string &getCwdEnv() const {return cwdenv;}
756 process *createProcess(const string file, vector<string> argv, vector<string> envp, const string dir);
757 bool attachProcess(const string &progpath, int pid, int afterAttach);
759 void handleProcessExit(process *p, int exitStatus);
761 unsigned inferiorMalloc(process *proc, int size, inferiorHeapType type);
762 void inferiorFree(process *proc, unsigned pointer, inferiorHeapType type,
763 const vector<unsigVecType> &pointsToCheck);
765 extern resource *machineResource;
775 // formerly getActiveStackFrameInfo
777 Frame(int theFrame, int thePc, bool theUppermost) {
778 frame_ = theFrame; pc_ = thePc;
779 uppermostFrame = theUppermost;
782 int getPC() const { return pc_; }
783 int getFramePtr(){ return frame_;}
784 bool isLastFrame() const {
785 if ((pc_ == 0)||(frame_ == 0))
791 Frame getPreviousStackFrameInfo(process *proc) const;
794 extern vector<process *> processVec;
796 #define CT_BLOCK_SIZE 300
800 CT(process *pproc) : CTvectorAddr(0), CTvectorSize(0), CTmapTable(CThash)
804 unsigned size() { return(CTvectorSize); }
805 bool update(unsigned tableAddr);
806 void add(unsigned CTid, unsigned &position);
807 void remove(unsigned CTid, unsigned position);
808 void dup(unsigned CTid, unsigned mid, Thread *thr, unsigned &position);
809 unsigned getCTmapId(unsigned mid)
811 assert(CTmapTable.defines(mid));
812 return(CTmapTable[mid]);
814 unsigned getCTusagePos(unsigned position) {
815 assert(position < CTusage.size());
816 return(CTusage[position]);
819 unsigned CTvectorAddr;
820 unsigned CTvectorSize;
821 dictionary_hash<unsigned, unsigned> CTmapTable;
829 // This definition must be completed later when we get the result of a call
830 // to thr_self in the application. We are assuming that
831 // 0 <= thr_self,tid < MAX_NUMBER_OF_THREADS - naim
832 Thread(process *pproc) : tid(0), pos(0), rid(NULL)
835 ppid = pproc->getPid();
836 CTvector = new CT(proc);
838 Thread(process *proc_, int tid_, int pos_, resource *rid_ )
841 ppid = proc_->getPid();
845 CTvector = new CT(proc_);
846 //assert(tid>=0 && tid<MAX_NUMBER_OF_THREADS);
852 int get_tid() { return(tid); }
853 unsigned get_pos() { return(pos); }
854 void update_tid(int id, int p) { tid = id; pos = p; }
855 int get_ppid() { return(ppid); }
856 resource *get_rid() { return(rid); }
857 process *get_proc() { return(proc); }