Fixes for accessing local variable via StackwalkerAPI
[dyninst.git] / stackwalk / src / procstate.C
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
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.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 #include "stackwalk/h/swk_errors.h"
33 #include "stackwalk/h/procstate.h"
34 #include "stackwalk/src/libstate.h"
35 #include "common/h/headers.h"
36 #include <assert.h>
37 #include <string>
38 #include <vector>
39
40 using namespace Dyninst;
41 using namespace Dyninst::Stackwalker;
42 using namespace std;
43
44 class DefaultLibState : public LibraryState
45 {
46 public:
47    DefaultLibState(ProcessState *parent) : 
48       LibraryState(parent) 
49    {
50    }
51
52    virtual bool getLibraryAtAddr(Address, LibAddrPair &) {
53       return false;
54    }
55
56    virtual bool getLibraries(std::vector<LibAddrPair> &) {
57       return false;
58    }
59
60    virtual void notifyOfUpdate() {
61    }
62
63    virtual Address getLibTrapAddress() {
64       return 0x0;
65    }
66
67    ~DefaultLibState() { 
68    }
69 };
70
71 std::map<Dyninst::PID, ProcessState *> ProcessState::proc_map;
72
73 ProcessState::ProcessState(Dyninst::PID pid_, std::string executable_path_) :
74    library_tracker(NULL),
75    executable_path(executable_path_)
76 {
77    std::map<PID, ProcessState *>::iterator i = proc_map.find(pid_);
78    if (i != proc_map.end())
79    {
80       sw_printf("[%s:%u] - Already attached to debuggee %d\n",
81                 __FILE__, __LINE__, pid_);
82       setLastError(err_badparam, "Attach requested to already " \
83                    "attached process");
84       return;
85    }
86    setPid(pid_);
87 }
88
89 void ProcessState::setPid(Dyninst::PID pid_)
90 {
91    pid = pid_;
92    proc_map[pid] = this;
93 }
94
95 Dyninst::PID ProcessState::getProcessId() 
96 {
97    return pid;
98 }
99
100 bool ProcessState::preStackwalk(Dyninst::THR_ID)
101 {
102    return true;
103 }
104
105 bool ProcessState::postStackwalk(Dyninst::THR_ID)
106 {
107    return true;
108 }
109
110 void ProcessState::setDefaultLibraryTracker()
111 {
112   if (library_tracker) return;
113
114   std::string execp = getExecutablePath();
115   library_tracker = new TrackLibState(this, execp);
116 }
117
118 Walker *ProcessState::getWalker() const
119 {
120    return walker;
121 }
122
123 ProcessState::~ProcessState()
124 {
125    if (library_tracker)
126       delete library_tracker;
127    proc_map.erase(pid);
128 }
129
130 int ProcDebug::pipe_in = -1;
131 int ProcDebug::pipe_out = -1;
132
133 ProcDebug::ProcDebug(PID p, string exe) : 
134   ProcessState(p, exe),
135   initial_thread(NULL),
136   active_thread(NULL),
137   sigfunc(NULL)
138 {
139   initial_thread = ThreadState::createThreadState(this);
140   threads[initial_thread->getTid()] = initial_thread;   
141 }
142
143 ProcDebug::ProcDebug(std::string executable, 
144                      const std::vector<std::string> & /*argv*/) : 
145    ProcessState(0, executable),
146    initial_thread(NULL),
147    active_thread(NULL),
148    sigfunc(NULL)
149 {
150 }
151
152 bool ProcDebug::create(string executable, 
153                        const vector<string> &argv)
154 {
155   bool result = debug_create(executable, argv);
156   if (!result) {
157     sw_printf("[%s:%u] - Could not create debuggee, %s\n",
158               __FILE__, __LINE__, executable.c_str());
159     return false;
160   }
161
162   setPid(pid);
163   initial_thread = ThreadState::createThreadState(this, NULL_THR_ID, true);
164
165   threads[initial_thread->getTid()] = initial_thread;   
166
167   sw_printf("[%s:%u] - Created debugged %s on pid %d\n",
168             __FILE__, __LINE__, executable.c_str(), pid);
169   result = debug_waitfor_create();
170   if (state() == ps_exited) {
171      sw_printf("[%s:%u] - Process %s exited during create\n", 
172                __FILE__, __LINE__, executable.c_str());
173     return false; 
174   }
175   if (!result) {
176     sw_printf("[%s:%u] - Error during process create for %d\n",
177               __FILE__, __LINE__, pid);
178     return false;
179   }
180   result = debug_post_create();
181     if (!result) {
182     sw_printf("[%s:%u] - Error during post create for %d\n",
183                 __FILE__, __LINE__, pid);
184       return false;
185     }
186      
187   assert(state() == ps_running);
188   
189   return true;
190 }
191
192 bool ProcDebug::debug_waitfor_create()
193 {
194   for (;;) {
195     bool handled, result;
196     
197     result = debug_wait_and_handle(true, false, handled);
198     if (!result || state() == ps_errorstate) {
199       sw_printf("[%s:%u] - Error.  Process %d errored during create\n",
200                 __FILE__, __LINE__, pid);
201       return false;
202     }
203     if (state() == ps_exited) {
204       sw_printf("[%s:%u] - Error.  Process %d exited during create\n",
205                 __FILE__, __LINE__, pid);
206       return false;
207     }
208     if (state() == ps_running) {
209       sw_printf("[%s:%u] - Successfully completed create on %d\n",
210                 __FILE__, __LINE__, pid);
211       return true;
212     }
213   }
214 }
215
216 bool ProcDebug::multi_attach(vector<ProcDebug *> &pids)
217 {
218    bool result;
219    bool had_error = false;
220    vector<ProcDebug *>::iterator i;
221
222 #define for_each_procdebug(func, cond, err_msg) \
223    for (i = pids.begin(); i != pids.end(); i++) { \
224       ProcDebug *pd = (*i); \
225       if (!pd) \
226         continue; \
227       if (!cond) \
228         continue; \
229       result = pd->func(pd->initial_thread); \
230       if (!result) { \
231          sw_printf("[%s:%u] - Could not %s to %d", __FILE__, __LINE__, err_msg, pd->pid); \
232          delete pd; \
233          *i = NULL; \
234          had_error = true; \
235       } \
236    }
237
238    for_each_procdebug(debug_attach, true, "attach");
239
240    for_each_procdebug(debug_waitfor_attach, true, "wait for attach");
241
242    for_each_procdebug(debug_post_attach, true, "post attach");
243
244    for_each_procdebug(debug_continue, (pd->state() != ps_running), "send continue");
245
246    return had_error;
247 }
248
249 bool ProcDebug::attach()
250 {
251   bool result = debug_attach(initial_thread);
252   if (!result) {
253     sw_printf("[%s:%u] - Could not attach to debuggee, %d\n",
254               __FILE__, __LINE__, pid);
255     return false;
256   }
257
258   result = debug_waitfor_attach(initial_thread);
259   if (!result) {
260      sw_printf("[%s:%u] - Error waiting for attach\n", __FILE__, __LINE__);
261      goto error;
262   }
263
264   result = debug_post_attach(initial_thread);
265   if (!result) {
266      sw_printf("[%s:%u] - Error on post attach for %d\n",
267                __FILE__, __LINE__, pid);
268      goto error;
269   }
270
271   if (state() != ps_running) {
272      result = debug_continue(initial_thread);
273      if (!result) {
274         sw_printf("[%s:%u] - Could not continue debuggee %d after attach\n",
275                   __FILE__, __LINE__, pid);
276         goto error;
277      }
278   }
279
280   return true;
281
282  error:
283   if (state() == ps_exited) {
284     setLastError(err_procexit, "Process exited unexpectedly during attach");
285   }
286   sw_printf("[%s:%u] - Error during process attach for %d\n",
287             __FILE__, __LINE__, pid);
288   return false;
289 }
290
291
292 bool ProcDebug::debug_waitfor_attach(ThreadState *ts)
293 {
294   Dyninst::THR_ID tid = ts->getTid();
295   for (;;) {
296     bool handled, result;
297
298     if (ts->state() == ps_exited) {
299       sw_printf("[%s:%u] - Error.  Thread %d/%d exited during attach\n",
300                 __FILE__, __LINE__, pid, tid);
301       return false;
302     }
303     if (ts->state() == ps_attached || ts->state() == ps_running)  {
304       sw_printf("[%s:%u] - Successfully completed attach on %d/%d\n",
305                 __FILE__, __LINE__, pid, tid);
306       return true;
307     }
308     
309     result = debug_wait_and_handle(true, false, handled);
310     if (!result || ts->state() == ps_errorstate) {
311       sw_printf("[%s:%u] - Error.  Thread %d/%d errored during attach\n",
312                 __FILE__, __LINE__, pid, tid);
313       return false;
314     }
315   }
316 }
317
318 bool ProcDebug::debug_post_attach(ThreadState *)
319 {
320    return true;
321 }
322
323 bool ProcDebug::debug_post_create()
324 {
325    return true;
326 }
327
328 bool ProcDebug::resume(Dyninst::THR_ID tid)
329 {
330    sw_printf("[%s:%u] - User is continuing process %d, thread %d\n",
331              __FILE__, __LINE__, pid, tid);
332    
333    ThreadState *thr = NULL;
334    if (tid != NULL_THR_ID) {
335       //Handle the case where we're being asked to continue one thread.
336       thread_map_t::iterator i = threads.find(tid);
337       if (i == threads.end()) {
338          sw_printf("[%s:%u] - Thread %d in process %d was not valid\n",
339                    __FILE__, __LINE__, tid, pid);
340          setLastError(err_badparam, "No such thread");
341          return false;
342       }
343       thr = (*i).second;
344       assert(thr);
345       if (thr->state() == ps_exited) {
346          sw_printf("[%s:%u] - Attempt to resume thread %d in proc %d that "
347                    "already exited\n", __FILE__, __LINE__, tid, pid);
348          setLastError(err_badparam, "Thread already exited");
349          return false;
350       }
351       if (!thr->isStopped()) {
352          sw_printf("[%s:%u] - thread %d is already running on process %d\n",
353                    __FILE__, __LINE__, tid, pid);
354          thr->setUserStopped(false);
355       }
356       else {
357          bool result = resume_thread(thr);
358          if (result) {
359             thr->setUserStopped(false);
360          }
361       }
362       return true;
363    }
364    
365    //Handle the case where we're continuing all threads
366    thread_map_t::iterator i;
367    bool had_error = false;
368    for (i = threads.begin(); i != threads.end(); i++) {
369       thr = (*i).second;
370       int thr_tid = thr->getTid();
371       assert(thr);
372       if (thr->state() == ps_exited) {
373          sw_printf("[%s:%u] - thread %d on process %d already exited\n",
374                 __FILE__, __LINE__, thr_tid, pid);
375          continue;
376       }
377       if (!thr->isStopped()) {
378          sw_printf("[%s:%u] - thread %d is already running on process %d\n",
379                    __FILE__, __LINE__, thr_tid, pid);
380          thr->setUserStopped(false);
381          continue;
382       }
383
384       sw_printf("[%s:%u] - Continuing thread %d on process %d\n",
385                 __FILE__, __LINE__, thr_tid, pid);
386       bool result = resume_thread(thr);
387       if (!result) {
388          sw_printf("[%s:%u] - Error resuming thread %d on process %d\n",
389                 __FILE__, __LINE__, thr_tid, pid);
390          had_error = true;
391       }
392       else {
393          thr->setUserStopped(false);
394       }
395    }
396    return !had_error;
397 }
398
399 bool ProcDebug::resume_thread(ThreadState *thr)
400 {
401    Dyninst::THR_ID tid = thr->getTid();
402    sw_printf("[%s:%u] - Top level resume for %d/%d\n",
403              __FILE__, __LINE__, pid, tid);
404    bool result = debug_continue(thr);
405    if (!result) {
406       sw_printf("[%s:%u] - Could not resume debugee %d, thread %d\n",
407                 __FILE__, __LINE__, pid, tid);
408       return false;
409    }
410
411    result = debug_waitfor_continue(thr);
412    if (state() == ps_exited) {
413       setLastError(err_procexit, "Process exited unexpectedly during continue");
414       return false; 
415    }
416    if (!result) {
417       sw_printf("[%s:%u] - Error during process resume for %d\n",
418                 __FILE__, __LINE__, pid);
419       return false;
420    }
421    
422    return true;
423 }
424
425 bool ProcDebug::debug_waitfor_continue(ThreadState *thr)
426 {
427   sw_printf("[%s:%u] - At debug_waitfor_continue, isStopped = %d\n",
428             __FILE__, __LINE__, (int) thr->isStopped());
429   while (thr->isStopped()) {
430     bool handled, result;
431     
432     result = debug_wait_and_handle(true, false, handled);
433     if (!result || state() == ps_errorstate) {
434       sw_printf("[%s:%u] - Error.  Process %d errored during continue\n",
435                 __FILE__, __LINE__, pid);
436       return false;
437     }
438     if (state() == ps_exited || thr->state() == ps_exited) {
439       sw_printf("[%s:%u] - Error.  Process %d exited during continue\n",
440                 __FILE__, __LINE__, pid);
441       return false;
442     }
443   }
444   sw_printf("[%s:%u] - Successfully continued %d/%d\n",
445             __FILE__, __LINE__, pid, thr->getTid());
446   return true;
447 }
448
449 bool ProcDebug::pause(Dyninst::THR_ID tid)
450 {
451    sw_printf("[%s:%u] - User is stopping process %d, thread %d\n",
452              __FILE__, __LINE__, pid, tid);
453    
454    ThreadState *thr = NULL;
455    if (tid != NULL_THR_ID) {
456       //Handle the case where we're being asked to stop one thread.
457       thread_map_t::iterator i = threads.find(tid);
458       if (i == threads.end()) {
459          sw_printf("[%s:%u] - Thread %d in process %d was not valid\n",
460                    __FILE__, __LINE__, tid, pid);
461          setLastError(err_badparam, "No such thread");
462          return false;
463       }
464       thr = (*i).second;
465       assert(thr);
466       if (thr->state() == ps_exited) {
467          sw_printf("[%s:%u] - Attempt to resume thread %d in proc %d that "
468                    "already exited\n", __FILE__, __LINE__, tid, pid);
469          setLastError(err_procexit, "Thread already exited");
470          return false;
471       }
472       bool result = true;
473       if (!thr->isStopped()) {
474          result = pause_thread(thr);
475          if (result) {
476             thr->setUserStopped(true);         
477          }
478       }
479       return result;
480    }
481    
482    //Handle the case where we're stopping all threads
483    thread_map_t::iterator i;
484    bool had_error = false;
485    for (i = threads.begin(); i != threads.end(); i++) {
486       thr = (*i).second;
487       assert(thr);
488       if (thr->state() == ps_exited) {
489          sw_printf("[%s:%u] - thread %d on process %d already exited\n",
490                 __FILE__, __LINE__, tid, pid);
491          continue;
492       }
493       sw_printf("[%s:%u] - Pausing thread %d on process %d\n",
494                 __FILE__, __LINE__, tid, pid);
495       if (!thr->isStopped()) {
496          bool result = pause_thread(thr);
497          if (!result) {
498             sw_printf("[%s:%u] - Error pausing thread %d on process %d\n",
499                       __FILE__, __LINE__, tid, pid);
500             had_error = true;
501             continue;
502          }
503       }
504       thr->setUserStopped(true);         
505    }
506    return !had_error;   
507 }
508
509 bool ProcDebug::pause_thread(ThreadState *thr)
510 {
511    Dyninst::THR_ID tid = thr->getTid();
512    sw_printf("[%s:%u] - Top level thread pause for %d/%d\n",
513              __FILE__, __LINE__, pid, tid);
514    if (thr->isStopped())
515    {
516       sw_printf("Thread already paused, returning\n");
517       return true;
518    }
519
520    bool result = debug_pause(thr);
521    if (!result) {
522       sw_printf("[%s:%u] - Could not pause debuggee %d, thr %d\n",
523                 __FILE__, __LINE__, pid, tid);
524     return false;
525   }
526   
527    result = debug_waitfor_pause(thr);
528    if (thr->state() == ps_exited) {
529     setLastError(err_procexit, "Process exited unexpectedly during pause");
530     return false; 
531   }
532   if (!result) {
533       sw_printf("[%s:%u] - Error during process pause for %d, thr %d\n",
534                 __FILE__, __LINE__, pid, tid);
535     return false;
536   }
537
538    assert(thr->isStopped());
539   return true;
540 }
541
542 bool ProcDebug::debug_waitfor_pause(ThreadState *thr)
543 {
544    Dyninst::THR_ID tid = thr->getTid();
545    sw_printf("[%s:%u] - Waiting for %d, %d to stop\n", __FILE__, __LINE__, pid, tid);
546    while (!thr->isStopped()) {
547       bool handled, result;
548       
549       result = debug_wait_and_handle(true, false, handled);
550       if (!result || thr->state() == ps_errorstate) {
551          sw_printf("[%s:%u] - Error.  Process %d, %d errored during pause\n",
552                    __FILE__, __LINE__, pid, tid);
553          return false;
554       }
555       if (thr->state() == ps_exited) {
556          sw_printf("[%s:%u] - Error.  Process %d, %d exited during pause\n",
557                    __FILE__, __LINE__, pid, tid);
558          return false;
559       }
560    }
561    sw_printf("[%s:%u] - Successfully stopped %d, %d\n", 
562              __FILE__, __LINE__, pid, tid);
563   return true;
564 }
565
566
567 bool ProcDebug::debug_waitfor(dbg_t event_type) {
568   bool handled;
569   dbg_t handled_type;
570   bool flush = false;
571 #if defined(os_linux)
572   flush = true;
573 #endif
574   while (debug_wait_and_handle(true, flush, handled, &handled_type)) {
575     if (handled_type == event_type) {
576       return true;
577     }
578   }
579   return false;
580 }
581
582
583 bool ProcDebug::debug_wait_and_handle(bool block, bool flush, bool &handled, 
584                                       dbg_t *event_type)
585 {
586   bool result;
587   handled = false;
588   
589   for (;;) {
590      DebugEvent ev = debug_get_event(block);
591
592      if (ev.dbg == dbg_noevent)
593      {
594         sw_printf("[%s:%u] - Returning from debug_wait_and_handle, %s.\n",
595                   __FILE__, __LINE__, handled ? "handled event" : "no event");
596         if (!handled && event_type) {
597            *event_type = dbg_noevent;
598         }
599         return true;
600      }
601      if (event_type) {
602         *event_type = ev.dbg;
603      }
604      if (ev.dbg == dbg_err)
605      {
606         sw_printf("[%s:%u] - Returning from debug_wait_and_handle with error\n",
607                   __FILE__, __LINE__);
608         return false;
609      }
610
611      sw_printf("[%s:%u] - Handling event for pid %d: dbg %d, data %d\n", 
612                __FILE__, __LINE__, ev.proc->pid, ev.dbg, ev.data.idata);
613      result = ev.proc->debug_handle_event(ev);
614      if (!result) {
615         sw_printf("[%s:%u] - debug_handle_event returned error for ev.dbg = %d, " \
616                   "ev.proc = %d\n", __FILE__, __LINE__, ev.dbg, ev.proc->pid);
617         handled = false;
618         return false;
619      }
620      
621      sw_printf("[%s:%u] - Event %d on pid %d successfully handled\n", 
622                __FILE__, __LINE__, ev.dbg, ev.proc->pid);
623      handled = true;
624
625      if (!flush)
626         break;
627      block = false;
628   }
629   return true;
630
631
632
633 bool ProcDebug::add_new_thread(THR_ID tid) {
634   if (threads.count(tid)) return true;
635
636   sw_printf("[%s:%u] - Adding new thread %d, in proc %d\n",
637             __FILE__, __LINE__, tid, pid);
638
639   ThreadState *new_thread = ThreadState::createThreadState(this, tid);
640   threads[tid] = new_thread;
641   
642   if (!new_thread && getLastError() == err_noproc) {
643     //Race condition, get thread ID or running thread, which then 
644     // exits.  Should be rare...
645     sw_printf("[%s:%u] - Error creating thread %d, does not exist\n",
646               __FILE__, __LINE__, tid);
647     clearLastError();
648     return false;
649
650   } else if (!new_thread) {
651     sw_printf("[%s:%u] - Unexpected error creating thread %d\n",
652               __FILE__, __LINE__, tid);
653     return false;
654   }
655
656   return true;
657 }
658
659
660 ProcDebug::~ProcDebug()
661 {
662 }
663
664 unsigned ProcSelf::getAddressWidth()
665 {
666    return sizeof(void *);
667 }
668
669 bool ProcSelf::isFirstParty()
670 {
671   return true;
672 }
673
674 ProcSelf::~ProcSelf()
675 {
676 }
677
678 bool ProcDebug::handleDebugEvent(bool block)
679 {
680   bool result;
681   bool handled;
682   
683   result = debug_wait_and_handle(block, true, handled);
684   if (!result) {
685     sw_printf("[%s:%u] - Error waiting for event in handleDebugEvent\n",
686               __FILE__, __LINE__);
687     return false;
688   }
689
690   return true;
691 }
692
693 bool ProcDebug::preStackwalk(Dyninst::THR_ID tid)
694 {
695    if (tid == NULL_THR_ID)
696       tid = initial_thread->getTid();
697
698    sw_printf("[%s:%u] - Calling preStackwalk for thread %d\n", __FILE__, __LINE__, tid);
699
700    thread_map_t::iterator i = threads.find(tid);
701    if (i == threads.end()) {
702       sw_printf("[%s:%u] - Couldn't find thread %d!\n", __FILE__, __LINE__, tid);
703       return false;
704    }
705    
706    bool result = true;
707    active_thread = (*i).second;
708    if (active_thread->state() != ps_running) {
709       sw_printf("[%s:%u] - Attempt to stackwalk on non-running thread %d/%d\n",
710                 __FILE__, __LINE__, active_thread->proc()->getProcessId(), 
711                 active_thread->getTid());
712       setLastError(err_procexit, "Stackwalk attempted on exited thread");
713       return false;
714    }
715
716    if (!active_thread->userIsStopped()) {
717       active_thread->setShouldResume(true);
718    }
719    if (!active_thread->isStopped())
720       result = pause_thread(active_thread);
721    return result;
722 }
723
724 bool ProcDebug::postStackwalk(Dyninst::THR_ID tid)
725 {
726    if (tid == NULL_THR_ID)
727       tid = initial_thread->getTid();
728
729    sw_printf("[%s:%u] - Calling preStackwalk for thread %d\n", __FILE__, __LINE__, tid);
730
731    thread_map_t::iterator i = threads.find(tid);
732    if (i == threads.end()) {
733       sw_printf("[%s:%u] - Couldn't find thread %d!\n", __FILE__, __LINE__, tid);
734       return false;
735    }
736
737    assert(active_thread == (*i).second);
738    if (active_thread->shouldResume()) {
739       resume_thread(active_thread);
740       active_thread->setShouldResume(false);      
741    }
742    return true;
743 }
744
745 bool ProcDebug::isTerminated()
746 {
747    return (state() == ps_exited || state() == ps_errorstate);
748 }
749
750 bool ProcDebug::isFirstParty()
751 {
752   return false;
753 }
754
755 LibraryState::LibraryState(ProcessState *parent) :
756    procstate(parent)
757 {
758 }
759
760 LibraryState::~LibraryState()
761 {
762 }
763
764 #ifndef os_bg_ion
765 bool ProcDebug::newProcDebugSet(const vector<Dyninst::PID> &pids,
766                                 vector<ProcDebug *> &out_set)
767 {
768    vector<Dyninst::PID>::const_iterator i;
769    for (i=pids.begin(); i!=pids.end(); i++)
770    {
771       Dyninst::PID pid = *i;
772       ProcDebug *new_pd = ProcDebug::newProcDebug(pid);
773       if (!new_pd) {
774          fprintf(stderr, "[%s:%u] - Unable to allocate new ProcDebugBG\n",
775                  __FILE__, __LINE__);
776          return false;
777    }
778       out_set.push_back(new_pd);
779    }
780    return true;
781 }
782 #endif // !os_bg_ion
783
784 LibraryState *ProcessState::getLibraryTracker()
785 {
786    return library_tracker;
787 }
788
789 proc_state ProcDebug::state()
790 {
791    assert(initial_thread);
792    return initial_thread->state();
793 }
794
795 void ProcDebug::setState(proc_state p)
796 {
797    assert(initial_thread);
798    sw_printf("[%s:%u] - Setting initial thread for %d to state %d\n",
799              __FILE__, __LINE__, pid, p);
800    initial_thread->setState(p);
801 }
802
803 void ProcDebug::registerSignalCallback(sig_callback_func f)
804 {
805    sigfunc = f;
806 }
807
808 string ProcessState::getExecutablePath() {
809   return executable_path;
810 }
811
812 ThreadState::ThreadState(ProcDebug *p, Dyninst::THR_ID id) :
813    is_stopped(true),
814    user_stopped(true),
815    should_resume(false),
816    tid(id),
817    thr_state(ps_neonatal),
818    parent(p),
819    pending_sigstops(0)
820 {
821 }
822
823 bool ThreadState::isStopped()
824 {
825    return is_stopped;
826 }
827
828 void ThreadState::setStopped(bool s)
829 {
830    is_stopped = s;
831 }
832
833 bool ThreadState::userIsStopped()
834 {
835    return user_stopped;
836 }
837
838 void ThreadState::setUserStopped(bool u)
839 {
840    user_stopped = u;
841 }
842
843 bool ThreadState::shouldResume()
844 {
845    return should_resume;
846 }
847
848 void ThreadState::setShouldResume(bool r)
849 {
850    should_resume = r;
851 }
852
853 Dyninst::THR_ID ThreadState::getTid()
854 {
855    return tid;
856 }
857
858 proc_state ThreadState::state()
859 {
860    return thr_state;
861 }
862
863 void ThreadState::setState(proc_state s)
864 {
865    sw_printf("[%s:%u] - Setting thread %d to state %d\n",
866              __FILE__, __LINE__, tid, s);
867    thr_state = s;
868 }
869
870 ProcDebug* ThreadState::proc() 
871 {
872    return parent;
873 }
874
875 ThreadState::~ThreadState()
876 {
877 }
878
879 void ThreadState::markPendingStop() {
880   pending_sigstops++;
881 }
882
883 void ThreadState::clearPendingStop() {
884   pending_sigstops--;
885 }
886
887 bool ThreadState::hasPendingStop() {
888   return pending_sigstops != 0;
889 }
890