proccontrol: Fix Coverity UNINIT_CTOR errors
[dyninst.git] / proccontrol / src / procset.C
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 #include "proccontrol/h/PCProcess.h"
32 #include "proccontrol/h/ProcessSet.h"
33 #include "proccontrol/h/PlatFeatures.h"
34 #include "proccontrol/h/Mailbox.h"
35 #include "proccontrol/h/Generator.h"
36 #include "proccontrol/src/int_process.h"
37 #include "proccontrol/src/procpool.h"
38 #include "proccontrol/src/int_handler.h"
39 #include "proccontrol/src/irpc.h"
40 #include "proccontrol/src/response.h"
41 #include "proccontrol/src/processplat.h"
42 #include "proccontrol/src/int_event.h"
43 #include "common/src/Types.h"
44 #include <stdlib.h>
45 #include <map>
46 #include <algorithm>
47
48 #if defined(os_windows)
49 #include "external/stdint-win.h"
50 #include "external/inttypes-win.h"
51 #endif
52 #include <boost/crc.hpp>
53 #include <iterator>
54
55 using namespace Dyninst;
56 using namespace ProcControlAPI;
57 using namespace std;
58
59 namespace Dyninst {
60 namespace ProcControlAPI {
61
62 class PSetFeatures {
63    friend class ProcessSet;
64 private:
65    PSetFeatures();
66    ~PSetFeatures();
67    LibraryTrackingSet *libset;
68    ThreadTrackingSet *thrdset;
69    LWPTrackingSet *lwpset;
70    FollowForkSet *forkset;
71    RemoteIOSet *ioset;
72    MemoryUsageSet *memset;
73 };
74
75 class TSetFeatures {
76    friend class ThreadSet;
77 private:
78    TSetFeatures();
79    ~TSetFeatures();
80    CallStackUnwindingSet *stkset;
81 };
82
83 }
84 }
85
86 PSetFeatures::PSetFeatures() :
87    libset(NULL),
88    thrdset(NULL),
89    lwpset(NULL),
90    forkset(NULL),
91    ioset(NULL)
92 {
93 }
94
95 PSetFeatures::~PSetFeatures()
96 {
97    if (libset) {
98       delete libset;
99       libset = NULL;
100    }
101    if (thrdset) {
102       delete thrdset;
103       thrdset = NULL;
104    }
105    if (forkset) {
106       delete forkset;
107       forkset = NULL;
108    }
109    if (ioset) {
110       delete ioset;
111       ioset = NULL;
112    }
113 }
114
115 TSetFeatures::TSetFeatures() :
116    stkset(NULL)
117 {
118 }
119
120 TSetFeatures::~TSetFeatures()
121 {
122    if (stkset) {
123       delete stkset;
124       stkset = NULL;
125    }
126 }
127
128 /**
129  * AddressSet implementation follows.  This is essentially a std::multimap of Address -> Process::ptr
130  * plus some additional features:
131  *  - Ability to create addresses based on ProcControlAPI objects, such as libraries.
132  *  - Additional range features to make it easier to group addresses
133  *  - No duplicates of Address, Process:ptr pairs are allowed, though there are
134  *    duplicate Address keys.
135  *
136  * I'd recommend your to your favorite multimap documentation for most of this.
137  **/
138 typedef pair<Address, Process::ptr> apair_t;
139
140 AddressSet::AddressSet() :
141    iaddrs(NULL)
142 {
143 }
144
145 AddressSet::ptr AddressSet::newAddressSet() {
146    AddressSet::ptr newset = AddressSet::ptr(new AddressSet);
147    newset->iaddrs = new int_addressSet();
148    return newset;
149 }
150
151 AddressSet::ptr AddressSet::newAddressSet(ProcessSet::const_ptr ps, Address addr)
152 {
153    AddressSet::ptr newset = AddressSet::ptr(new AddressSet);
154    newset->iaddrs = new int_addressSet();
155    for (ProcessSet::const_iterator i = ps->begin(); i != ps->end(); i++) {
156       newset->iaddrs->insert(value_type(addr, *i));
157    }
158    return newset;
159 }
160
161 AddressSet::ptr AddressSet::newAddressSet(ProcessSet::const_ptr ps, string library_name, Offset off)
162 {
163    MTLock lock_this_func;
164
165    AddressSet::ptr newset = AddressSet::ptr(new AddressSet);
166    newset->iaddrs = new int_addressSet();
167    for (ProcessSet::const_iterator i = ps->begin(); i != ps->end(); i++) {
168       int_process *p = (*i)->llproc();
169       if (!p) 
170          continue;
171       int_library *lib = p->getLibraryByName(library_name);
172       if (!lib)
173          continue;
174       newset->iaddrs->insert(value_type(lib->getAddr() + off, *i));
175    }
176    return newset;
177 }
178
179 AddressSet::ptr AddressSet::newAddressSet(Process::const_ptr p, Address addr)
180 {
181    AddressSet::ptr newset = AddressSet::ptr(new AddressSet);
182    newset->iaddrs = new int_addressSet();
183    newset->iaddrs->insert(value_type(addr, p->llproc()->proc()));
184    return newset;
185 }
186
187 AddressSet::ptr AddressSet::newAddressSet(ProcessSet::ptr ps, Address addr)
188 {
189    AddressSet::ptr newset = AddressSet::ptr(new AddressSet);
190    newset->iaddrs = new int_addressSet();
191    for (ProcessSet::iterator i = ps->begin(); i != ps->end(); i++) {
192       newset->iaddrs->insert(value_type(addr, *i));
193    }
194    return newset;
195 }
196
197 AddressSet::ptr AddressSet::newAddressSet(ProcessSet::ptr ps, string library_name, Offset off)
198 {
199    MTLock lock_this_func;
200
201    AddressSet::ptr newset = AddressSet::ptr(new AddressSet);
202    newset->iaddrs = new int_addressSet();
203    for (ProcessSet::iterator i = ps->begin(); i != ps->end(); i++) {
204       int_process *p = (*i)->llproc();
205       if (!p) 
206          continue;
207       int_library *lib = p->getLibraryByName(library_name);
208       if (!lib)
209          continue;
210       newset->iaddrs->insert(value_type(lib->getAddr() + off, *i));
211    }
212    return newset;
213 }
214
215 AddressSet::ptr AddressSet::newAddressSet(Process::ptr p, Address addr)
216 {
217    AddressSet::ptr newset = AddressSet::ptr(new AddressSet);
218    newset->iaddrs = new int_addressSet();
219    newset->iaddrs->insert(value_type(addr, p->llproc()->proc()));
220    return newset;
221 }
222
223 AddressSet::~AddressSet()
224 {
225    if (iaddrs) {
226       delete iaddrs;
227       iaddrs = NULL;
228    }
229 }
230
231 AddressSet::iterator AddressSet::begin()
232 {
233    return iaddrs->begin();
234 }
235
236 AddressSet::iterator AddressSet::end()
237 {
238    return iaddrs->end();
239 }
240
241 AddressSet::iterator AddressSet::find(Address a)
242 {
243    return iaddrs->find(a);
244 }
245
246 AddressSet::iterator AddressSet::find(Address a, Process::const_ptr p)
247 {
248    pair<iterator, iterator> range = equal_range(a);
249    for (iterator i = range.first; i != range.second; i++) {
250       if (i->second == p)
251          return i;
252    }
253    return end();
254 }
255
256 AddressSet::const_iterator AddressSet::begin() const
257 {
258    return iaddrs->begin();
259 }
260
261 AddressSet::const_iterator AddressSet::end() const
262 {
263    return iaddrs->end();
264 }
265
266 AddressSet::const_iterator AddressSet::find(Address a) const
267 {
268    return iaddrs->find(a);
269 }
270
271 AddressSet::const_iterator AddressSet::find(Address a, Process::const_ptr p) const
272 {
273    pair<const_iterator, const_iterator> range = equal_range(a);
274    for (const_iterator i = range.first; i != range.second; i++) {
275       if (i->second == p)
276          return i;
277    }
278    return end();
279 }
280
281 size_t AddressSet::count(Address a) const
282 {
283    return iaddrs->count(a);
284 }
285
286 size_t AddressSet::size() const
287 {
288    return iaddrs->size();
289 }
290
291 bool AddressSet::empty() const
292 {
293    return iaddrs->empty();
294 }
295
296 pair<AddressSet::iterator, bool> AddressSet::insert(Address a, Process::const_ptr p)
297 {
298    Process::ptr ncp = pc_const_cast<Process>(p);
299    pair<iterator, bool> result;
300    for (result.first = iaddrs->find(a); result.first != iaddrs->end() && result.first->first == a; result.first++) {
301       if (result.first->second == ncp) {
302          result.second = false;
303          return result;
304       }
305    }
306    result.first = iaddrs->insert(value_type(a, ncp));
307    result.second = true;
308    return result;
309 }
310
311 size_t AddressSet::insert(Address a, ProcessSet::const_ptr ps)
312 {
313    size_t count_added = 0;
314    for (ProcessSet::const_iterator i = ps->begin(); i != ps->end(); i++) {
315       Process::ptr proc = *i;
316       pair<AddressSet::iterator, bool> result = insert(a, *i);
317       if (result.second)
318          count_added++;
319    }
320    return count_added;
321 }
322
323 pair<AddressSet::iterator, bool> AddressSet::insert(Address a, Process::ptr p)
324 {
325    Process::ptr ncp = pc_const_cast<Process>(p);
326    pair<iterator, bool> result;
327    for (result.first = iaddrs->find(a); result.first != iaddrs->end() && result.first->first == a; result.first++) {
328       if (result.first->second == ncp) {
329          result.second = false;
330          return result;
331       }
332    }
333    result.first = iaddrs->insert(value_type(a, ncp));
334    result.second = true;
335    return result;
336 }
337
338 size_t AddressSet::insert(Address a, ProcessSet::ptr ps)
339 {
340    size_t count_added = 0;
341    for (ProcessSet::iterator i = ps->begin(); i != ps->end(); i++) {
342       Process::ptr proc = *i;
343       pair<AddressSet::iterator, bool> result = insert(a, *i);
344       if (result.second)
345          count_added++;
346    }
347    return count_added;
348 }
349
350 void AddressSet::erase(AddressSet::iterator pos)
351 {
352    iaddrs->erase(pos);
353 }
354
355 size_t AddressSet::erase(Process::const_ptr p)
356 {
357    size_t num_erased = 0;
358    Process::ptr ncp = pc_const_cast<Process>(p);
359    iterator i = iaddrs->begin();
360    while (i != iaddrs->end()) {
361       if (i->second == ncp) {
362          iterator j = i++;
363          iaddrs->erase(j);
364          num_erased++;
365       }
366       else {
367          i++;
368       }
369    }
370    return num_erased;
371 }
372
373 size_t AddressSet::erase(Address a, Process::const_ptr p)
374 {
375    Process::ptr ncp = pc_const_cast<Process>(p);
376    iterator i = find(a, p);
377    if (i == end())
378       return 0;
379    erase(i);
380    return 1;
381 }
382
383 void AddressSet::clear()
384 {
385    iaddrs->clear();
386 }
387
388 AddressSet::iterator AddressSet::lower_bound(Address a)
389 {
390    return iaddrs->lower_bound(a);
391 }
392
393 AddressSet::iterator AddressSet::upper_bound(Address a)
394 {
395    return iaddrs->upper_bound(a);
396 }
397
398 pair<AddressSet::iterator, AddressSet::iterator> AddressSet::equal_range(Address a)
399 {
400    return iaddrs->equal_range(a);
401 }
402
403 AddressSet::const_iterator AddressSet::lower_bound(Address a) const
404 {
405    return iaddrs->lower_bound(a);
406 }
407
408 AddressSet::const_iterator AddressSet::upper_bound(Address a) const
409 {
410    return iaddrs->upper_bound(a);
411 }
412
413 pair<AddressSet::const_iterator, AddressSet::const_iterator> AddressSet::equal_range(Address a) const
414 {
415    return iaddrs->equal_range(a);
416 }
417
418 AddressSet::ptr AddressSet::set_union(AddressSet::const_ptr pp) const
419 {
420    AddressSet::ptr newset = AddressSet::newAddressSet();
421
422    std::set_union(iaddrs->begin(), iaddrs->end(),
423                   pp->iaddrs->begin(), pp->iaddrs->end(),
424                   inserter(*newset->iaddrs, newset->iaddrs->end()));
425
426    return newset;
427 }
428
429 AddressSet::ptr AddressSet::set_intersection(AddressSet::const_ptr pp) const
430 {
431    AddressSet::ptr newset = AddressSet::newAddressSet();
432
433    std::set_intersection(iaddrs->begin(), iaddrs->end(),
434                          pp->iaddrs->begin(), pp->iaddrs->end(),
435                          inserter(*newset->iaddrs, newset->iaddrs->end()));
436
437    return newset;
438 }
439
440 AddressSet::ptr AddressSet::set_difference(AddressSet::const_ptr pp) const
441 {
442    AddressSet::ptr newset = AddressSet::newAddressSet();
443
444    std::set_difference(iaddrs->begin(), iaddrs->end(),
445                        pp->iaddrs->begin(), pp->iaddrs->end(),
446                        inserter(*newset->iaddrs, newset->iaddrs->end()));
447
448    return newset;
449 }
450
451
452 /**
453  * The following bundle of hackery is a wrapper around iterators that
454  * checks processes for common errors.  Many of the functions that implement
455  * ProcessSet and ThreadSet have do an operation where they iterate over
456  * a collection, pull some Process::ptr or Thread::ptr out of that collection,
457  * check it for common errors (e.g, operating on a dead process), then do some
458  * real work. These classes/templates are an attempt to bring all that error checking
459  * and iteration into a common place.
460  *
461  * Things are complicated by the fact that we use many different types of collections
462  * We might be operating over sets of Process::ptrs, or multimaps from Thread::ptr to 
463  * register values, etc.  The common iteration and error handling code is in the iter_t
464  * template, which takes the type of collection it's iterating over as template parameters.
465  *
466  * The three big operations iter_t needs to do is extract a process from an iterator and
467  * get the begin/end iterators from a collection.  These operations are done by a set
468  * of overloaded functions: get_proc, get_begin, and get_end.  We have an instance of these
469  * for each type of collection we deal with.
470  **/
471 template<class T>
472 static Process::const_ptr get_proc(const T &i, err_t *) {
473    return i->first;
474 }
475
476 template<class T>
477 static typename T::iterator get_begin(T *m) {
478    return m->begin();
479 }
480
481 template<class T>
482 static typename T::iterator get_end(T *m) {
483    return m->end();
484 }
485
486 template<class T>
487 static typename T::const_iterator get_begin(const T *m) {
488    return m->begin();
489 }
490
491 template<class T>
492 static typename T::const_iterator get_end(const T *m) {
493    return m->end();
494 }
495
496 static Process::const_ptr get_proc(const int_addressSet::iterator &i, err_t *) {
497    return i->second;
498 }
499
500 static int_addressSet::iterator get_begin(AddressSet::ptr as) {
501    return as->get_iaddrs()->begin();
502 }
503
504 static int_addressSet::iterator get_end(AddressSet::ptr as) {
505    return as->get_iaddrs()->end();
506 }
507
508 static void thread_err_check(int_thread *ithr, err_t *thread_error) {
509    if (!ithr) {
510       *thread_error = err_exited;
511    }
512    if (ithr->getUserState().getState() == int_thread::running) {
513       *thread_error = err_notrunning;
514    }
515 }
516
517 static Process::const_ptr get_proc(const map<Thread::const_ptr, MachRegisterVal>::const_iterator &i, err_t *thread_error)
518 {
519    if (thread_error)
520       thread_err_check(i->first->llthrd(), thread_error);
521    return i->first->getProcess();
522 }
523
524 static Process::const_ptr get_proc(const map<Thread::const_ptr, RegisterPool>::const_iterator &i, err_t *thread_error)
525 {
526    if (thread_error)
527       thread_err_check(i->first->llthrd(), thread_error);
528    return i->first->getProcess();
529 }
530
531 static Process::const_ptr get_proc(const multimap<Thread::const_ptr, IRPC::ptr>::const_iterator &i, err_t *thread_error = NULL) 
532 {
533    if (thread_error)
534       thread_err_check(i->first->llthrd(), thread_error);
535    return i->first->getProcess();
536 }
537
538 static Process::const_ptr get_proc(const int_processSet::iterator &i, err_t *) {
539    return *i;
540 }
541
542 static Process::const_ptr get_proc(const int_threadSet::iterator &i, err_t *thread_error = NULL) {
543    if (thread_error)
544       thread_err_check((*i)->llthrd(), thread_error);
545    return (*i)->getProcess();
546 }
547
548 #define ERR_CHCK_EXITED       (1<<0)
549 #define ERR_CHCK_DETACHED     (1<<1)
550 #define ERR_CHCK_STOPPED      (1<<2)
551 #define ERR_CHCK_THRD_STOPPED (1<<3)
552 #define CLEAR_ERRS            (1<<4)
553 #define THREAD_CLEAR_ERRS     (1<<5)
554
555 #define ERR_CHCK_NORM (ERR_CHCK_EXITED | ERR_CHCK_DETACHED | CLEAR_ERRS)
556 #define ERR_CHCK_ALL  (ERR_CHCK_NORM | ERR_CHCK_STOPPED)
557 #define ERR_CHCK_THRD (ERR_CHCK_EXITED | ERR_CHCK_DETACHED | THREAD_CLEAR_ERRS)
558
559 template<class cont_t, class iterator_t>
560 class iter_t {
561 private:
562    const char *msg;
563    bool &had_error;
564    unsigned int flags;
565    cont_t container;
566    iterator_t iter;
567    bool finished_clear;
568    bool did_begin;
569
570    bool proc_check(Process::const_ptr p, err_t thr_error) {
571       int_process *proc = p ? p->llproc() : NULL;
572       if (!proc) {
573          perr_printf("%s attempted on exited process\n", msg);
574          if (p) p->setLastError(err_exited, "Operation attempted on exited process");
575          had_error = true;
576          return false;
577       }
578       if ((flags & CLEAR_ERRS) && !finished_clear) {
579          proc->clearLastError();
580       }
581       if ((flags & ERR_CHCK_EXITED) && thr_error == err_exited) {
582          perr_printf("%s attempted on exited thread in process %d\n", msg, p->getPid());
583          p->setLastError(err_exited, "Group operation attempted on exited thread");
584          had_error = true;
585          return false;
586       }
587       if ((flags & ERR_CHCK_THRD_STOPPED) && thr_error == err_notrunning) {
588          perr_printf("%s attempted on running thread in process %d\n", msg, p->getPid());
589          p->setLastError(err_notrunning, "Group operation attempted on running thread");
590          had_error = true;
591          return false;
592       }
593       if ((flags & ERR_CHCK_EXITED) && !proc) {
594          perr_printf("%s attempted on exited process %d\n", msg, p->getPid());
595          p->setLastError(err_exited, "Group operation attempted on exited process");
596          had_error = true;
597          return false;
598       }
599       if ((flags & ERR_CHCK_DETACHED) && p->isDetached()) {
600          perr_printf("%s attempted on detached process %d\n", msg, proc->getPid());
601          p->setLastError(err_detached, "Group operation attempted on detached process");
602          had_error = true;
603          return false;
604       }
605       if ((flags & ERR_CHCK_STOPPED) && p->hasRunningThread()) {
606          perr_printf("%s attempted on running process %d\n", msg, proc->getPid());
607          p->setLastError(err_notstopped, "Group operation attempted on running process");
608          had_error = true;
609          return false;
610       } 
611       return true;
612    }
613
614 public:
615    typedef iterator_t i_t;
616
617    iter_t(const char *m, bool &e, unsigned int f) :
618       msg(m),
619       had_error(e),
620       flags(f),
621       container(NULL),
622       finished_clear(false),
623       did_begin(false)
624    {
625    }
626    
627    ~iter_t() {
628    }
629
630    iterator_t begin(cont_t c) {
631       container = c;
632       if (!finished_clear && (flags & THREAD_CLEAR_ERRS)) {
633          for (iter = get_begin(container); iter != get_end(container); iter++) {
634             Process::const_ptr proc = get_proc(iter, NULL);
635             proc->clearLastError();
636          }
637          finished_clear = true;
638       }
639       else {
640          if (did_begin)
641             finished_clear = true;
642       }
643       did_begin = true;
644
645       iter = get_begin(container);
646       err_t thr_error = err_none;
647       Process::const_ptr proc = get_proc(iter, &thr_error);
648       if (!proc_check(proc, thr_error))
649          return inc();
650       return iter;
651    }
652    
653    iterator_t end() {
654       return get_end(container);
655    }
656
657    iterator_t inc() {
658       iterator_t end = this->end();
659       bool result = false;
660       do {
661          iter++;
662          if (iter == end) {
663             return iter;
664          }
665          err_t thr_error = err_none;
666          Process::const_ptr proc = get_proc(iter, &thr_error);
667          result = proc_check(proc, thr_error);
668       } while (!result);
669       return iter;
670    }
671 };
672
673 typedef iter_t<AddressSet::ptr, int_addressSet::iterator> addrset_iter;
674 typedef iter_t<int_processSet *, int_processSet::iterator> procset_iter;
675 typedef iter_t<multimap<Process::const_ptr, ProcessSet::read_t> *, multimap<Process::const_ptr, ProcessSet::read_t>::iterator> readmap_iter;
676 typedef iter_t<multimap<Process::const_ptr, ProcessSet::write_t> *, multimap<Process::const_ptr, ProcessSet::write_t>::iterator > writemap_iter;
677 typedef iter_t<const multimap<Process::const_ptr, IRPC::ptr> *, multimap<Process::const_ptr, IRPC::ptr>::const_iterator > rpcmap_iter;
678 typedef iter_t<const multimap<Thread::const_ptr, IRPC::ptr> *, multimap<Thread::const_ptr, IRPC::ptr>::const_iterator > rpcmap_thr_iter;
679 typedef iter_t<int_threadSet *, int_threadSet::iterator> thrset_iter;
680 typedef iter_t<const map<Thread::const_ptr, Dyninst::MachRegisterVal> *, map<Thread::const_ptr, Dyninst::MachRegisterVal>::const_iterator> setreg_iter;
681 typedef iter_t<const map<Thread::const_ptr, RegisterPool> *, map<Thread::const_ptr, RegisterPool>::const_iterator> setallreg_iter;
682
683 ProcessSet::ProcessSet() :
684    features(NULL)
685 {
686    procset = new int_processSet;
687 }
688
689 ProcessSet::~ProcessSet()
690 {
691    if (procset) {
692       delete procset;
693       procset = NULL;
694    }
695    if (features) {
696       delete features;
697       features = NULL;
698    }
699 }
700
701 ProcessSet::ptr ProcessSet::newProcessSet()
702 {
703    return ProcessSet::ptr(new ProcessSet());
704 }
705
706 ProcessSet::ptr ProcessSet::newProcessSet(Process::const_ptr pp)
707 {
708    ProcessSet::ptr newps = newProcessSet();
709    newps->insert(pp);
710    return newps;
711 }
712
713 ProcessSet::ptr ProcessSet::newProcessSet(ProcessSet::const_ptr pp)
714 {
715    return newProcessSet(*pp->procset);
716 }
717
718 ProcessSet::ptr ProcessSet::newProcessSet(const set<Process::ptr> &procs)
719 {
720    ProcessSet::ptr newps = newProcessSet();
721    copy(procs.begin(), procs.end(), inserter(*newps->procset, newps->procset->end()));
722    return newps;
723 }
724
725 ProcessSet::ptr ProcessSet::newProcessSet(Process::ptr p)
726 {
727    ProcessSet::ptr newps = newProcessSet();
728    newps->insert(p);
729    return newps;
730 }
731
732 ProcessSet::ptr ProcessSet::newProcessSet(ProcessSet::ptr pp)
733 {
734    return newProcessSet(*pp->procset);
735 }
736
737 struct proc_strip_const {
738    Process::ptr operator()(Process::const_ptr p) const {
739       return pc_const_cast<Process>(p);
740    }
741 };
742
743 ProcessSet::ptr ProcessSet::newProcessSet(const set<Process::const_ptr> &procs)
744 {
745    ProcessSet::ptr newps = newProcessSet();
746    int_processSet &newset = *newps->procset;
747    transform(procs.begin(), procs.end(), inserter(newset, newset.end()), proc_strip_const());
748    return newps;
749 }
750
751 ProcessSet::ptr ProcessSet::newProcessSet(AddressSet::const_iterator begin, AddressSet::const_iterator end)
752 {
753    ProcessSet::ptr newps = newProcessSet();
754    int_processSet &newset = *newps->procset;
755    for (AddressSet::const_iterator i = begin; i != end; i++) {
756       pair<Address, Process::ptr> ii = *i;
757       Process::ptr p = ii.second;
758       newset.insert((*i).second);
759    }
760    return newps;
761 }
762
763 ProcessSet::ptr ProcessSet::createProcessSet(vector<CreateInfo> &cinfo)
764 {
765    MTLock lock_this_func(MTLock::allow_init, MTLock::deliver_callbacks);
766
767    pthrd_printf("User asked to launch %u executables\n", (unsigned) cinfo.size());
768
769    if (int_process::isInCB()) {
770       perr_printf("User attempted call on process create while in CB, erroring.");
771       for (vector<CreateInfo>::iterator i = cinfo.begin(); i != cinfo.end(); i++) {
772          i->error_ret = err_incallback;
773       }
774       return ProcessSet::ptr();
775    }
776
777    ProcPool()->condvar()->lock();
778
779    map<int_process *, vector<CreateInfo>::iterator> info_map;
780    ProcessSet::ptr newps = newProcessSet();
781    int_processSet &newset = *newps->procset;
782
783    pthrd_printf("Creating new process objects\n");
784    for (vector<CreateInfo>::iterator i = cinfo.begin(); i != cinfo.end(); i++) {
785       Process::ptr newproc(new Process());
786       int_process *llproc = int_process::createProcess(i->executable, i->argv, i->envp, i->fds);
787       llproc->initializeProcess(newproc);
788       info_map[llproc] = i;
789       newset.insert(newproc);
790    }
791
792    pthrd_printf("Triggering create on new process objects\n");
793    int_process::create(&newset); //Releases procpool lock
794
795    for (ProcessSet::iterator i = newps->begin(); i != newps->end();) {
796       int_process *proc = (*i)->llproc();
797       map<int_process *, vector<CreateInfo>::iterator>::iterator j = info_map.find(proc);
798       assert(j != info_map.end());
799       CreateInfo &ci = *(j->second);
800
801       err_t last_error = proc->getLastError();
802       if (last_error == err_none) {
803          ci.proc = proc->proc();
804          ci.error_ret = err_none;
805          i++;
806          continue;
807       }
808       ci.error_ret = last_error;
809       ci.proc = Process::ptr();
810       newps->erase(i++);
811    }
812
813    return newps;
814 }
815
816 ProcessSet::ptr ProcessSet::attachProcessSet(vector<AttachInfo> &ainfo)
817 {
818    MTLock lock_this_func(MTLock::allow_init, MTLock::deliver_callbacks);
819
820    pthrd_printf("User asked to attach to %u processes\n", (unsigned) ainfo.size());
821
822    if (int_process::isInCB()) {
823       perr_printf("User attempted call on process create while in CB, erroring.");
824       for (vector<AttachInfo>::iterator i = ainfo.begin(); i != ainfo.end(); i++) {
825          i->error_ret = err_incallback;
826       }
827       return ProcessSet::ptr();
828    }
829
830    ProcPool()->condvar()->lock();
831
832    map<int_process *, vector<AttachInfo>::iterator> info_map;
833    ProcessSet::ptr newps = newProcessSet();
834    int_processSet &newset = *newps->procset;
835
836    for (vector<AttachInfo>::iterator i = ainfo.begin(); i != ainfo.end(); i++) {
837       Process::ptr newproc(new Process());
838       int_process *llproc = int_process::createProcess(i->pid, i->executable);
839       llproc->initializeProcess(newproc);
840       info_map[llproc] = i;
841       newset.insert(newproc);
842    }
843
844    int_process::attach(&newset, false); //Releases procpool lock
845
846    for (ProcessSet::iterator i = newps->begin(); i != newps->end(); ) {
847       int_process *proc = (*i)->llproc();
848       map<int_process *, vector<AttachInfo>::iterator>::iterator j = info_map.find(proc);
849       assert(j != info_map.end());
850       AttachInfo &ai = *(j->second);
851       
852       err_t last_error = proc->getLastError();
853       if (last_error == err_none) {
854          ai.proc = proc->proc();
855          ai.error_ret = err_none;
856          i++;
857          continue;
858       }
859       pthrd_printf("Erasing process %d from attach return set because err = %d\n",
860                    proc->getPid(), last_error);
861       ai.error_ret = last_error;
862       ai.proc = Process::ptr();
863       newps->erase(i++);
864    }
865
866    return newps;
867 }
868
869 ProcessSet::ptr ProcessSet::set_union(ProcessSet::ptr pp) const
870 {
871    //No MTLock needed, not digging into internals.
872    ProcessSet::ptr newps = ProcessSet::ptr(new ProcessSet);
873    int_processSet *me = procset;
874    int_processSet *you = pp->procset;
875    int_processSet *them = newps->procset;
876
877    std::set_union(me->begin(), me->end(), you->begin(), you->end(), inserter(*them, them->end()));
878    return newps;
879 }
880
881 ProcessSet::ptr ProcessSet::set_intersection(ProcessSet::ptr pp) const
882 {
883    //No MTLock needed, not digging into internals.
884    ProcessSet::ptr newps = ProcessSet::ptr(new ProcessSet);
885    int_processSet *me = procset;
886    int_processSet *you = pp->procset;
887    int_processSet *them = newps->procset;
888
889    std::set_intersection(me->begin(), me->end(), you->begin(), you->end(), inserter(*them, them->end()));
890    return newps;
891 }
892
893 ProcessSet::ptr ProcessSet::set_difference(ProcessSet::ptr pp) const
894 {
895    //No MTLock needed, not digging into internals.
896    ProcessSet::ptr newps = ProcessSet::ptr(new ProcessSet);
897    int_processSet *me = procset;
898    int_processSet *you = pp->procset;
899    int_processSet *them = newps->procset;
900
901    std::set_difference(me->begin(), me->end(), you->begin(), you->end(), inserter(*them, them->end()));
902    return newps;
903 }
904
905 ProcessSet::iterator ProcessSet::begin()
906 {
907    return iterator(procset->begin());
908 }
909
910 ProcessSet::iterator ProcessSet::end()
911 {
912    return iterator(procset->end());
913 }
914
915 ProcessSet::iterator ProcessSet::find(Process::const_ptr p)
916 {
917    return iterator(procset->find(pc_const_cast<Process>(p)));
918 }
919
920 ProcessSet::iterator ProcessSet::find(PID p)
921 {
922    ProcPool()->condvar()->lock();
923    int_process *llproc = ProcPool()->findProcByPid(p);
924    ProcPool()->condvar()->unlock();
925    if (!llproc) return end();
926    return iterator(procset->find(llproc->proc()));
927 }
928
929 ProcessSet::const_iterator ProcessSet::begin() const
930 {
931    return const_iterator(procset->begin());
932 }
933
934 ProcessSet::const_iterator ProcessSet::end() const
935 {
936    return const_iterator(procset->end());
937 }
938
939 ProcessSet::const_iterator ProcessSet::find(Process::const_ptr p) const
940 {
941    return const_iterator(procset->find(pc_const_cast<Process>(p)));
942 }
943
944 ProcessSet::const_iterator ProcessSet::find(PID p) const
945 {
946    ProcPool()->condvar()->lock();
947    int_process *llproc = ProcPool()->findProcByPid(p);
948    ProcPool()->condvar()->unlock();
949    if (!llproc) return end();
950    return const_iterator(procset->find(llproc->proc()));
951 }
952
953 bool ProcessSet::empty() const
954 {
955    return procset->empty();
956 }
957
958 size_t ProcessSet::size() const
959 {
960    return procset->size();
961 }
962
963 pair<ProcessSet::iterator, bool> ProcessSet::insert(Process::const_ptr p)
964 {
965    pair<int_processSet::iterator, bool> result = procset->insert(pc_const_cast<Process>(p));
966    return pair<ProcessSet::iterator, bool>(ProcessSet::iterator(result.first), result.second);
967 }
968
969 void ProcessSet::erase(ProcessSet::iterator pos)
970 {
971    procset->erase(pos.int_iter);
972 }
973
974 size_t ProcessSet::erase(Process::const_ptr p)
975 {
976    ProcessSet::iterator i = find(p);
977    if (i == end()) return 0;
978    erase(i);
979    return 1;
980 }
981
982 void ProcessSet::clear()
983 {
984    procset->clear();
985 }
986
987 LibraryTrackingSet *ProcessSet::getLibraryTracking()
988 {
989    if (features && features->libset)
990       return features->libset;
991
992    MTLock lock_this_func;
993    if (!procset)
994       return NULL;
995    if (!features) {
996       features = new PSetFeatures();
997    }
998    for (int_processSet::iterator i = procset->begin(); i != procset->end(); i++) {
999       Process::ptr p = *i;
1000       if (p->getLibraryTracking()) {
1001          features->libset = new LibraryTrackingSet(shared_from_this());
1002          return features->libset;
1003       }
1004    }
1005
1006    return NULL;
1007 }
1008
1009 ThreadTrackingSet *ProcessSet::getThreadTracking()
1010 {
1011    if (features && features->thrdset)
1012       return features->thrdset;
1013
1014    MTLock lock_this_func;
1015    if (!procset)
1016       return NULL;
1017    if (!features) {
1018       features = new PSetFeatures();
1019    }
1020    for (int_processSet::iterator i = procset->begin(); i != procset->end(); i++) {
1021       Process::ptr p = *i;
1022       if (p->getThreadTracking()) {
1023          features->thrdset = new ThreadTrackingSet(shared_from_this());
1024          return features->thrdset;
1025       }
1026    }
1027
1028    return NULL;
1029 }
1030
1031 LWPTrackingSet *ProcessSet::getLWPTracking()
1032 {
1033    if (features && features->lwpset)
1034       return features->lwpset;
1035
1036    MTLock lock_this_func;
1037    if (!procset)
1038       return NULL;
1039    if (!features) {
1040       features = new PSetFeatures();
1041    }
1042    for (int_processSet::iterator i = procset->begin(); i != procset->end(); i++) {
1043       Process::ptr p = *i;
1044       if (p->getLWPTracking()) {
1045          features->lwpset = new LWPTrackingSet(shared_from_this());
1046          return features->lwpset;
1047       }
1048    }
1049
1050    return NULL;
1051 }
1052
1053 FollowForkSet *ProcessSet::getFollowFork()
1054 {
1055    if (features && features->forkset)
1056       return features->forkset;
1057
1058    MTLock lock_this_func;
1059    if (!procset)
1060       return NULL;
1061    if (!features) {
1062       features = new PSetFeatures();
1063    }
1064    for (int_processSet::iterator i = procset->begin(); i != procset->end(); i++) {
1065       Process::ptr p = *i;
1066       if (p->getFollowFork()) {
1067          features->forkset = new FollowForkSet(shared_from_this());
1068          return features->forkset;
1069       }
1070    }
1071
1072    return NULL;
1073 }
1074
1075 RemoteIOSet *ProcessSet::getRemoteIO()
1076 {
1077    if (features && features->ioset)
1078       return features->ioset;
1079
1080    MTLock lock_this_func;
1081    if (!procset)
1082       return NULL;
1083    if (!features) {
1084       features = new PSetFeatures();
1085    }
1086    for (int_processSet::iterator i = procset->begin(); i != procset->end(); i++) {
1087       Process::ptr p = *i;
1088       if (p->getRemoteIO()) {
1089          features->ioset = new RemoteIOSet(shared_from_this());
1090          return features->ioset;
1091       }
1092    }
1093
1094    return NULL;
1095 }
1096
1097 MemoryUsageSet *ProcessSet::getMemoryUsage()
1098 {
1099    if (features && features->memset)
1100       return features->memset;
1101
1102    MTLock lock_this_func;
1103    if (!procset)
1104       return NULL;
1105    if (!features) {
1106       features = new PSetFeatures();
1107    }
1108    for (int_processSet::iterator i = procset->begin(); i != procset->end(); i++) {
1109       Process::ptr p = *i;
1110       if (p->getMemoryUsage()) {
1111          features->memset = new MemoryUsageSet(shared_from_this());
1112          return features->memset;
1113       }
1114    }
1115
1116    return NULL;
1117 }
1118
1119 const LibraryTrackingSet *ProcessSet::getLibraryTracking() const
1120 {
1121    return const_cast<ProcessSet *>(this)->getLibraryTracking();
1122 }
1123
1124 const ThreadTrackingSet *ProcessSet::getThreadTracking() const
1125 {
1126    return const_cast<ProcessSet *>(this)->getThreadTracking();
1127 }
1128
1129 const LWPTrackingSet *ProcessSet::getLWPTracking() const
1130 {
1131    return const_cast<ProcessSet *>(this)->getLWPTracking();
1132 }
1133
1134 const FollowForkSet *ProcessSet::getFollowFork() const
1135 {
1136    return const_cast<ProcessSet *>(this)->getFollowFork();
1137 }
1138
1139 const RemoteIOSet *ProcessSet::getRemoteIO() const
1140 {
1141    return const_cast<ProcessSet *>(this)->getRemoteIO();
1142 }
1143
1144 const MemoryUsageSet *ProcessSet::getMemoryUsage() const
1145 {
1146    return const_cast<ProcessSet *>(this)->getMemoryUsage();
1147 }
1148 ProcessSet::ptr ProcessSet::getErrorSubset() const
1149 {
1150    MTLock lock_this_func;
1151
1152    ProcessSet::ptr newps = newProcessSet();
1153    for (ProcessSet::const_iterator i = begin(); i != end(); i++) {
1154       ProcControlAPI::err_t err = (*i)->getLastError();
1155       if (err == err_none)
1156          continue;
1157       newps->insert(*i);
1158    }
1159    return newps;
1160 }
1161
1162 void ProcessSet::getErrorSubsets(map<ProcControlAPI::err_t, ProcessSet::ptr> &err_sets) const
1163 {
1164    MTLock lock_this_func;
1165
1166    for (const_iterator i = begin(); i != end(); i++) {
1167       Process::ptr proc = *i;
1168       ProcControlAPI::err_t err = proc->getLastError();
1169       if (err == err_none)
1170          continue;
1171       map<err_t, ProcessSet::ptr>::iterator j = err_sets.find(err);
1172       ProcessSet::ptr ps;
1173       if (j != err_sets.end()) {
1174          ps = j->second;
1175       }
1176       else {
1177          ps = ProcessSet::newProcessSet();
1178          err_sets[err] = ps;
1179       }
1180       ps->insert(proc);
1181    }
1182 }
1183
1184 template<class iter, class pred>
1185 static bool all_match(iter b, iter e, pred p)
1186 {
1187    bool result = true;
1188    for (iter i = b; i != e; i++) {
1189       if (!p(*i))
1190          result = false;
1191    }
1192    return result;
1193 }
1194
1195 template<class iter, class pred>
1196 static bool any_match(iter b, iter e, pred p)
1197 {
1198    bool result = false;
1199    for (iter i = b; i != e; i++) {
1200       if (p(*i))
1201          result = true;
1202    }
1203    return result;
1204 }
1205
1206 template<class iter, class pred>
1207 static ProcessSet::ptr create_subset(iter b, iter e, pred p) {
1208    ProcessSet::ptr newps = ProcessSet::newProcessSet();
1209    for (iter i = b; i != e; i++) {
1210       if (p(*i)) {
1211          newps->insert(*i);
1212       }
1213    }
1214    return newps;
1215 }
1216
1217 template<class iter, class pred>
1218 static ThreadSet::ptr create_thrsubset(iter b, iter e, pred p) {
1219    ThreadSet::ptr newts = ThreadSet::newThreadSet();
1220    for (iter i = b; i != e; i++) {
1221       if (p(*i)) {
1222          newts->insert(*i);
1223       }
1224    }
1225    return newts;
1226 }
1227
1228 struct test_terminate {
1229    bool operator()(Process::ptr p) {
1230       p->clearLastError();
1231       int_process *llproc = p->llproc();
1232       if (!llproc)
1233          return true;
1234       return false;
1235    }
1236
1237
1238    bool operator()(Thread::ptr t) {
1239       Process::ptr p = t->getProcess();
1240       p->clearLastError();
1241       return (!p->llproc() || !t->llthrd());
1242    }
1243 };
1244
1245 bool ProcessSet::anyTerminated() const
1246 {
1247    MTLock lock_this_func;
1248    return any_match(procset->begin(), procset->end(), test_terminate());
1249 }
1250
1251 bool ProcessSet::allTerminated() const
1252 {
1253    MTLock lock_this_func;
1254    return all_match(procset->begin(), procset->end(), test_terminate());
1255 }
1256
1257 ProcessSet::ptr ProcessSet::getTerminatedSubset() const
1258 {
1259    MTLock lock_this_func;
1260    return create_subset(procset->begin(), procset->end(), test_terminate());
1261 }
1262
1263 struct test_exited {
1264    bool operator()(Process::ptr p) {
1265       p->clearLastError();
1266       int_process *llproc = p->llproc();
1267       if (!llproc)
1268          return p->exitstate()->exited;
1269       return false;
1270    }
1271 };
1272
1273 bool ProcessSet::anyExited() const
1274 {
1275    MTLock lock_this_func;
1276    if (procset->empty())
1277       return true;
1278    return any_match(procset->begin(), procset->end(), test_exited());
1279 }
1280
1281 bool ProcessSet::allExited() const
1282 {
1283    MTLock lock_this_func;
1284    if (procset->empty())
1285       return true;
1286    return all_match(procset->begin(), procset->end(), test_exited());
1287 }
1288
1289 ProcessSet::ptr ProcessSet::getExitedSubset() const
1290 {
1291    MTLock lock_this_func;
1292    return create_subset(procset->begin(), procset->end(), test_exited());
1293 }
1294
1295 struct test_crashed {
1296    bool operator()(Process::ptr p) {
1297       p->clearLastError();
1298       int_process *llproc = p->llproc();
1299       if (!llproc)
1300          return p->exitstate()->crashed;
1301       return false;
1302    }
1303 };
1304
1305 bool ProcessSet::anyCrashed() const
1306 {
1307    MTLock lock_this_func;
1308    return any_match(procset->begin(), procset->end(), test_crashed());
1309 }
1310
1311 bool ProcessSet::allCrashed() const
1312 {
1313    MTLock lock_this_func;
1314    return all_match(procset->begin(), procset->end(), test_crashed());
1315 }
1316
1317 ProcessSet::ptr ProcessSet::getCrashedSubset() const
1318 {
1319    MTLock lock_this_func;
1320    return create_subset(procset->begin(), procset->end(), test_crashed());
1321 }
1322
1323 struct test_detached {
1324    bool operator()(Process::ptr p) {
1325       p->clearLastError();
1326       int_process *llproc = p->llproc();
1327       if (!llproc)
1328          return false;
1329       return llproc->getState() == int_process::detached;
1330    }
1331 };
1332
1333 bool ProcessSet::anyDetached() const
1334 {
1335    MTLock lock_this_func;
1336    return any_match(procset->begin(), procset->end(), test_detached());
1337 }
1338
1339 bool ProcessSet::allDetached() const
1340 {
1341    MTLock lock_this_func;
1342    return all_match(procset->begin(), procset->end(), test_detached());
1343 }
1344
1345 ProcessSet::ptr ProcessSet::getDetachedSubset() const
1346 {
1347    MTLock lock_this_func;
1348    return create_subset(procset->begin(), procset->end(), test_detached());
1349 }
1350
1351 struct test_thr {
1352    enum test_t {
1353       any,
1354       all
1355    };
1356    test_t test;
1357    int_thread::State ts;
1358
1359    test_thr(test_t t_, int_thread::State ts_) : test(t_), ts(ts_) {}
1360
1361    bool operator()(Process::ptr p) {
1362       p->clearLastError();
1363       int_process *llproc = p->llproc();
1364       if (!llproc)
1365          return false;
1366       int_threadPool *tp = llproc->threadPool();
1367       for (int_threadPool::iterator i = tp->begin(); i != tp->end(); i++) {
1368          bool match = ((*i)->getUserState().getState() == ts);
1369          if (match && test == any)
1370             return true;
1371          if (!match && test == all)
1372             return false;
1373       }
1374       return (test == all);
1375    }
1376
1377    bool operator()(Thread::ptr t) {
1378       int_thread *llthrd = t->llthrd();
1379       if (!llthrd)
1380          return false;
1381       int_process *llproc = llthrd->llproc();
1382       llproc->clearLastError();
1383       bool match = (llthrd->getUserState().getState() == ts);
1384       if (match && test == any)
1385          return true;
1386       if (!match && test == all)
1387          return false;
1388       return (test == all);
1389    }
1390 };
1391
1392 bool ProcessSet::anyThreadStopped() const
1393 {
1394    MTLock lock_this_func;
1395    return any_match(procset->begin(), procset->end(), test_thr(test_thr::any, int_thread::stopped));
1396 }
1397
1398 bool ProcessSet::allThreadsStopped() const
1399 {
1400    MTLock lock_this_func;
1401    return all_match(procset->begin(), procset->end(), test_thr(test_thr::all, int_thread::stopped));
1402 }
1403
1404 ProcessSet::ptr ProcessSet::getAllThreadStoppedSubset() const
1405 {
1406    MTLock lock_this_func;
1407    return create_subset(procset->begin(), procset->end(), test_thr(test_thr::all, int_thread::stopped));
1408 }
1409
1410 ProcessSet::ptr ProcessSet::getAnyThreadStoppedSubset() const
1411 {
1412    MTLock lock_this_func;
1413    return create_subset(procset->begin(), procset->end(), test_thr(test_thr::any, int_thread::stopped));
1414 }
1415
1416 bool ProcessSet::anyThreadRunning() const
1417 {
1418    MTLock lock_this_func;
1419    return any_match(procset->begin(), procset->end(), test_thr(test_thr::any, int_thread::running));
1420 }
1421
1422 bool ProcessSet::allThreadsRunning() const
1423 {
1424    MTLock lock_this_func;
1425    return all_match(procset->begin(), procset->end(), test_thr(test_thr::all, int_thread::running));
1426 }
1427
1428 ProcessSet::ptr ProcessSet::getAllThreadRunningSubset() const
1429 {
1430    MTLock lock_this_func;
1431    return create_subset(procset->begin(), procset->end(), test_thr(test_thr::all, int_thread::running));
1432 }
1433
1434 ProcessSet::ptr ProcessSet::getAnyThreadRunningSubset() const
1435 {
1436    MTLock lock_this_func;
1437    return create_subset(procset->begin(), procset->end(), test_thr(test_thr::any, int_thread::running));
1438 }
1439
1440 bool ProcessSet::continueProcs() const
1441 {
1442    bool had_error = false;
1443    MTLock lock_this_func(MTLock::deliver_callbacks);
1444
1445    if (int_process::isInCB()) {
1446       perr_printf("User attempted call on process while in CB, erroring.");
1447       for_each(procset->begin(), procset->end(), setError(err_incallback, "Cannot continueProc from callback\n"));
1448       return false;
1449    }
1450
1451    procset_iter iter("continueProc", had_error, ERR_CHCK_NORM);
1452    for (int_processSet::iterator i = iter.begin(procset); i != iter.end(); i = iter.inc()) {
1453       Process::ptr p = *i;
1454       int_process *proc = p->llproc();
1455
1456       pthrd_printf("User continuing entire process %d\n", proc->getPid());
1457       proc->threadPool()->initialThread()->getUserState().setStateProc(int_thread::running);
1458       proc->throwNopEvent();
1459    }
1460    return !had_error;
1461 }
1462
1463 bool ProcessSet::stopProcs() const
1464 {
1465    MTLock lock_this_func(MTLock::deliver_callbacks);
1466    bool had_error = false;
1467    bool had_success = false;
1468    if (int_process::isInCB()) {
1469       perr_printf("User attempted call on process while in CB, erroring.");
1470       for_each(procset->begin(), procset->end(), setError(err_incallback, "Cannot continueProc from callback\n"));
1471       return false;
1472    }
1473    int_processSet error_set;
1474    procset_iter iter("stopProc", had_error, ERR_CHCK_NORM);
1475    for (int_processSet::iterator i = iter.begin(procset); i != iter.end(); i = iter.inc()) {
1476       Process::ptr p = *i;
1477       int_process *proc = p->llproc();
1478       pthrd_printf("User stopping entire process %d\n", proc->getPid());
1479       proc->threadPool()->initialThread()->getUserState().setStateProc(int_thread::stopped);
1480       proc->throwNopEvent();
1481       had_success = true;
1482    }
1483
1484    if (!had_success)
1485       return false;
1486
1487    bool result = int_process::waitAndHandleEvents(false);
1488    if (!result) {
1489       perr_printf("Internal error calling waitAndHandleEvents\n");
1490       for_each(procset->begin(), procset->end(), 
1491                setError(err_internal, "Error while calling waitAndHandleForProc from process stop\n"));
1492       return false;
1493    }
1494
1495    for (int_processSet::iterator i = procset->begin(); i != procset->end(); i++) {
1496       int_process *proc = (*i)->llproc();
1497       if (!proc) {
1498          perr_printf("Process %d exited while waiting for user stop, erroring\n", (*i)->getPid());
1499          (*i)->setLastError(err_exited, "Process exited while being stopped.\n");
1500          had_error = true;
1501          continue;
1502       }
1503    }
1504    return !had_error;
1505 }
1506
1507 static bool do_detach(int_processSet *procset, bool temporary, bool leaveStopped)
1508 {
1509    MTLock lock_this_func(MTLock::deliver_callbacks);
1510    bool had_error = false;
1511    bool had_success = false;
1512
1513    if (int_process::isInCB()) {
1514       perr_printf("User attempted call on process while in CB, erroring.");
1515       for_each(procset->begin(), procset->end(), setError(err_incallback, "Cannot continueProc from callback\n"));
1516       return false;
1517    }
1518
1519    procset_iter iter("detach", had_error, ERR_CHCK_NORM);
1520    for (int_processSet::iterator i = iter.begin(procset); i != iter.end(); i = iter.inc()) {
1521       Process::ptr p = *i;
1522       int_process *proc = p->llproc();
1523
1524       if (temporary && !proc->plat_supportDOTF()) {
1525          perr_printf("Temporary detach not supported on this platform\n");
1526          p->setLastError(err_unsupported, "Temporary detach not supported on this platform\n");
1527          had_error = true;
1528          continue;
1529       }
1530
1531       int_threadPool *tp = proc->threadPool();
1532       bool has_rpc = false;
1533       for (int_threadPool::iterator i = tp->begin(); i != tp->end(); i++) {
1534          int_thread *thr = *i;
1535          if (!thr->getPostedRPCs()->empty() || thr->runningRPC()) {
1536             has_rpc = true;
1537             break;
1538          }
1539       }
1540       if (has_rpc) {
1541          perr_printf("detach on a process with pending RPCs\n");
1542          p->setLastError(err_pendingirpcs, "Process has pending iRPCs, cannot detach\n");
1543          had_error = true;
1544          continue;
1545       }
1546       
1547       proc->throwDetachEvent(temporary, leaveStopped);
1548       had_success = true;
1549    }
1550
1551    if (had_success) {
1552       bool result = int_process::waitAndHandleEvents(false);
1553       if (!result) {
1554          perr_printf("Internal error calling waitAndHandleEvents\n");
1555          for_each(procset->begin(), procset->end(), 
1556                   setError(err_internal, "Error while calling waitAndHandleForProc from detach\n"));
1557          return false;
1558       }
1559    }
1560    
1561    for (int_processSet::iterator i = procset->begin(); i != procset->end(); i++) {
1562       Process::ptr p = *i;
1563       int_process *proc = p->llproc();
1564       
1565       if (!proc && temporary) {
1566          perr_printf("Process exited during temporary detach\n");
1567          p->setLastError(err_exited, "Process exited during temporary detach");
1568          had_error = true;
1569          continue;
1570       }
1571    }
1572
1573    return !had_error;
1574 }
1575
1576 bool ProcessSet::detach(bool leaveStopped) const
1577 {
1578    return do_detach(procset, false, leaveStopped);
1579 }
1580
1581 bool ProcessSet::temporaryDetach() const
1582 {
1583    return do_detach(procset, true, false);
1584 }
1585
1586 bool ProcessSet::reAttach() const
1587 {
1588    bool had_error = false;
1589    MTLock lock_this_func(MTLock::deliver_callbacks);
1590    if (int_process::isInCB()) {
1591       perr_printf("User attempted call on process while in CB, erroring.");
1592       for_each(procset->begin(), procset->end(), setError(err_incallback, "Cannot reAttach from callback\n"));
1593       return false;
1594    }
1595
1596    procset_iter iter("reAttach", had_error, ERR_CHCK_EXITED);
1597    for (int_processSet::iterator i = iter.begin(procset); i != iter.end(); i = iter.inc());
1598
1599    ProcPool()->condvar()->lock();
1600    bool attach_okay = int_process::attach(procset, true);
1601
1602    return !had_error && attach_okay;
1603 }
1604
1605 bool ProcessSet::terminate() const
1606 {
1607    bool had_error = false;
1608    bool run_sync = false;
1609    set<int_process *> to_clean;
1610    pthrd_printf("ProcessSet::terminate entry\n");
1611    MTLock lock_this_func(MTLock::deliver_callbacks);
1612    if (int_process::isInCB()) {
1613       perr_printf("User attempted call on process while in CB, erroring.");
1614       for_each(procset->begin(), procset->end(), setError(err_incallback, "Cannot terminate from callback\n"));
1615       return false;
1616    }
1617
1618 #if defined(os_linux)
1619    pthrd_printf("Clearing queue pre-force-terminate\n");
1620    int_process::waitAndHandleEvents(false);
1621 #endif
1622
1623    // Clean out the event queue before we terminate; otherwise we can race
1624    set<int_process *> procs;
1625    procset_iter iter("terminate", had_error, ERR_CHCK_NORM);
1626    for (int_processSet::iterator i = iter.begin(procset); i != iter.end(); i = iter.inc()) {
1627       Process::ptr p = *i;
1628       int_process *proc = p->llproc();
1629
1630       pthrd_printf("User terminating process %d\n", proc->getPid());
1631
1632       if (!proc->preTerminate()) {
1633          perr_printf("pre-terminate hook failed\n");
1634          p->setLastError(err_internal, "Pre-terminate hook failed\n");
1635          had_error = true;
1636          continue;
1637       }
1638       procs.insert(proc);
1639    }
1640
1641    // Handle anything from preTerminate
1642 #if defined(os_linux)
1643    int_process::waitAndHandleEvents(false);
1644 #endif
1645
1646    ProcPool()->condvar()->lock();
1647
1648    for (set<int_process *>::iterator i = procs.begin(); i != procs.end();) {
1649       int_process *proc = *i;
1650
1651       bool needsSync = false;
1652       bool result = proc->terminate(needsSync);
1653       if (!result) {
1654          pthrd_printf("Terminating process %d failed\n", proc->getPid());
1655          had_error = true;
1656          procs.erase(i++);
1657          continue;
1658       }
1659
1660       if (needsSync) {
1661          run_sync = true;
1662          procs.erase(i++);
1663          continue;
1664       }
1665       i++;
1666    }
1667
1668    ProcPool()->condvar()->broadcast();
1669    ProcPool()->condvar()->unlock();
1670    pthrd_printf("Processes terminated: sync is %d\n", run_sync);
1671    if (run_sync) {
1672      pthrd_printf("Process: waiting on waitAndHandleEvents\n");
1673       bool result = int_process::waitAndHandleEvents(false);
1674       pthrd_printf("Process: back from waitAndHandleEvents\n");
1675       if (!result) {
1676          perr_printf("Internal error calling waitAndHandleEvents\n");
1677          for_each(procset->begin(), procset->end(), 
1678                   setError(err_internal, "Error while calling waitAndHandleEvents from terminate\n"));
1679          had_error = true;
1680       }
1681    }
1682    for (set<int_process *>::iterator i = procs.begin(); i != procs.end(); i++) {
1683       int_process *proc = *i;
1684       HandlerPool *hp = proc->handlerPool();
1685       delete proc;
1686       delete hp;
1687    }
1688
1689    return !had_error;
1690 }
1691
1692 AddressSet::ptr ProcessSet::mallocMemory(size_t size) const
1693 {
1694    MTLock lock_this_func(MTLock::deliver_callbacks);
1695    bool had_error = false;
1696    if (int_process::isInCB()) {
1697       perr_printf("User attempted call on process while in CB, erroring.");
1698       for_each(procset->begin(), procset->end(), setError(err_incallback, "Cannot mallocMemory from callback\n"));
1699       return AddressSet::newAddressSet();
1700    }
1701
1702    AddressSet::ptr aresult = AddressSet::newAddressSet();
1703    procset_iter iter("mallocMemory", had_error, ERR_CHCK_NORM);
1704    for (int_processSet::iterator i = iter.begin(procset); i != iter.end(); i = iter.inc()) {
1705       aresult->insert(0, *i);
1706    }
1707    
1708    int_process::infMalloc(size, aresult->get_iaddrs(), false);
1709    return aresult;
1710 }
1711
1712 bool ProcessSet::mallocMemory(size_t size, AddressSet::ptr location) const
1713 {
1714    MTLock lock_this_func(MTLock::deliver_callbacks);
1715    bool had_error = false;
1716    if (int_process::isInCB()) {
1717       perr_printf("User attempted call on process while in CB, erroring.");
1718       for_each(procset->begin(), procset->end(), setError(err_incallback, "Cannot mallocMemory from callback\n"));
1719       return false;
1720    }
1721    
1722    addrset_iter iter("mallocMemory", had_error, ERR_CHCK_NORM);
1723    for (int_addressSet::iterator i = location->iaddrs->begin(); i != location->iaddrs->end(); i++);
1724
1725    return int_process::infMalloc(size, location->iaddrs, true);
1726 }
1727
1728 bool ProcessSet::freeMemory(AddressSet::ptr addrset) const
1729 {
1730    bool had_error = false;
1731    MTLock lock_this_func(MTLock::deliver_callbacks);
1732    if (int_process::isInCB()) {
1733       perr_printf("User attempted call on process while in CB, erroring.");
1734       for_each(procset->begin(), procset->end(), setError(err_incallback, "Cannot freeMemory from callback\n"));
1735       return false;
1736    }
1737
1738    addrset_iter iter("free memory", had_error, ERR_CHCK_NORM);
1739    for (int_addressSet::iterator i = iter.begin(addrset); i != iter.end(); i = iter.inc());
1740
1741    bool free_result = int_process::infFree(addrset->iaddrs);
1742    return !had_error && free_result;   
1743 }
1744
1745 bool ProcessSet::readMemory(AddressSet::ptr addrset, multimap<Process::ptr, void *> &mem_result, size_t size) const
1746 {
1747    //Use the read_t form of readMemory below
1748    multimap<Process::const_ptr, read_t> all_reads;
1749    for (int_addressSet::iterator i = addrset->iaddrs->begin(); i != addrset->iaddrs->end(); i++) {
1750       Process::const_ptr p = i->second;
1751       read_t r;
1752       r.addr = i->first;
1753       r.size = size;
1754       r.buffer = malloc(size);
1755       r.err = 0;
1756       all_reads.insert(make_pair(p, r));
1757    }
1758
1759    readMemory(all_reads);
1760
1761    bool had_error = false;
1762    for (multimap<Process::const_ptr, read_t>::iterator i = all_reads.begin(); i != all_reads.end(); i++) {
1763       Process::const_ptr p = i->first;
1764       const read_t &r = i->second;
1765       if (r.err) {
1766          free(r.buffer);
1767          had_error = true;
1768          continue;
1769       }
1770       mem_result.insert(make_pair(p->llproc()->proc(), r.buffer));
1771    }
1772    return !had_error;
1773 }
1774
1775 struct bufferCompare {
1776    void *buffer;
1777    size_t size;
1778    uint32_t checksum;
1779    bool use_checksum;
1780
1781    bufferCompare(void *b, size_t s, bool uc) {
1782       buffer = b;
1783       size = s;
1784       use_checksum = uc;
1785       boost::crc_32_type crcComputer;
1786       crcComputer.process_bytes(b, s);
1787       checksum = crcComputer.checksum();
1788    }
1789    bool operator<(const bufferCompare &bc) const {
1790       if (use_checksum)
1791          return checksum < bc.checksum;
1792       if (checksum < bc.checksum)
1793          return true;
1794       if (checksum > bc.checksum)
1795          return false;
1796       for (unsigned i=0; i<size; i++) {
1797          char c1 = ((char *) buffer)[i];
1798          char c2 = ((char *) bc.buffer)[i];
1799          if (c1 != c2) return c1 < c2;
1800       }
1801       return false;
1802    }
1803 };
1804
1805 bool ProcessSet::readMemory(AddressSet::ptr addrset, map<void *, ProcessSet::ptr> &mem_result, size_t size, 
1806                             bool use_checksum) const
1807 {
1808    multimap<Process::ptr, void *> initial_result;
1809    bool had_error = !readMemory(addrset, initial_result, size);
1810
1811    map<bufferCompare, ProcessSet::ptr> unique_results;
1812    for (multimap<Process::ptr, void *>::iterator i = initial_result.begin(); i != initial_result.end(); i++) {
1813       Process::const_ptr proc = i->first;
1814       void *buffer = i->second;
1815
1816       bufferCompare bc(buffer, size, use_checksum);
1817       map<bufferCompare, ProcessSet::ptr>::iterator j = unique_results.find(bc);
1818       
1819       if (j != unique_results.end()) {
1820          ProcessSet::ptr ps = j->second;
1821          ps->insert(proc);
1822          free(buffer);
1823       }
1824       else {
1825          ProcessSet::ptr ps = newProcessSet(proc);
1826          unique_results.insert(make_pair(bc, ps));
1827       }
1828    }
1829
1830    for (map<bufferCompare, ProcessSet::ptr>::iterator i = unique_results.begin(); i != unique_results.end(); i++) {
1831       mem_result.insert(make_pair(i->first.buffer, i->second));
1832    }
1833    return !had_error;
1834 }
1835
1836 bool ProcessSet::readMemory(multimap<Process::const_ptr, read_t> &addrs) const
1837 {
1838    MTLock lock_this_func;
1839    bool had_error = false;
1840    for_each(procset->begin(), procset->end(), clearError());
1841
1842    set<response::ptr> all_responses;
1843    map<response::ptr, multimap<Process::const_ptr, read_t>::const_iterator> resps_to_procs;
1844
1845    readmap_iter iter("read memory", had_error, ERR_CHCK_ALL);
1846    for (readmap_iter::i_t i = iter.begin(&addrs); i != iter.end(); i = iter.inc()) {
1847       Process::const_ptr p = i->first;
1848       int_process *proc = p->llproc();
1849       const read_t &r = i->second;
1850       
1851       Address addr = r.addr;
1852       void *buffer = r.buffer;
1853       size_t size = r.size;
1854       pthrd_printf("User wants to read memory from 0x%lx of size %lu in process %d\n", 
1855                    addr, (unsigned long) size, proc->getPid());
1856
1857       mem_response::ptr resp = mem_response::createMemResponse((char *) buffer, size);
1858       bool result = proc->readMem(addr, resp);
1859       if (!result) {
1860          pthrd_printf("Error reading from memory %lx on target process %d\n", addr, proc->getPid());
1861          (void)resp->isReady();
1862          free(buffer);
1863          had_error = true;
1864          continue;
1865       }
1866       all_responses.insert(resp);
1867       resps_to_procs[resp] = i;
1868    }
1869
1870    int_process::waitForAsyncEvent(all_responses);
1871
1872    map<response::ptr, multimap<Process::const_ptr, read_t>::const_iterator>::iterator i;
1873    for (i = resps_to_procs.begin(); i != resps_to_procs.end(); i++) {
1874       mem_response::ptr resp = i->first->getMemResponse();
1875       Process::const_ptr p = i->second->first;
1876       int_process *proc = p->llproc();
1877       read_t &read_result = const_cast<read_t &>(i->second->second);
1878       if (resp->hasError()) {
1879          pthrd_printf("Error reading from memory %lx on target process %d\n",
1880                       resp->lastBase(), p->getPid());
1881          had_error = true;
1882          read_result.err = resp->errorCode();
1883          proc->setLastError(read_result.err, proc->getLastErrorMsg());
1884       }
1885       read_result.err = 0;
1886    }
1887    return !had_error;
1888 }
1889
1890 bool ProcessSet::writeMemory(AddressSet::ptr addrset, const void *buffer, size_t size) const
1891 {
1892    MTLock lock_this_func;
1893    bool had_error = false;
1894
1895    set<response::ptr> all_responses;
1896
1897    addrset_iter iter("write memory", had_error, ERR_CHCK_ALL);
1898    for (int_addressSet::iterator i = iter.begin(addrset); i != iter.end(); i = iter.inc()) {
1899       Process::ptr p = i->second;
1900       int_process *proc = p->llproc();
1901       Address addr = i->first;
1902
1903       result_response::ptr resp = result_response::createResultResponse();
1904       bool result = proc->writeMem(buffer, addr, size, resp);
1905       if (!result) {
1906          perr_printf("Failed to write memory to %d at %lx\n", proc->getPid(), addr);
1907          had_error = true;
1908          continue;
1909       }
1910       all_responses.insert(resp);
1911    }
1912
1913    int_process::waitForAsyncEvent(all_responses);
1914
1915    for (set<response::ptr>::iterator i = all_responses.begin(); i != all_responses.end(); i++) {
1916       response::ptr resp = *i;
1917       if (resp->hasError())
1918          had_error = true;
1919    }
1920
1921    return !had_error;
1922 }
1923
1924 bool ProcessSet::writeMemory(multimap<Process::const_ptr, write_t> &addrs) const
1925 {
1926    MTLock lock_this_func;
1927    bool had_error = false;
1928    for_each(procset->begin(), procset->end(), clearError());
1929
1930    set<response::ptr> all_responses;
1931    map<response::ptr, multimap<Process::const_ptr, write_t>::const_iterator> resps_to_procs;
1932
1933    writemap_iter iter("read memory", had_error, ERR_CHCK_ALL);
1934    for (writemap_iter::i_t i = iter.begin(&addrs); i != iter.end(); i = iter.inc()) {
1935       Process::const_ptr p = i->first;
1936       int_process *proc = p->llproc();
1937       const write_t &w = i->second;
1938
1939       result_response::ptr resp = result_response::createResultResponse();
1940       bool result = proc->writeMem(w.buffer, w.addr, w.size, resp);
1941       if (!result) {
1942          perr_printf("Failed to write memory to %d at %lx", proc->getPid(), w.addr);
1943          (void)resp->isReady();
1944          had_error = true;
1945          continue;
1946       }
1947       all_responses.insert(resp);
1948       resps_to_procs.insert(make_pair(resp, i));
1949    }
1950
1951    int_process::waitForAsyncEvent(all_responses);
1952    
1953    map<response::ptr, multimap<Process::const_ptr, write_t>::const_iterator>::iterator i;
1954    for (i = resps_to_procs.begin(); i != resps_to_procs.end(); i++) {
1955       result_response::ptr resp = i->first->getResultResponse();
1956       Process::const_ptr p = i->second->first;
1957       int_process *proc = p->llproc();
1958       write_t &write_result = const_cast<write_t &>(i->second->second);
1959
1960       if (resp->hasError()) {
1961          pthrd_printf("Error reading from memory %lx on target process %d\n",
1962                       write_result.addr, p->getPid());
1963          had_error = true;
1964          write_result.err = resp->errorCode();
1965          proc->setLastError(write_result.err, proc->getLastErrorMsg());
1966       }
1967       write_result.err = 0;
1968    }
1969    return !had_error;
1970 }
1971
1972 static bool addBreakpointWorker(set<pair<int_process *, bp_install_state *> > &bp_installs)
1973 {
1974    bool had_error = false;
1975    bool result;
1976
1977    set<response::ptr> all_responses;
1978    for (set<pair<int_process *, bp_install_state *> >::iterator i = bp_installs.begin(); 
1979         i != bp_installs.end();) 
1980    {
1981       int_process *proc = i->first;
1982       bp_install_state *is = i->second;
1983       
1984       result = proc->addBreakpoint_phase1(is);
1985       if (!result) {
1986          had_error = true;
1987          delete is;
1988          bp_installs.erase(i++);
1989          continue;
1990       }
1991       all_responses.insert(is->mem_resp);
1992       i++;
1993    }
1994
1995    result = int_process::waitForAsyncEvent(all_responses);
1996    if (!result) {
1997       perr_printf("Error waiting for async results during bp insertion\n");
1998       had_error = true;
1999    }
2000    all_responses.clear();
2001
2002    for (set<pair<int_process *, bp_install_state *> >::iterator i = bp_installs.begin(); 
2003         i != bp_installs.end();) 
2004    {
2005       int_process *proc = i->first;
2006       bp_install_state *is = i->second;
2007       
2008       result = proc->addBreakpoint_phase2(is);
2009       if (!result) {
2010          had_error = true;
2011          delete is;
2012          bp_installs.erase(i++);
2013          continue;
2014       }
2015       all_responses.insert(is->res_resp);
2016       i++;
2017    }
2018
2019    result = int_process::waitForAsyncEvent(all_responses);
2020    if (!result) {
2021       perr_printf("Error waiting for async results during bp insertion\n");
2022       had_error = true;
2023    }
2024
2025    for (set<pair<int_process *, bp_install_state *> >::iterator i = bp_installs.begin(); 
2026         i != bp_installs.end();) {
2027       int_process *proc = i->first;
2028       bp_install_state *is = i->second;
2029       
2030       result = proc->addBreakpoint_phase3(is);
2031       if (!result) {
2032          had_error = true;
2033       }
2034       delete is;
2035       bp_installs.erase(i++);
2036       continue;
2037    }
2038
2039    return !had_error;
2040 }
2041
2042 bool ProcessSet::addBreakpoint(AddressSet::ptr addrset, Breakpoint::ptr bp) const
2043 {
2044    MTLock lock_this_func;
2045    bool had_error = false;
2046
2047    set<pair<int_process *, bp_install_state *> > bp_installs;
2048    addrset_iter iter("Breakpoint add", had_error, ERR_CHCK_ALL);
2049    for (int_addressSet::iterator i = iter.begin(addrset); i != iter.end(); i = iter.inc()) {
2050       Process::ptr p = i->second;
2051       int_process *proc = p->llproc();
2052       Address addr = i->first;
2053       
2054       bp_install_state *is = new bp_install_state();
2055       is->addr = addr;
2056       is->bp = bp->llbp();
2057       bp_installs.insert(make_pair(proc, is));
2058    }
2059
2060    return addBreakpointWorker(bp_installs) && !had_error;
2061 }
2062
2063 bool ProcessSet::rmBreakpoint(AddressSet::ptr addrset, Breakpoint::ptr bp) const
2064 {
2065    MTLock lock_this_func;
2066    bool had_error = false;
2067    for_each(procset->begin(), procset->end(), clearError());
2068
2069    set<response::ptr> all_responses;
2070    map<response::ptr, int_process *> resp_to_proc;
2071
2072    addrset_iter iter("Breakpoint remove", had_error, ERR_CHCK_ALL);
2073    for (int_addressSet::iterator i = iter.begin(addrset); i != iter.end(); i = iter.inc()) {
2074       Process::ptr p = i->second;
2075       int_process *proc = p->llproc();
2076       Address addr = i->first;
2077
2078       set<response::ptr> resps;
2079       bool result = proc->removeBreakpoint(addr, bp->llbp(), all_responses);
2080       if (!result) {
2081          pthrd_printf("Failed to rmBreakpoint on %d\n", proc->getPid());
2082          had_error = true;
2083          continue;
2084       }
2085       all_responses.insert(resps.begin(), resps.end());
2086       for (set<response::ptr>::iterator i=resps.begin(); i != resps.end(); i++)
2087          resp_to_proc.insert(make_pair(*i, proc));
2088    }
2089
2090    bool result = int_process::waitForAsyncEvent(all_responses);
2091    if (!result) {
2092       pthrd_printf("Failed to wait for async events\n");
2093       had_error = true;
2094    }
2095
2096    for (set<response::ptr>::iterator i = all_responses.begin(); i != all_responses.end(); i++) {
2097       response::ptr resp = *i;
2098       if (!resp->hasError())
2099          continue;
2100       had_error = true;
2101       int_process *proc = resp_to_proc[resp];
2102       assert(proc);
2103       proc->setLastError(resp->errorCode(), proc->getLastErrorMsg());
2104    }
2105
2106    return !had_error;
2107 }
2108
2109 bool ProcessSet::postIRPC(const multimap<Process::const_ptr, IRPC::ptr> &rpcs) const
2110 {
2111    MTLock lock_this_func;
2112    bool had_error = false;
2113
2114    rpcmap_iter iter("Post RPC", had_error, ERR_CHCK_NORM);
2115    for (
2116       multimap<Process::const_ptr, IRPC::ptr>::const_iterator i = iter.begin(&rpcs); 
2117       i != iter.end();
2118       i = iter.inc()) {
2119       Process::const_ptr p = i->first;
2120       int_process *proc = p->llproc();
2121       IRPC::ptr rpc = i->second;
2122
2123       bool result = rpcMgr()->postRPCToProc(proc, rpc->llrpc()->rpc);
2124       if (!result) {
2125          pthrd_printf("postRPCToProc failed on %d\n", proc->getPid());
2126          had_error = true;
2127       }
2128    }
2129    return !had_error;
2130 }
2131
2132 bool ProcessSet::postIRPC(IRPC::ptr irpc, multimap<Process::ptr, IRPC::ptr> *result) const
2133 {
2134    MTLock lock_this_func;
2135    bool had_error = false;
2136
2137    procset_iter iter("post RPC", had_error, ERR_CHCK_NORM);
2138    for (int_processSet::iterator i = iter.begin(procset); i != iter.end(); i = iter.inc()) {
2139       Process::ptr p = *i;
2140       int_process *proc = p->llproc();
2141       IRPC::ptr local_rpc = IRPC::createIRPC(irpc);
2142       
2143       bool bresult = rpcMgr()->postRPCToProc(proc, local_rpc->llrpc()->rpc);
2144       if (!bresult) {
2145          pthrd_printf("postRPCToProc failed on %d\n", proc->getPid());
2146          had_error = true;
2147          continue;
2148       }
2149       
2150       if (result) 
2151          result->insert(make_pair(p, local_rpc));
2152    }
2153    return !had_error;
2154 }
2155
2156 bool ProcessSet::postIRPC(IRPC::ptr irpc, AddressSet::ptr addrset, multimap<Process::ptr, IRPC::ptr> *result) const
2157 {
2158    MTLock lock_this_func;
2159    bool had_error = false;
2160
2161    addrset_iter iter("post RPC", had_error, ERR_CHCK_NORM);
2162    for (int_addressSet::iterator i = iter.begin(addrset); i != iter.end(); i = iter.inc()) {
2163       Process::ptr p = i->second;
2164       int_process *proc = p->llproc();
2165       Address addr = i->first;
2166       IRPC::ptr local_rpc = IRPC::createIRPC(irpc, addr);
2167       
2168       bool bresult = rpcMgr()->postRPCToProc(proc, local_rpc->llrpc()->rpc);
2169       if (!bresult) {
2170          pthrd_printf("postRPCToProc failed on %d\n", proc->getPid());
2171          had_error = true;
2172          continue;
2173       }
2174       
2175       if (result) 
2176          result->insert(make_pair(p, local_rpc));
2177    }
2178    return !had_error;
2179 }
2180
2181 ProcessSet::iterator::iterator(int_processSet::iterator i)
2182 {
2183    int_iter = i;
2184 }
2185
2186 ProcessSet::iterator::iterator()
2187 {
2188 }
2189
2190 ProcessSet::iterator::~iterator()
2191 {
2192 }
2193
2194
2195 Process::ptr ProcessSet::iterator::operator*() const
2196 {
2197    return *int_iter;
2198 }
2199
2200
2201 bool ProcessSet::iterator::operator==(const ProcessSet::iterator &i) const
2202 {
2203    return int_iter == i.int_iter;
2204 }
2205
2206 bool ProcessSet::iterator::operator!=(const ProcessSet::iterator &i) const
2207 {
2208    return int_iter != i.int_iter;
2209 }
2210
2211 ProcessSet::iterator ProcessSet::iterator::operator++()
2212 {
2213    return ProcessSet::iterator(++int_iter);
2214 }
2215
2216 ProcessSet::iterator ProcessSet::iterator::operator++(int)
2217 {
2218    return ProcessSet::iterator(int_iter++);
2219 }
2220
2221 ProcessSet::const_iterator::const_iterator()
2222 {
2223 }
2224
2225 ProcessSet::const_iterator::~const_iterator()
2226 {
2227 }
2228
2229 Process::ptr ProcessSet::const_iterator::operator*() const
2230 {
2231    return *int_iter;
2232 }
2233
2234 bool ProcessSet::const_iterator::operator==(const ProcessSet::const_iterator &i) const
2235 {
2236    return int_iter == i.int_iter;
2237 }
2238
2239 bool ProcessSet::const_iterator::operator!=(const ProcessSet::const_iterator &i) const
2240 {
2241    return int_iter != i.int_iter;
2242 }
2243
2244 ProcessSet::const_iterator ProcessSet::const_iterator::operator++()
2245 {
2246    return ProcessSet::const_iterator(++int_iter);
2247 }
2248
2249 ProcessSet::const_iterator ProcessSet::const_iterator::operator++(int)
2250 {
2251    return ProcessSet::const_iterator(int_iter++);
2252 }
2253
2254 int_processSet *ProcessSet::getIntProcessSet() {
2255    return procset;
2256 }
2257
2258 struct thread_strip_const {
2259    Thread::ptr operator()(Thread::const_ptr t) const {
2260       return pc_const_cast<Thread>(t);
2261    }
2262 };
2263
2264
2265 ThreadSet::ThreadSet() :
2266    features(NULL)
2267 {
2268    ithrset = new int_threadSet;
2269 }
2270
2271 ThreadSet::~ThreadSet()
2272 {
2273    if (ithrset) {
2274       delete ithrset;
2275       ithrset = NULL;
2276    }
2277    if (features) {
2278       delete features;
2279       features = NULL;
2280    }
2281 }
2282
2283 ThreadSet::ptr ThreadSet::newThreadSet()
2284 {
2285    return ThreadSet::ptr(new ThreadSet());
2286 }
2287
2288 ThreadSet::ptr ThreadSet::newThreadSet(const ThreadPool &threadp)
2289 {
2290    ThreadSet::ptr newts = ThreadSet::ptr(new ThreadSet());
2291    int_threadSet* &newset = newts->ithrset;
2292    
2293    transform(threadp.begin(), threadp.end(), inserter(*newset, newset->end()), thread_strip_const());
2294    return newts;
2295 }
2296
2297 ThreadSet::ptr ThreadSet::newThreadSet(const set<Thread::const_ptr> &threads)
2298 {
2299    ThreadSet::ptr newts = ThreadSet::ptr(new ThreadSet());
2300    int_threadSet* &newset = newts->ithrset;
2301    transform(threads.begin(), threads.end(), inserter(*newset, newset->end()), thread_strip_const());
2302    return newts;
2303 }
2304
2305 ThreadSet::ptr ThreadSet::newThreadSet(Thread::ptr thr) {
2306    ThreadSet::ptr newts = ThreadSet::ptr(new ThreadSet());
2307    newts->ithrset->insert(thr);
2308    return newts;
2309 }
2310
2311 ThreadSet::ptr ThreadSet::newThreadSet(ProcessSet::ptr ps, bool initial_only)
2312 {
2313    MTLock lock_this_func;
2314    bool had_error = false;
2315
2316    ThreadSet::ptr newts = ThreadSet::ptr(new ThreadSet());
2317    int_threadSet* &newset = newts->ithrset;
2318
2319    procset_iter iter("New thread group", had_error, ERR_CHCK_NORM);
2320    for (procset_iter::i_t i = iter.begin(ps->procset); i != iter.end(); i = iter.inc()) {
2321       if (had_error) {
2322          pthrd_printf("Failed to create new thread group\n");
2323          return ThreadSet::ptr();
2324       }
2325       Process::ptr proc = *i;
2326       if (initial_only) {
2327          newset->insert(proc->threads().getInitialThread());
2328       }
2329       else {
2330          ThreadPool &pool = proc->threads();
2331          for (ThreadPool::iterator j = pool.begin(); j != pool.end(); j++) {
2332             newset->insert(*j);
2333          }
2334       }
2335    }
2336    return newts;
2337 }
2338
2339 ThreadSet::ptr ThreadSet::set_union(ThreadSet::ptr tp) const
2340 {
2341    ThreadSet::ptr newts = ThreadSet::ptr(new ThreadSet);
2342    int_threadSet *me = ithrset;
2343    int_threadSet *you = tp->ithrset;
2344    int_threadSet *them = newts->ithrset;
2345
2346    std::set_union(me->begin(), me->end(), you->begin(), you->end(), inserter(*them, them->end()));
2347    return newts;
2348 }
2349
2350 ThreadSet::ptr ThreadSet::set_intersection(ThreadSet::ptr tp) const
2351 {
2352    ThreadSet::ptr newts = ThreadSet::ptr(new ThreadSet);
2353    int_threadSet *me = ithrset;
2354    int_threadSet *you = tp->ithrset;
2355    int_threadSet *them = newts->ithrset;
2356
2357    std::set_intersection(me->begin(), me->end(), you->begin(), you->end(), inserter(*them, them->end()));
2358    return newts;
2359 }
2360
2361 ThreadSet::ptr ThreadSet::set_difference(ThreadSet::ptr tp) const
2362 {
2363    ThreadSet::ptr newts = ThreadSet::ptr(new ThreadSet);
2364    int_threadSet *me = ithrset;
2365    int_threadSet *you = tp->ithrset;
2366    int_threadSet *them = newts->ithrset;
2367
2368    std::set_difference(me->begin(), me->end(), you->begin(), you->end(), inserter(*them, them->end()));
2369    return newts;
2370 }
2371
2372 ThreadSet::iterator ThreadSet::begin() {
2373    return iterator(ithrset->begin());
2374 }
2375
2376 ThreadSet::iterator ThreadSet::end() {
2377    return iterator(ithrset->end());
2378 }
2379
2380 ThreadSet::iterator ThreadSet::find(Thread::const_ptr p) {
2381    return iterator(ithrset->find(pc_const_cast<Thread>(p)));
2382 }
2383
2384 ThreadSet::const_iterator ThreadSet::begin() const {
2385    return const_iterator(ithrset->begin());
2386 }
2387
2388 ThreadSet::const_iterator ThreadSet::end() const {
2389    return const_iterator(ithrset->end());
2390 }
2391
2392 ThreadSet::const_iterator ThreadSet::find(Thread::const_ptr p) const {
2393    return const_iterator(ithrset->find(pc_const_cast<Thread>(p)));
2394 }
2395
2396 bool ThreadSet::empty() const {
2397    return ithrset->empty();
2398 }
2399
2400 size_t ThreadSet::size() const {
2401    return ithrset->size();
2402 }
2403
2404 int_threadSet *ThreadSet::getIntThreadSet() const {
2405    return ithrset;
2406 }
2407
2408 pair<ThreadSet::iterator, bool> ThreadSet::insert(Thread::const_ptr p) {
2409    pair<int_threadSet::iterator, bool> result = ithrset->insert(pc_const_cast<Thread>(p));
2410    return pair<ThreadSet::iterator, bool>(ThreadSet::iterator(result.first), result.second);
2411 }
2412
2413 void ThreadSet::erase(iterator pos)
2414 {
2415    ithrset->erase(pos.int_iter);
2416 }
2417
2418 size_t ThreadSet::erase(Thread::const_ptr t)
2419 {
2420    ThreadSet::iterator i = find(t);
2421    if (i == end()) return 0;
2422    erase(i);
2423    return 1;
2424 }
2425
2426 void ThreadSet::clear()
2427 {
2428    ithrset->clear();
2429 }
2430
2431 ThreadSet::ptr ThreadSet::getErrorSubset() const
2432 {
2433    MTLock lock_this_func;
2434
2435    ThreadSet::ptr errts = newThreadSet();
2436    for (const_iterator i = begin(); i != end(); i++) {
2437       Thread::ptr thr = *i;
2438       Process::ptr proc = thr->getProcess();
2439       if (!proc) {
2440          errts->insert(thr);
2441          continue;
2442       }
2443       if (proc->getLastError() == err_none) {
2444          continue;
2445       }
2446       errts->insert(thr);
2447    }
2448    return errts;
2449 }
2450
2451 void ThreadSet::getErrorSubsets(map<ProcControlAPI::err_t, ThreadSet::ptr> &err_sets) const
2452 {
2453    MTLock lock_this_func;
2454
2455    for (const_iterator i = begin(); i != end(); i++) {
2456       Thread::ptr thr = *i;
2457       Process::ptr proc = thr->getProcess();
2458  
2459      ProcControlAPI::err_t err = proc->getLastError();
2460       if (err == err_none)
2461          continue;
2462       map<err_t, ThreadSet::ptr>::iterator j = err_sets.find(err);
2463       ThreadSet::ptr ts;
2464       if (j != err_sets.end()) {
2465          ts = j->second;
2466       }
2467       else {
2468          ts = ThreadSet::newThreadSet();
2469          err_sets[err] = ts;
2470       }
2471       ts->insert(thr);
2472    }   
2473 }
2474
2475
2476 bool ThreadSet::anyStopped() const
2477 {
2478    MTLock lock_this_func;
2479    return any_match(ithrset->begin(), ithrset->end(), test_thr(test_thr::any, int_thread::stopped));
2480 }
2481
2482 bool ThreadSet::allStopped() const
2483 {
2484    MTLock lock_this_func;
2485    return all_match(ithrset->begin(), ithrset->end(), test_thr(test_thr::all, int_thread::stopped));
2486 }
2487
2488 ThreadSet::ptr ThreadSet::getStoppedSubset() const
2489 {
2490    MTLock lock_this_func;
2491    return create_thrsubset(ithrset->begin(), ithrset->end(), test_thr(test_thr::any, int_thread::stopped));
2492 }
2493
2494 bool ThreadSet::anyRunning() const
2495 {
2496    MTLock lock_this_func;
2497    return any_match(ithrset->begin(), ithrset->end(), test_thr(test_thr::any, int_thread::running));
2498 }
2499
2500 bool ThreadSet::allRunning() const
2501 {
2502    MTLock lock_this_func;
2503    return all_match(ithrset->begin(), ithrset->end(), test_thr(test_thr::all, int_thread::running));
2504 }
2505
2506 ThreadSet::ptr ThreadSet::getRunningSubset() const
2507 {
2508    MTLock lock_this_func;
2509    return create_thrsubset(ithrset->begin(), ithrset->end(), test_thr(test_thr::any, int_thread::running));
2510 }
2511
2512 bool ThreadSet::anyTerminated() const
2513 {
2514    MTLock lock_this_func;
2515    return any_match(ithrset->begin(), ithrset->end(), test_terminate());
2516 }
2517
2518 bool ThreadSet::allTerminated() const
2519 {
2520    MTLock lock_this_func;
2521    return all_match(ithrset->begin(), ithrset->end(), test_terminate());
2522 }
2523
2524 ThreadSet::ptr ThreadSet::getTerminatedSubset() const
2525 {
2526    MTLock lock_this_func;
2527    return create_thrsubset(ithrset->begin(), ithrset->end(), test_terminate());
2528 }
2529
2530 struct test_singlestep {
2531    bool operator()(Thread::ptr t) {
2532       Process::ptr p = t->getProcess();
2533       p->clearLastError();
2534       return t->getSingleStepMode();
2535    }
2536 };
2537
2538 bool ThreadSet::anySingleStepMode() const
2539 {
2540    MTLock lock_this_func;
2541    return any_match(ithrset->begin(), ithrset->end(), test_singlestep());
2542 }
2543
2544 bool ThreadSet::allSingleStepMode() const
2545 {
2546    MTLock lock_this_func;
2547    return all_match(ithrset->begin(), ithrset->end(), test_singlestep());
2548 }
2549
2550 ThreadSet::ptr ThreadSet::getSingleStepSubset() const
2551 {
2552    MTLock lock_this_func;
2553    return create_thrsubset(ithrset->begin(), ithrset->end(), test_singlestep());
2554 }
2555
2556 struct test_userthrinfo {
2557    bool operator()(Thread::ptr t) {
2558       Process::ptr p = t->getProcess();
2559       p->clearLastError();
2560       return t->haveUserThreadInfo();
2561    }
2562 };
2563
2564
2565 bool ThreadSet::anyHaveUserThreadInfo() const
2566 {
2567    MTLock lock_this_func;
2568    return any_match(ithrset->begin(), ithrset->end(), test_userthrinfo());
2569 }
2570
2571 bool ThreadSet::allHaveUserThreadInfo() const
2572 {
2573    MTLock lock_this_func;
2574    return all_match(ithrset->begin(), ithrset->end(), test_userthrinfo());
2575 }
2576
2577 ThreadSet::ptr ThreadSet::getHaveUserThreadInfoSubset() const
2578 {
2579    MTLock lock_this_func;
2580    return create_thrsubset(ithrset->begin(), ithrset->end(), test_userthrinfo());
2581 }
2582
2583 bool ThreadSet::getStartFunctions(AddressSet::ptr result) const
2584 {
2585    MTLock lock_this_func;
2586    bool had_error = false;
2587    thrset_iter iter("get start function", had_error, ERR_CHCK_THRD);
2588    for (thrset_iter::i_t i = iter.begin(ithrset); i != iter.end(); i = iter.inc()) {
2589       Thread::ptr t = *i;
2590       Process::ptr p = t->getProcess();
2591       Address addr;
2592       bool bresult = t->llthrd()->getStartFuncAddress(addr);
2593       if (bresult)
2594          result->insert(addr, p);
2595    }
2596    return !had_error;
2597 }
2598
2599 bool ThreadSet::getStackBases(AddressSet::ptr result) const
2600 {
2601    MTLock lock_this_func;
2602    bool had_error = false;
2603    thrset_iter iter("get stack base", had_error, ERR_CHCK_THRD);
2604    for (thrset_iter::i_t i = iter.begin(ithrset); i != iter.end(); i = iter.inc()) {
2605       Thread::ptr t = *i;
2606       Process::ptr p = t->getProcess();
2607       Address addr;
2608       bool bresult = t->llthrd()->getStackBase(addr);
2609       if (bresult)
2610          result->insert(addr, p);
2611    }
2612    return !had_error;
2613 }
2614
2615 bool ThreadSet::getTLSs(AddressSet::ptr result) const
2616 {
2617    MTLock lock_this_func;
2618    bool had_error = false;
2619    thrset_iter iter("get TLS", had_error, ERR_CHCK_THRD);
2620    for (thrset_iter::i_t i = iter.begin(ithrset); i != iter.end(); i = iter.inc()) {
2621       Thread::ptr t = *i;
2622       Process::ptr p = t->getProcess();
2623       Address addr;
2624       bool bresult = t->llthrd()->getTLSPtr(addr);
2625       if (bresult)
2626          result->insert(addr, p);
2627    }
2628    return !had_error;
2629 }
2630
2631 bool ThreadSet::stopThreads() const
2632 {
2633    MTLock lock_this_func;
2634    bool had_error = false;
2635    set<int_process *> all_procs;
2636
2637    thrset_iter iter("stop thread", had_error, ERR_CHCK_THRD);
2638    for (thrset_iter::i_t i = iter.begin(ithrset); i != iter.end(); i = iter.inc()) {
2639       Thread::ptr t = *i;
2640       int_thread *thr = t->llthrd();
2641       int_process *proc = thr->llproc();
2642
2643       thr->getUserState().setState(int_thread::stopped);
2644       all_procs.insert(proc);
2645    }
2646
2647    for (set<int_process *>::iterator i = all_procs.begin(); i != all_procs.end(); i++) {
2648       int_process *proc = *i;
2649       proc->throwNopEvent();
2650    }
2651    return !had_error;
2652 }
2653
2654 bool ThreadSet::continueThreads() const
2655 {
2656    MTLock lock_this_func;
2657    bool had_error = false;
2658    set<int_process *> all_procs;
2659
2660    thrset_iter iter("continue thread", had_error, ERR_CHCK_THRD);
2661    for (thrset_iter::i_t i = iter.begin(ithrset); i != iter.end(); i = iter.inc()) {
2662       Thread::ptr t = *i;
2663       int_thread *thr = t->llthrd();
2664       int_process *proc = thr->llproc();
2665
2666       thr->getUserState().setState(int_thread::running);
2667       all_procs.insert(proc);
2668    }
2669
2670    for (set<int_process *>::iterator i = all_procs.begin(); i != all_procs.end(); i++) {
2671       int_process *proc = *i;
2672       proc->throwNopEvent();
2673    }
2674    return !had_error;
2675 }
2676
2677 bool ThreadSet::setSingleStepMode(bool v) const
2678 {
2679    MTLock lock_this_func;
2680    bool had_error = false;
2681
2682    thrset_iter iter("set single step", had_error, ERR_CHCK_THRD | ERR_CHCK_THRD_STOPPED);
2683    for (thrset_iter::i_t i = iter.begin(ithrset); i != iter.end(); i = iter.inc()) {
2684       Thread::ptr thr = *i;
2685       thr->setSingleStepMode(v);
2686    }
2687    return !had_error;
2688 }
2689
2690 static bool getRegisterWorker(Dyninst::MachRegister reg, int_threadSet *ithrset, 
2691                               set<pair<Thread::ptr, reg_response::ptr> > &thr_to_response)
2692 {
2693    bool had_error = false;
2694    
2695    set<response::ptr> all_responses;
2696    thrset_iter iter("getRegister", had_error, ERR_CHCK_THRD | ERR_CHCK_THRD_STOPPED);
2697    for (thrset_iter::i_t i = iter.begin(ithrset); i != iter.end(); i = iter.inc()) {
2698       Thread::ptr t = *i;
2699       int_thread *thr = t->llthrd();
2700       reg_response::ptr response = reg_response::createRegResponse();
2701       bool result = thr->getRegister(reg, response);
2702       if (!result) {
2703          pthrd_printf("Error reading register response on thread %d/%d\n",
2704                       thr->llproc()->getPid(), thr->getLWP());
2705          had_error = true;
2706          continue;
2707       }
2708
2709       thr_to_response.insert(make_pair(t, response));
2710       all_responses.insert(response);
2711    }
2712
2713    bool result = int_process::waitForAsyncEvent(all_responses);
2714    if (!result) {
2715       pthrd_printf("Error waiting for async events to complete\n");
2716       thr_to_response.clear();
2717       return false;
2718    }
2719
2720    for (set<pair<Thread::ptr, reg_response::ptr > >::iterator i = thr_to_response.begin(); 
2721         i != thr_to_response.end();)
2722    {
2723       Thread::ptr thr = i->first;
2724       reg_response::ptr resp = i->second;
2725
2726       if (resp->hasError()) {
2727          thr->getProcess()->setLastError(resp->errorCode(), thr->getProcess()->getLastErrorMsg());
2728          pthrd_printf("Error in response from %d/%d\n", thr->llthrd()->llproc()->getPid(),
2729                       thr->llthrd()->getLWP());
2730          had_error = true;
2731          thr_to_response.erase(i++);
2732          continue;
2733       }
2734       i++;
2735    }
2736
2737    return !had_error;
2738 }
2739
2740 bool ThreadSet::getRegister(Dyninst::MachRegister reg, map<Thread::ptr, Dyninst::MachRegisterVal> &results) const
2741 {
2742    MTLock lock_this_func;
2743    bool had_error = false;
2744    
2745    set<pair<Thread::ptr, reg_response::ptr> > thr_to_response;
2746    bool result = getRegisterWorker(reg, ithrset, thr_to_response);
2747    if (!result) {
2748       pthrd_printf("Error in getRegisterWorker\n");
2749       had_error = true;
2750    }
2751
2752    for (set<pair<Thread::ptr, reg_response::ptr > >::iterator i = thr_to_response.begin(); 
2753         i != thr_to_response.end(); i++) 
2754    {
2755       Thread::ptr thr = i->first;
2756       reg_response::ptr resp = i->second;
2757
2758       results.insert(make_pair(thr, resp->getResult()));
2759    }
2760    return !had_error;
2761 }
2762
2763 bool ThreadSet::getRegister(Dyninst::MachRegister reg, map<Dyninst::MachRegisterVal, ThreadSet::ptr> &results) const
2764 {
2765    MTLock lock_this_func;
2766    bool had_error = false;
2767    
2768    set<pair<Thread::ptr, reg_response::ptr> > thr_to_response;
2769    bool result = getRegisterWorker(reg, ithrset, thr_to_response);
2770    if (!result) {
2771       pthrd_printf("Error in getRegisterWorker\n");
2772       had_error = true;
2773    }
2774
2775    for (set<pair<Thread::ptr, reg_response::ptr > >::iterator i = thr_to_response.begin(); 
2776         i != thr_to_response.end(); i++) 
2777    {
2778       Thread::ptr thr = i->first;
2779       reg_response::ptr resp = i->second;
2780       MachRegisterVal val = resp->getResult();
2781
2782       ThreadSet::ptr ts;
2783       map<MachRegisterVal, ThreadSet::ptr>::iterator j = results.find(val);
2784       if (j == results.end()) {
2785          ts = ThreadSet::newThreadSet();
2786          results.insert(make_pair(val, ts));
2787       }
2788       else {
2789          ts = j->second;
2790       }
2791       ts->insert(thr);
2792    }
2793    return !had_error;
2794 }
2795
2796 bool ThreadSet::setRegister(Dyninst::MachRegister reg, const map<Thread::const_ptr, Dyninst::MachRegisterVal> &vals) const
2797 {
2798    MTLock lock_this_func;
2799    bool had_error = false;
2800    
2801    set<response::ptr> all_responses;
2802    set<pair<Thread::ptr, result_response::ptr> > thr_to_response;
2803
2804    setreg_iter iter("setRegister", had_error, ERR_CHCK_THRD | ERR_CHCK_THRD_STOPPED);
2805    for (setreg_iter::i_t i = iter.begin(&vals); i != iter.end(); i = iter.inc()) {
2806       Thread::const_ptr t = i->first;
2807       MachRegisterVal val = i->second;
2808       int_thread *thr = t->llthrd();
2809       result_response::ptr response = result_response::createResultResponse();
2810
2811       bool result = thr->setRegister(reg, val, response);
2812       if (!result) {
2813          pthrd_printf("Error writing register response on thread %d/%d\n",
2814                       thr->llproc()->getPid(), thr->getLWP());
2815          had_error = true;
2816          continue;
2817       }
2818
2819       thr_to_response.insert(make_pair(thr->thread(), response));
2820       all_responses.insert(response);
2821    }
2822
2823    bool result = int_process::waitForAsyncEvent(all_responses);
2824    if (!result) {
2825       pthrd_printf("Error waiting for async events to complete\n");
2826       thr_to_response.clear();
2827       return false;
2828    }
2829
2830    for (set<pair<Thread::ptr, result_response::ptr > >::iterator i = thr_to_response.begin(); 
2831         i != thr_to_response.end(); i++)
2832    {
2833       Thread::ptr thr = i->first;
2834       result_response::ptr resp = i->second;
2835
2836       if (resp->hasError() || !resp->getResult()) {
2837          thr->getProcess()->setLastError(resp->errorCode(), thr->getProcess()->getLastErrorMsg());
2838          pthrd_printf("Error in response from %d/%d\n", thr->llthrd()->llproc()->getPid(),
2839                       thr->llthrd()->getLWP());
2840          had_error = true;
2841       }
2842    }
2843
2844    return !had_error;
2845 }
2846
2847 bool ThreadSet::setRegister(Dyninst::MachRegister reg, Dyninst::MachRegisterVal val) const
2848 {
2849    MTLock lock_this_func;
2850    bool had_error = false;
2851    map<Thread::const_ptr, Dyninst::MachRegisterVal> vals;
2852
2853    thrset_iter iter("setRegister", had_error, ERR_CHCK_THRD | ERR_CHCK_THRD_STOPPED);
2854    for (thrset_iter::i_t i = iter.begin(ithrset); i != iter.end(); i = iter.inc()) {
2855       vals.insert(make_pair(*i, val));
2856    }
2857    return setRegister(reg, vals) && !had_error;
2858 }
2859
2860 bool ThreadSet::getAllRegisters(map<Thread::ptr, RegisterPool> &results) const
2861 {
2862    MTLock lock_this_func;
2863    bool had_error = false;
2864
2865    set<response::ptr> all_responses;
2866    set<pair<Thread::ptr, allreg_response::ptr> > thr_to_response;
2867
2868    thrset_iter iter("getAllRegisters", had_error, ERR_CHCK_THRD | ERR_CHCK_THRD_STOPPED);
2869    for (thrset_iter::i_t i = iter.begin(ithrset); i != iter.end(); i = iter.inc()) {
2870       Thread::ptr t = *i;
2871       int_thread *thr = t->llthrd();
2872       int_registerPool *newpool = new int_registerPool();
2873       allreg_response::ptr response = allreg_response::createAllRegResponse(newpool);
2874       bool result = thr->getAllRegisters(response);
2875       if (!result) {
2876          pthrd_printf("Error reading registers on thread %d/%d\n",
2877                       thr->llproc()->getPid(), thr->getLWP());
2878          had_error = true;
2879          delete newpool;
2880          continue;
2881       }
2882
2883       thr_to_response.insert(make_pair(t, response));
2884       all_responses.insert(response);
2885    }
2886
2887    bool result = int_process::waitForAsyncEvent(all_responses);
2888    if (!result) {
2889       pthrd_printf("Error waiting for async events to complete\n");
2890       for (set<pair<Thread::ptr, allreg_response::ptr> >::iterator i = thr_to_response.begin(); 
2891            i != thr_to_response.end(); i++) {
2892          delete i->second->getRegPool();
2893       }
2894       return false;
2895    }
2896
2897    for (set<pair<Thread::ptr, allreg_response::ptr> >::iterator i = thr_to_response.begin(); 
2898         i != thr_to_response.end(); i++)
2899    {
2900       Thread::ptr thr = i->first;
2901       allreg_response::ptr resp = i->second;
2902       int_registerPool *pool = resp->getRegPool();
2903
2904       if (resp->hasError()) {
2905          thr->getProcess()->setLastError(resp->errorCode(), thr->getProcess()->getLastErrorMsg());
2906          pthrd_printf("Error in response from %d/%d\n", thr->llthrd()->llproc()->getPid(),
2907                       thr->llthrd()->getLWP());
2908          had_error = true;
2909          delete pool;
2910          continue;
2911       }
2912       
2913       RegisterPool rpool;
2914       rpool.llregpool = pool;
2915       results.insert(make_pair(thr, rpool));
2916    }
2917
2918    return !had_error;
2919 }
2920
2921 bool ThreadSet::setAllRegisters(const map<Thread::const_ptr, RegisterPool> &reg_vals) const
2922 {
2923    MTLock lock_this_func;
2924    bool had_error = false;
2925    
2926    set<response::ptr> all_responses;
2927    set<pair<Thread::ptr, result_response::ptr> > thr_to_response;
2928
2929    setallreg_iter iter("setAllRegisters", had_error, ERR_CHCK_THRD | ERR_CHCK_THRD_STOPPED);
2930    for (setallreg_iter::i_t i = iter.begin(&reg_vals); i != iter.end(); i = iter.inc()) {
2931       Thread::const_ptr t = i->first;
2932       RegisterPool pool = i->second;
2933       int_thread *thr = t->llthrd();
2934       result_response::ptr response = result_response::createResultResponse();
2935
2936       bool result = thr->setAllRegisters(*pool.llregpool, response);
2937       if (!result) {
2938          pthrd_printf("Error setting registers on thread %d/%d\n",
2939                       thr->llproc()->getPid(), thr->getLWP());
2940          had_error = true;
2941          continue;
2942       }
2943
2944       thr_to_response.insert(make_pair(thr->thread(), response));
2945       all_responses.insert(response);      
2946    }
2947
2948    bool result = int_process::waitForAsyncEvent(all_responses);
2949    if (!result) {
2950       pthrd_printf("Error waiting for async events to complete\n");
2951       return false;
2952    }
2953
2954    for (set<pair<Thread::ptr, result_response::ptr > >::iterator i = thr_to_response.begin(); 
2955         i != thr_to_response.end(); i++)
2956    {
2957       Thread::ptr thr = i->first;
2958       result_response::ptr resp = i->second;
2959
2960       if (resp->hasError() || !resp->getResult()) {
2961          thr->getProcess()->setLastError(resp->errorCode(), thr->getProcess()->getLastErrorMsg());
2962          pthrd_printf("Error in response from %d/%d\n", thr->llthrd()->llproc()->getPid(),
2963                       thr->llthrd()->getLWP());
2964          had_error = true;
2965       }
2966    }
2967    return !had_error;
2968 }
2969
2970 bool ThreadSet::postIRPC(const multimap<Thread::const_ptr, IRPC::ptr> &rpcs) const
2971 {
2972    MTLock lock_this_func;
2973    bool had_error = false;
2974
2975    rpcmap_thr_iter iter("Post RPC", had_error, ERR_CHCK_NORM);
2976    for (rpcmap_thr_iter::i_t i = iter.begin(&rpcs); i != iter.end(); i = iter.inc()) {
2977       IRPC::ptr rpc = i->second;
2978       Thread::const_ptr t = i->first;
2979       int_thread *thread = t->llthrd();
2980
2981       bool result = rpcMgr()->postRPCToThread(thread, rpc->llrpc()->rpc);
2982       if (!result) {
2983          pthrd_printf("postRPCToThread failed on %d/%d\n", thread->llproc()->getPid(), thread->getLWP());
2984          had_error = true;
2985       }
2986    }
2987    return !had_error;
2988 }
2989
2990 bool ThreadSet::postIRPC(IRPC::ptr irpc, multimap<Thread::ptr, IRPC::ptr> *results) const
2991 {
2992    MTLock lock_this_func;
2993    bool had_error = false;
2994
2995    thrset_iter iter("Post RPC", had_error, ERR_CHCK_NORM);
2996    for (thrset_iter::i_t i = iter.begin(ithrset); i != iter.end(); i = iter.inc()) {
2997       Thread::ptr t = *i;
2998       int_thread *thread = t->llthrd();
2999       IRPC::ptr local_rpc = IRPC::createIRPC(irpc);
3000
3001       bool result = rpcMgr()->postRPCToThread(thread, local_rpc->llrpc()->rpc);
3002       if (!result) {
3003          pthrd_printf("postRPCToThread failed on %d/%d\n", thread->llproc()->getPid(), thread->getLWP());
3004          had_error = true;
3005          continue;
3006       }
3007       if (results)
3008          results->insert(make_pair(t, local_rpc));
3009    }
3010    return !had_error;
3011 }
3012
3013 CallStackUnwindingSet *ThreadSet::getCallStackUnwinding()
3014 {
3015    if (features && features->stkset)
3016       return features->stkset;
3017
3018    MTLock lock_this_func;
3019    if (!features) {
3020       features = new TSetFeatures();
3021    }
3022    if (!ithrset)
3023       return NULL;
3024    for (int_threadSet::iterator i = ithrset->begin(); i != ithrset->end(); i++) {
3025       Thread::ptr t = *i;
3026       if (t->getCallStackUnwinding()) {
3027          features->stkset = new CallStackUnwindingSet(shared_from_this());
3028          return features->stkset;
3029       }
3030    }
3031
3032    return NULL;
3033 }
3034
3035 const CallStackUnwindingSet *ThreadSet::getCallStackUnwinding() const
3036 {
3037    return const_cast<ThreadSet *>(this)->getCallStackUnwinding();
3038 }
3039
3040 ThreadSet::iterator::iterator(int_threadSet::iterator i)
3041 {
3042    int_iter = i;
3043 }
3044
3045 ThreadSet::iterator::iterator()
3046 {
3047 }
3048
3049 ThreadSet::iterator::~iterator()
3050 {
3051 }
3052
3053 Thread::ptr ThreadSet::iterator::operator*()
3054 {
3055    return *int_iter;
3056 }
3057
3058 bool ThreadSet::iterator::operator==(const iterator &i)
3059 {
3060    return int_iter == i.int_iter;
3061 }
3062
3063 bool ThreadSet::iterator::operator!=(const iterator &i)
3064 {
3065    return int_iter != i.int_iter;
3066 }
3067
3068 ThreadSet::iterator ThreadSet::iterator::operator++()
3069 {
3070    return ThreadSet::iterator(++int_iter);
3071 }
3072
3073 ThreadSet::iterator ThreadSet::iterator::operator++(int)
3074 {
3075    return ThreadSet::iterator(int_iter++);
3076 }
3077
3078 ThreadSet::const_iterator::const_iterator(int_threadSet::iterator i)
3079 {
3080    int_iter = i;
3081 }
3082
3083 ThreadSet::const_iterator::const_iterator()
3084 {
3085 }
3086
3087 ThreadSet::const_iterator::~const_iterator()
3088 {
3089 }
3090
3091 Thread::ptr ThreadSet::const_iterator::operator*()
3092 {
3093    return *int_iter;
3094 }
3095
3096 bool ThreadSet::const_iterator::operator==(const const_iterator &i)
3097 {
3098    return int_iter == i.int_iter;
3099 }
3100
3101 bool ThreadSet::const_iterator::operator!=(const const_iterator &i)
3102 {
3103    return int_iter != i.int_iter;
3104 }
3105
3106 ThreadSet::const_iterator ThreadSet::const_iterator::operator++()
3107 {
3108    return ThreadSet::const_iterator(++int_iter);
3109 }
3110
3111 ThreadSet::const_iterator ThreadSet::const_iterator::operator++(int)
3112 {
3113    return ThreadSet::const_iterator(int_iter++);
3114 }
3115
3116 LibraryTrackingSet::LibraryTrackingSet(ProcessSet::ptr ps_) :
3117    wps(ps_)
3118 {
3119 }
3120
3121 LibraryTrackingSet::~LibraryTrackingSet()
3122 {
3123    wps = ProcessSet::weak_ptr();
3124 }
3125
3126 bool LibraryTrackingSet::setTrackLibraries(bool b) const
3127 {
3128    MTLock lock_this_func;
3129    bool had_error = false;
3130
3131    ProcessSet::ptr ps = wps.lock();
3132    if (!ps) {
3133       perr_printf("setTrackLibraries on deleted process set\n");
3134       globalSetLastError(err_badparam, "setTrackLibraries attempted on deleted ProcessSet object");
3135       return false;
3136    }
3137    int_processSet *procset = ps->getIntProcessSet();
3138
3139    set<pair<int_process *, bp_install_state *> > bps_to_install;
3140    set<response::ptr> all_responses;
3141
3142    procset_iter iter("setTrackLibraries", had_error, ERR_CHCK_NORM);
3143    for (int_processSet::iterator i = iter.begin(procset); i != iter.end(); i = iter.inc()) {
3144       Process::ptr p = *i;
3145       int_libraryTracking *proc = p->llproc()->getLibraryTracking();
3146       if (!proc) {
3147          perr_printf("Library tracking not supported on process %d\n", p->getPid());
3148          p->setLastError(err_unsupported, "No library tracking on this platform\n");
3149          had_error = true;
3150          continue;
3151       }
3152       
3153       pthrd_printf("Changing sysv track libraries to %s for %d\n",
3154                    b ? "true" : "false", proc->getPid());
3155
3156       bool add_bp;
3157       int_breakpoint *bp;
3158       Address addr;
3159
3160       bool result = proc->setTrackLibraries(b, bp, addr, add_bp);
3161       if (!result) {
3162          had_error = true;
3163          continue;
3164       }
3165       if (add_bp) {
3166          bp_install_state *is = new bp_install_state();
3167          is->addr = addr;
3168          is->bp = bp;
3169          is->do_install = true;
3170          bps_to_install.insert(make_pair(proc, is));
3171       }
3172       else {
3173          result = proc->removeBreakpoint(addr, bp, all_responses);
3174          if (!result) {
3175             pthrd_printf("Error removing breakpoint in setTrackLibraries\n");
3176             had_error = true;
3177             continue;
3178          }
3179       }
3180    }
3181
3182    bool result = int_process::waitForAsyncEvent(all_responses);
3183    if (!result) {
3184       pthrd_printf("Error waiting for bp removals in setTrackLibraries\n");
3185       had_error = true;
3186    }
3187    if (bps_to_install.empty())
3188       return !had_error;
3189    
3190    return addBreakpointWorker(bps_to_install) && !had_error;
3191 }
3192
3193 bool LibraryTrackingSet::refreshLibraries() const
3194 {
3195    MTLock lock_this_scope;
3196    bool had_error = false;
3197    set<int_process *> procs;
3198     
3199    ProcessSet::ptr ps = wps.lock();
3200    if (!ps) {
3201       perr_printf("refreshLibraries on deleted process set\n");
3202       globalSetLastError(err_badparam, "refreshLibraries attempted on deleted ProcessSet object");
3203       return false;
3204    }  
3205    if (int_process::isInCB()) {
3206       perr_printf("User attempted refreshLibraries in CB, erroring.");
3207       for_each(ps->begin(), ps->end(), setError(err_incallback, "Cannot refreshLibraries from callback\n"));
3208       return false;
3209    }
3210
3211    procset_iter iter("refreshLibraries", had_error, ERR_CHCK_ALL);
3212    for (int_processSet::iterator i = iter.begin(ps->getIntProcessSet()); i != iter.end(); i = iter.inc()) {
3213       procs.insert((*i)->llproc());
3214    }
3215       
3216    while (!procs.empty()) {
3217       set<response::ptr> all_responses;
3218       for (set<int_process *>::iterator i = procs.begin(); i != procs.end();) {
3219          int_process *proc = *i;
3220          std::set<int_library *> added;
3221          std::set<int_library *> rmd;
3222          bool wait_for_async = false;
3223             
3224          bool result = proc->refresh_libraries(added, rmd, wait_for_async, all_responses);
3225          if (!result && !wait_for_async) {
3226             pthrd_printf("Error refreshing libraries for %d\n", proc->getPid());
3227             had_error = true;
3228             procs.erase(i++);
3229             continue;
3230          }
3231          if (!wait_for_async) {
3232             procs.erase(i++);
3233             if (added.empty() && rmd.empty()) {
3234                pthrd_printf("Refresh found no new library events for process %d\n", proc->getPid());
3235                continue;
3236             }
3237
3238             pthrd_printf("Adding new library event for process %d after refresh\n", proc->getPid());
3239             struct lib_converter {
3240                static Library::ptr c(int_library* l) { return l->getUpPtr(); }
3241             };
3242             set<Library::ptr> libs_added, libs_rmd;
3243             transform(added.begin(), added.end(), inserter(libs_added, libs_added.end()), lib_converter::c);
3244             transform(rmd.begin(), rmd.end(), inserter(libs_rmd, libs_rmd.end()), lib_converter::c);
3245             EventLibrary::ptr evlib = EventLibrary::ptr(new EventLibrary(libs_added, libs_rmd));
3246             evlib->setProcess(proc->proc());
3247             evlib->setThread(proc->threadPool()->initialThread()->thread());
3248             evlib->setSyncType(Event::async);
3249             mbox()->enqueue(evlib);
3250             continue;
3251          }
3252          i++;
3253       }
3254       bool result = int_process::waitForAsyncEvent(all_responses);
3255       if (!result) {
3256          pthrd_printf("Error waiting for async events\n");
3257          had_error = true;
3258          break;
3259       }
3260    }
3261
3262    int_process::waitAndHandleEvents(false);
3263    return !had_error;
3264 }
3265
3266 ThreadTrackingSet::ThreadTrackingSet(ProcessSet::ptr ps_) :
3267    wps(ps_)
3268 {
3269 }
3270
3271 ThreadTrackingSet::~ThreadTrackingSet()
3272 {
3273 }
3274
3275 bool ThreadTrackingSet::setTrackThreads(bool b) const
3276 {
3277    MTLock lock_this_func;
3278    bool had_error = false;
3279
3280    set<pair<int_process *, bp_install_state *> > bps_to_install;
3281    set<response::ptr> all_responses;
3282
3283    ProcessSet::ptr ps = wps.lock();
3284    if (!ps) {
3285       perr_printf("refreshLibraries on deleted process set\n");
3286       globalSetLastError(err_badparam, "refreshLibraries attempted on deleted ProcessSet object");
3287       return false;
3288    }  
3289    int_processSet *procset = ps->getIntProcessSet();
3290    procset_iter iter("setTrackThreads", had_error, ERR_CHCK_ALL);
3291    for (int_processSet::iterator i = iter.begin(procset); i != iter.end(); i = iter.inc()) {
3292       Process::ptr p = *i;
3293       int_threadTracking *proc = p->llproc()->getThreadTracking();
3294       if (!proc) {
3295          perr_printf("Thread tracking not supported on process %d\n", p->getPid());
3296          p->setLastError(err_unsupported, "No thread tracking on this platform\n");
3297          had_error = true;
3298          continue;
3299       }
3300
3301       pthrd_printf("Changing sysv track threads to %s for %d\n",
3302                    b ? "true" : "false", proc->getPid());
3303
3304       bool add_bp;
3305       set<pair<int_breakpoint *, Address> > bps;
3306       bool result = proc->setTrackThreads(b, bps, add_bp);
3307       if (!result) {
3308          had_error = true;
3309          continue;
3310       }
3311       if (add_bp) {
3312          for (set<pair<int_breakpoint *, Address> >::iterator j = bps.begin(); j != bps.end(); j++) {
3313             bp_install_state *is = new bp_install_state();
3314             is->addr = j->second;
3315             is->bp = j->first;
3316             is->do_install = true;
3317             bps_to_install.insert(make_pair(proc, is));
3318          }
3319       }
3320       else {
3321          for (set<pair<int_breakpoint *, Address> >::iterator j = bps.begin(); j != bps.end(); j++) {
3322             result = proc->removeBreakpoint(j->second, j->first, all_responses);
3323             if (!result) {
3324                pthrd_printf("Error removing breakpoint in setTrackLibraries\n");
3325                had_error = true;
3326                continue;
3327             }
3328          }
3329       }
3330    }
3331
3332    bool result = int_process::waitForAsyncEvent(all_responses);
3333    if (!result) {
3334       pthrd_printf("Error waiting for bp removals in setTrackLibraries\n");
3335       had_error = true;
3336    }
3337    if (bps_to_install.empty())
3338       return !had_error;
3339    
3340    return addBreakpointWorker(bps_to_install) && !had_error;
3341 }
3342
3343 bool ThreadTrackingSet::refreshThreads() const
3344 {
3345    MTLock lock_this_func;
3346    bool had_error = false;
3347
3348    ProcessSet::ptr ps = wps.lock();
3349    if (!ps) {
3350       perr_printf("refreshThreads on deleted process set\n");
3351       globalSetLastError(err_badparam, "refreshThreads attempted on deleted ProcessSet object");
3352       return false;
3353    }
3354    int_processSet *procset = ps->getIntProcessSet();
3355    procset_iter iter("refreshThreads", had_error, ERR_CHCK_ALL);
3356    for (int_processSet::iterator i = iter.begin(procset); i != iter.end(); i = iter.inc()) {
3357       int_threadTracking *proc = (*i)->llproc()->getThreadTracking();
3358       if (!proc) {
3359          perr_printf("Thread tracking not supported on process %d\n", proc->getPid());
3360          proc->setLastError(err_unsupported, "No thread tracking on this platform\n");
3361          had_error = true;
3362          continue;
3363       }
3364       if (!proc->refreshThreads()) {
3365          had_error = true;
3366          continue;
3367       }
3368    }
3369    
3370    int_process::waitAndHandleEvents(false);
3371    return !had_error;
3372 }
3373
3374 LWPTrackingSet::LWPTrackingSet(ProcessSet::ptr ps_) :
3375    wps(ps_)
3376 {
3377 }
3378
3379 LWPTrackingSet::~LWPTrackingSet()
3380 {
3381 }
3382
3383 bool LWPTrackingSet::setTrackLWPs(bool b) const
3384 {
3385    MTLock lock_this_func;
3386    bool had_error = false;
3387    pthrd_printf("setting LWP tracking in process set to %s\n", b ? "enabled" : "disabled");
3388    int_processSet *procset = wps.lock()->getIntProcessSet();
3389    procset_iter iter("setTrackLWPs", had_error, ERR_CHCK_ALL);
3390    for (int_processSet::iterator i = iter.begin(procset); i != iter.end(); i = iter.inc()) {
3391       Process::ptr p = *i;
3392       LWPTracking *lwpt = p->getLWPTracking();
3393       if (!lwpt) {
3394          p->setLastError(err_unsupported, "LWP Tracking not supported on this process");
3395          had_error = true;
3396          continue;
3397       }
3398
3399       lwpt->setTrackLWPs(b);
3400    }
3401    return !had_error;
3402 }
3403
3404 bool LWPTrackingSet::refreshLWPs() const
3405 {
3406    MTLock lock_this_func;
3407    bool had_error = false;
3408    pthrd_printf("refreshing LWPs in process set\n");
3409
3410    int_processSet *procset = wps.lock()->getIntProcessSet();
3411    procset_iter iter("setTrackLWPs", had_error, ERR_CHCK_ALL);
3412    set<response::ptr> all_resps;
3413    set<int_process *> all_procs;
3414    set<int_process *> change_procs;
3415    for (int_processSet::iterator i = iter.begin(procset); i != iter.end(); i = iter.inc()) {
3416       int_LWPTracking *proc = (*i)->llproc()->getLWPTracking();
3417       if (!proc) {
3418          perr_printf("LWP tracking not supported on process %d\n", proc->getPid());
3419          proc->setLastError(err_unsupported, "No LWP tracking on this platform\n");
3420          had_error = true;
3421          continue;
3422       }
3423       result_response::ptr resp;
3424       if (!proc->lwp_refreshPost(resp)) {
3425          pthrd_printf("Error refreshing lwps on %d\n", proc->getPid());
3426          had_error = true;
3427       }
3428       if (resp) {
3429          all_resps.insert(resp);
3430       }
3431       all_procs.insert(proc);
3432    }
3433
3434    int_process::waitForAsyncEvent(all_resps);
3435
3436    for (set<int_process *>::iterator i = all_procs.begin(); i != all_procs.end(); i++) {
3437       int_LWPTracking *proc = (*i)->getLWPTracking();
3438       if (!proc)
3439          continue;
3440       bool changed;
3441       bool result = proc->lwp_refreshCheck(changed);
3442       if (!result) {
3443          pthrd_printf("Error refreshing lwps while creating events on %d\n", proc->getPid());
3444          had_error = true;
3445       }
3446       if (changed) {
3447          change_procs.insert(proc);
3448          proc->setForceGeneratorBlock(true);
3449       }
3450    }
3451
3452    if (change_procs.empty())
3453       return !had_error;
3454
3455    pthrd_printf("Found changes to thread in refresh.  Handling events.\n");
3456    ProcPool()->condvar()->lock();
3457    ProcPool()->condvar()->broadcast();
3458    ProcPool()->condvar()->unlock();
3459
3460    int_process::waitAndHandleEvents(false);
3461
3462    for (set<int_process *>::iterator i = change_procs.begin(); i != change_procs.end(); i++) {
3463       int_process *proc = *i;
3464       proc->setForceGeneratorBlock(false);      
3465    }
3466    return !had_error;
3467 }
3468
3469 FollowForkSet::FollowForkSet(ProcessSet::ptr ps_) :
3470    wps(ps_)
3471 {
3472 }
3473
3474 FollowForkSet::~FollowForkSet()
3475 {
3476    wps = ProcessSet::weak_ptr();
3477 }
3478
3479 bool FollowForkSet::setFollowFork(FollowFork::follow_t f) const
3480 {
3481    MTLock lock_this_func;
3482    bool had_error = false;
3483
3484    ProcessSet::ptr ps = wps.lock();
3485    if (!ps) {
3486       perr_printf("setFollowFork on deleted process set\n");
3487       globalSetLastError(err_badparam, "setFollowFork attempted on deleted ProcessSet object");
3488       return false;
3489    }  
3490    int_processSet *procset = ps->getIntProcessSet();
3491    procset_iter iter("setFollowFork", had_error, ERR_CHCK_ALL);
3492    for (int_processSet::iterator i = iter.begin(procset); i != iter.end(); i = iter.inc()) {
3493       int_followFork *proc = (*i)->llproc()->getFollowFork();
3494       if (!proc) {
3495          perr_printf("Follow Fork not supported on process %d\n", proc->getPid());
3496          proc->setLastError(err_unsupported, "No follow fork control on this platform\n");
3497          had_error = true;
3498          continue;
3499       }
3500       proc->fork_setTracking(f);
3501    }
3502
3503    return !had_error;
3504 }
3505
3506 CallStackUnwindingSet::CallStackUnwindingSet(ThreadSet::ptr ts) :
3507    wts(ts)
3508 {
3509 }
3510
3511 CallStackUnwindingSet::~CallStackUnwindingSet()
3512 {
3513    wts = ThreadSet::weak_ptr();
3514 }
3515
3516 bool CallStackUnwindingSet::walkStack(CallStackCallback *stk_cb)
3517 {
3518    MTLock lock_this_func;
3519    bool had_error = false;
3520
3521    ThreadSet::ptr thrset = wts.lock();
3522    if (!thrset) {
3523       perr_printf("walkStack was given an exited thread set\n");
3524       globalSetLastError(err_exited, "Exited threads passed to walkStack\n");
3525       return false;
3526    }
3527
3528    thrset_iter iter("walkStack", had_error, ERR_CHCK_NORM);
3529    set<response::ptr> all_responses;
3530    set<int_process *> all_procs;
3531    int_threadSet *ithrset = thrset->getIntThreadSet();
3532
3533    pthrd_printf("Sending requests for callstack\n");
3534    getResponses().lock();
3535    for (thrset_iter::i_t i = iter.begin(ithrset); i != iter.end(); i = iter.inc()) {
3536       Thread::ptr t = *i;
3537       int_thread *thr = t->llthrd();
3538       int_callStackUnwinding *proc = thr->llproc()->getCallStackUnwinding();
3539       if (!proc) {
3540          perr_printf("Stack unwinding not supported on process %d\n", t->getProcess()->getPid());
3541          t->setLastError(err_unsupported, "No stack unwinding on this platform\n");
3542          had_error = true;
3543          continue;
3544       }
3545       stack_response::ptr stk_resp = stack_response::createStackResponse(thr);
3546       stk_resp->markSyncHandled();
3547
3548       bool result = proc->plat_getStackInfo(thr, stk_resp);
3549       if (!result) {
3550          had_error = true;
3551          pthrd_printf("Could not get stackwalk from %d/%d\n", proc->getPid(), thr->getLWP());
3552          continue;
3553       }
3554
3555       getResponses().addResponse(stk_resp, proc);
3556       all_procs.insert(proc);
3557       all_responses.insert(stk_resp);
3558    }
3559    getResponses().unlock();
3560    getResponses().noteResponse();
3561
3562    for (set<int_process *>::iterator i = all_procs.begin(); i != all_procs.end(); i++) {
3563       int_process *proc = *i;
3564       proc->plat_preAsyncWait();
3565    }
3566    all_procs.clear();
3567
3568
3569    pthrd_printf("Processing requests for callstack\n");
3570    while (!all_responses.empty()) {
3571       bool did_something = false;
3572       stack_response::ptr a_resp;
3573       for (set<response::ptr>::iterator i = all_responses.begin(); i != all_responses.end();) {
3574          stack_response::ptr stk_resp = (*i)->getStackResponse();
3575          if (stk_resp->hasError() || stk_resp->isReady()) {
3576             int_thread *thr = stk_resp->getThread();
3577             int_callStackUnwinding *proc = thr->llproc()->getCallStackUnwinding();
3578             pthrd_printf("Handling completed stackwalk for %d/%d\n", proc->getPid(), thr->getLWP());
3579             bool result = proc->plat_handleStackInfo(stk_resp, stk_cb);
3580             if (!result) {
3581                pthrd_printf("Error handling stack info\n");
3582                had_error = true;
3583             }
3584             did_something = true;
3585             all_responses.erase(i++);
3586          }
3587          else {
3588             a_resp = stk_resp;
3589             i++;
3590          }
3591       }
3592       if (!did_something) 
3593          int_process::waitForAsyncEvent(a_resp);
3594    }
3595
3596    return !had_error;
3597 }
3598
3599 bool RemoteIOSet::getFileNames(FileSet *fset)
3600 {
3601    MTLock lock_this_func;
3602    bool had_error = false;
3603
3604    if (!fset) {
3605       perr_printf("NULL FileSet passed to getFileNames\n");
3606       globalSetLastError(err_badparam, "Unexpected NULL parameter");
3607       return false;
3608    }
3609    ProcessSet::ptr procs = pset.lock();
3610    if (!procs || procs->empty()) {
3611       perr_printf("getFileNames attempted on empty proces set\n");
3612       globalSetLastError(err_badparam, "getFileNames on empty process set");
3613       return false;
3614    }
3615
3616    pthrd_printf("RemoteIOSet::getFileNames called on %lu processes\n", (unsigned long)procs->size());
3617
3618    set<FileSetResp_t *> all_resps;
3619    int_processSet *procset = procs->getIntProcessSet();
3620    procset_iter iter("getFileNames", had_error, ERR_CHCK_NORM);   
3621    for (int_processSet::iterator i = iter.begin(procset); i != iter.end(); i = iter.inc()) {
3622       int_remoteIO *proc = (*i)->llproc()->getRemoteIO();
3623       if (!proc) {
3624          perr_printf("getFileNames attempted on non RemoteIO process %d\n", proc->getPid());
3625          proc->setLastError(err_unsupported, "getFileNames not supported on this platform");
3626          had_error = true;
3627          continue;
3628       }
3629
3630       FileSetResp_t *new_resp = new FileSetResp_t(fset, proc);
3631       bool result = proc->plat_getFileNames(new_resp);
3632       if (!result) {
3633          pthrd_printf("Error running plat_getFileNames on %d\n", proc->getPid());
3634          proc->setLastError(err_internal, "Internal error getting filenames");
3635          had_error = true;
3636          delete new_resp;
3637          continue;
3638       }
3639
3640       all_resps.insert(new_resp);
3641    }
3642
3643    for (set<FileSetResp_t *>::iterator i = all_resps.begin(); i != all_resps.end(); i++) {
3644       FileSetResp_t *resp = *i;
3645       resp->getProc()->waitForEvent(resp);
3646       delete resp;
3647    }
3648
3649    return !had_error;
3650 }
3651
3652 bool RemoteIOSet::getFileStatData(FileSet *fset)
3653 {
3654    MTLock lock_this_func;
3655    bool had_error = false;
3656
3657    if (!fset) {
3658       perr_printf("NULL FileSet passed to getFileStatData\n");
3659       globalSetLastError(err_badparam, "Unexpected NULL parameter");
3660       return false;
3661    }
3662    ProcessSet::ptr procs = pset.lock();
3663    if (!procs || procs->empty()) {
3664       perr_printf("getFileStatData attempted on empty proces set\n");
3665       globalSetLastError(err_badparam, "getFileStatData on empty process set");
3666       return false;
3667    }
3668
3669
3670    pthrd_printf("RemoteIOSet::getFileStatData called on %lu processes\n", (unsigned long)procs->size());
3671
3672    set<StatResp_t *> all_resps;
3673
3674    for (FileSet::iterator i = fset->begin(); i != fset->end(); i++) {
3675       pthrd_printf("About to access proc %p\n", i->first->llproc());
3676       fflush(stderr);
3677       int_remoteIO *proc = i->first->llproc()->getRemoteIO();
3678       if (!proc) {
3679          perr_printf("getFileStatData attempted on non RemoteIO process %d\n", proc->getPid());
3680          proc->setLastError(err_unsupported, "getFileStatData not supported on this platform");
3681          had_error = true;
3682          continue;
3683       }
3684       FileInfo &fi = i->second;
3685       int_fileInfo_ptr info = fi.getInfo();
3686       if (info->filename.empty()) {
3687          perr_printf("Empty filename in stat operation on %d\n", proc->getPid());
3688          proc->setLastError(err_badparam, "Empty filename specified in stat operation");
3689          had_error = true;
3690          continue;
3691       }
3692       
3693       bool result = proc->plat_getFileStatData(info->filename, &info->stat_results, all_resps);
3694       if (!result) {
3695          pthrd_printf("Error while requesting file stat data on %d\n", proc->getPid());
3696          had_error = true;
3697          continue;
3698       }
3699    }
3700
3701    for (set<StatResp_t *>::iterator i = all_resps.begin(); i != all_resps.end(); i++) {
3702       StatResp_t *resp = *i;
3703       resp->getProc()->waitForEvent(resp);
3704       delete resp;
3705    }
3706
3707    return !had_error;
3708 }
3709
3710 bool RemoteIOSet::readFileContents(const FileSet *fset)
3711 {
3712    MTLock lock_this_func;
3713    bool had_error = false;
3714
3715    if (!fset) {
3716       perr_printf("NULL FileSet passed to getFileStatData\n");
3717       globalSetLastError(err_badparam, "Unexpected NULL parameter");
3718       return false;
3719    }
3720
3721    set<FileReadResp_t *> resps;
3722
3723    for (FileSet::const_iterator i = fset->begin(); i != fset->end(); i++) {
3724       int_remoteIO *proc = i->first->llproc()->getRemoteIO();
3725       if (!proc) {
3726          perr_printf("getFileStatData attempted on non RemoteIO process %d\n", proc->getPid());
3727          proc->setLastError(err_unsupported, "getFileStatData not supported on this platform");
3728          had_error = true;
3729          continue;
3730       }
3731
3732       int_eventAsyncFileRead *fileread = new int_eventAsyncFileRead();
3733       fileread->offset = 0;
3734       fileread->whole_file = true;
3735       fileread->filename = i->second.getFilename();
3736       bool result = proc->plat_getFileDataAsync(fileread);
3737       if (!result) {
3738          pthrd_printf("Error while requesting file data on %d\n", proc->getPid());
3739          had_error = true;
3740          delete fileread;
3741          continue;
3742       }
3743    }
3744
3745    return !had_error;
3746 }
3747
3748 MemoryUsageSet::MemoryUsageSet(ProcessSet::ptr ps_) :
3749    wps(ps_)
3750 {
3751 }
3752
3753 MemoryUsageSet::~MemoryUsageSet()
3754 {
3755    wps = ProcessSet::weak_ptr();
3756 }
3757
3758 bool MemoryUsageSet::sharedUsed(std::map<Process::const_ptr, unsigned long> &used) const
3759 {
3760    MTLock lock_this_func;
3761    bool had_error = false;
3762
3763    ProcessSet::ptr ps = wps.lock();
3764    if (!ps) {
3765       perr_printf("setTrackLibraries on deleted process set\n");
3766       globalSetLastError(err_badparam, "sharedUsed attempted on deleted ProcessSet object");
3767       return false;
3768    }
3769    set<MemUsageResp_t *> resps;
3770    unsigned long *result_sizes = new unsigned long[ps->size()];
3771    pthrd_printf("Performing set operation getting sharedUsed\n");
3772
3773    int_processSet *procset = ps->getIntProcessSet();
3774    procset_iter iter("sharedUsed", had_error, ERR_CHCK_ALL);
3775    unsigned j = 0;
3776    for (int_processSet::iterator i = iter.begin(procset); i != iter.end(); i = iter.inc()) {
3777       int_memUsage *proc = (*i)->llproc()->getMemUsage();
3778       if (!proc) {
3779          perr_printf("GetMemUsage not supported on process %d\n", proc->getPid());
3780          proc->setLastError(err_unsupported, "No getMemUsage on this platform\n");
3781          had_error = true;
3782          continue;
3783       }
3784       MemUsageResp_t *resp = new MemUsageResp_t(result_sizes + j++, proc);
3785       bool result = proc->plat_getSharedUsage(resp);
3786       if (!result) {
3787          had_error = true;
3788          delete resp;
3789          continue;
3790       }
3791
3792       resps.insert(resp);
3793    }
3794
3795    for (set<MemUsageResp_t *>::iterator i = resps.begin(); i != resps.end(); i++) {
3796       MemUsageResp_t *resp = *i;
3797       resp->getProc()->waitForEvent(resp);
3798       used.insert(make_pair(resp->getProc()->proc(), *resp->get()));
3799       delete resp;
3800    }
3801
3802    delete [] result_sizes;
3803
3804    return !had_error;
3805 }
3806
3807 bool MemoryUsageSet::heapUsed(std::map<Process::const_ptr, unsigned long> &used) const
3808 {
3809    MTLock lock_this_func;
3810    bool had_error = false;
3811
3812    ProcessSet::ptr ps = wps.lock();
3813    if (!ps) {
3814       perr_printf("setTrackLibraries on deleted process set\n");
3815       globalSetLastError(err_badparam, "heapUsed attempted on deleted ProcessSet object");
3816       return false;
3817    }
3818    set<MemUsageResp_t *> resps;
3819    unsigned long *result_sizes = new unsigned long[ps->size()];
3820    pthrd_printf("Performing set operation getting heapUsed\n");
3821
3822    int_processSet *procset = ps->getIntProcessSet();
3823    procset_iter iter("heapUsed", had_error, ERR_CHCK_ALL);
3824    unsigned j = 0;
3825    for (int_processSet::iterator i = iter.begin(procset); i != iter.end(); i = iter.inc()) {
3826       int_memUsage *proc = (*i)->llproc()->getMemUsage();
3827       if (!proc) {
3828          perr_printf("GetMemUsage not supported on process %d\n", proc->getPid());
3829          proc->setLastError(err_unsupported, "No getMemUsage on this platform\n");
3830          had_error = true;
3831          continue;
3832       }
3833       MemUsageResp_t *resp = new MemUsageResp_t(result_sizes + j++, proc);
3834       bool result = proc->plat_getHeapUsage(resp);
3835       if (!result) {
3836          had_error = true;
3837          delete resp;
3838          continue;
3839       }
3840
3841       resps.insert(resp);
3842    }
3843
3844    for (set<MemUsageResp_t *>::iterator i = resps.begin(); i != resps.end(); i++) {
3845       MemUsageResp_t *resp = *i;
3846       resp->getProc()->waitForEvent(resp);
3847       used.insert(make_pair(resp->getProc()->proc(), *resp->get()));
3848       delete resp;
3849    }
3850
3851    delete [] result_sizes;
3852
3853    return !had_error;
3854 }
3855
3856 bool MemoryUsageSet::stackUsed(std::map<Process::const_ptr, unsigned long> &used) const
3857 {
3858    MTLock lock_this_func;
3859    bool had_error = false;
3860
3861    ProcessSet::ptr ps = wps.lock();
3862    if (!ps) {
3863       perr_printf("setTrackLibraries on deleted process set\n");
3864       globalSetLastError(err_badparam, "stackUsed attempted on deleted ProcessSet object");
3865       return false;
3866    }
3867    set<MemUsageResp_t *> resps;
3868    unsigned long *result_sizes = new unsigned long[ps->size()];
3869    pthrd_printf("Performing set operation getting stackUsed\n");
3870
3871    int_processSet *procset = ps->getIntProcessSet();
3872    procset_iter iter("stackUsed", had_error, ERR_CHCK_ALL);
3873    unsigned j = 0;
3874    for (int_processSet::iterator i = iter.begin(procset); i != iter.end(); i = iter.inc()) {
3875       int_memUsage *proc = (*i)->llproc()->getMemUsage();
3876       if (!proc) {
3877         &n