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