Compilation fix for boost 1.70
[dyninst.git] / proccontrol / h / ProcessSet.h
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 #if !defined(PROCESSSET_H_)
32 #define PROCESSSET_H_
33
34 #include <string>
35 #include <map>
36
37 #include "dyntypes.h"
38 #include "PCProcess.h"
39 #include "PCErrors.h"
40
41 typedef std::multimap<Dyninst::Address, Dyninst::ProcControlAPI::Process::ptr> int_addressSet;
42 typedef std::set<Dyninst::ProcControlAPI::Thread::ptr> int_threadSet;
43 typedef std::set<Dyninst::ProcControlAPI::Process::ptr> int_processSet;
44
45 namespace Dyninst {
46 namespace ProcControlAPI {
47
48 class ProcessSet;
49 class ThreadSet;
50 class LibraryTrackingSet;
51 class ThreadTrackingSet;
52 class CallStackUnwindingSet;
53 class FollowForkSet;
54 class LWPTrackingSet;
55 class RemoteIOSet;
56 class MemoryUsageSet;
57 class PSetFeatures;
58 class TSetFeatures;
59
60 typedef boost::shared_ptr<ProcessSet> ProcessSet_ptr;
61 typedef boost::shared_ptr<ThreadSet> ThreadSet_ptr;
62 typedef boost::shared_ptr<const ProcessSet> ProcessSet_const_ptr;
63 typedef boost::shared_ptr<const ThreadSet> ThreadSet_const_ptr;
64
65 /**
66  * AddressSet represents a set of Process/Address pairs.  It is used to 
67  * denote the address of something that exists across multiple processes.
68  *
69  * AddressSet is like a std::multimap<Address, Process::ptr> object.
70  * This means that it's easy to operate on the entire set, or to focus on an 
71  * Address and operate on each process that shares that Address.
72  *
73  * Unlike a standard multimap, you can't have duplicates of the Address/Process
74  * pairs.  In this way it behaves more like a set.
75  *
76  * Iteration over AddressSet is sorted by the Address. So, all Processes
77  * that share an Address will appear together when iterating over the set.
78  **/
79 class PC_EXPORT AddressSet
80 {
81   private:
82    int_addressSet *iaddrs;
83    friend void boost::checked_delete<AddressSet>(AddressSet *) CHECKED_DELETE_NOEXCEPT;
84    friend class ProcessSet;
85    AddressSet();
86    ~AddressSet();
87   public:
88    int_addressSet *get_iaddrs() { return iaddrs; }
89
90    typedef boost::shared_ptr<AddressSet> ptr;
91    typedef boost::shared_ptr<AddressSet> const_ptr;
92    
93    /**
94     * Create new Address sets
95     **/
96    static AddressSet::ptr newAddressSet();
97    static AddressSet::ptr newAddressSet(ProcessSet_const_ptr ps, Dyninst::Address addr);
98    static AddressSet::ptr newAddressSet(Process::const_ptr proc, Dyninst::Address addr);
99    static AddressSet::ptr newAddressSet(ProcessSet_const_ptr ps, std::string library_name, Dyninst::Offset off = 0);
100    //More redundant factories, to work around gcc 4.1 bug
101    static AddressSet::ptr newAddressSet(ProcessSet_ptr ps, Dyninst::Address addr);
102    static AddressSet::ptr newAddressSet(Process::ptr proc, Dyninst::Address addr);
103    static AddressSet::ptr newAddressSet(ProcessSet_ptr ps, std::string library_name, Dyninst::Offset off = 0);
104    
105    /**
106     * Standard iterators methods and container access
107     **/
108    typedef std::pair<Address, Process::ptr> value_type;
109    typedef std::multimap<Dyninst::Address, Process::ptr>::iterator iterator;
110    typedef std::multimap<Dyninst::Address, Process::ptr>::const_iterator const_iterator;
111
112    iterator begin();
113    iterator end();
114    iterator find(Dyninst::Address a);
115    iterator find(Dyninst::Address a, Process::const_ptr p);
116    const_iterator begin() const;
117    const_iterator end() const;
118    const_iterator find(Dyninst::Address a) const;
119    const_iterator find(Dyninst::Address a, Process::const_ptr p) const;
120
121    size_t count(Dyninst::Address a) const;
122    size_t size() const;
123    bool empty() const;
124
125    std::pair<iterator, bool> insert(Dyninst::Address a, Process::const_ptr p);
126    size_t insert(Dyninst::Address a, ProcessSet_const_ptr ps);
127    std::pair<iterator, bool> insert(Dyninst::Address a, Process::ptr p);
128    size_t insert(Dyninst::Address a, ProcessSet_ptr ps);
129    void erase(iterator pos);
130    size_t erase(Process::const_ptr p);
131    size_t erase(Dyninst::Address a, Process::const_ptr p);
132    void clear();
133
134    /**
135     * Use lower_bound, upper_bound and equal_range to focus on an Address.
136     * For example:
137     *   pair<AddressSet::iterator, AddressSet::iterator> range = myset.equal_range(0x1000);
138     *   for (AddressSet::iterator i = range.first; i != range.second; i++) {
139     *     //Every Process::ptr with address equal to 0x1000 here
140     *   }
141     **/
142    iterator lower_bound(Dyninst::Address a);
143    iterator upper_bound(Dyninst::Address a);
144    std::pair<iterator, iterator> equal_range(Dyninst::Address a);
145    const_iterator lower_bound(Dyninst::Address a) const;
146    const_iterator upper_bound(Dyninst::Address a) const;
147    std::pair<const_iterator, const_iterator> equal_range(Dyninst::Address a) const;
148
149    /**
150     * Return a new set by performing these set operations with another AddressSet
151     **/
152    AddressSet::ptr set_union(AddressSet::const_ptr pp) const;
153    AddressSet::ptr set_intersection(AddressSet::const_ptr pp) const;
154    AddressSet::ptr set_difference(AddressSet::const_ptr pp) const;
155 };
156
157
158 /**
159  * A ProcessSet is a set of processes.  By grouping processes together we can
160  * perform collective operations on the entire set, which may be more effecient
161  * than the equivalent sequential operations.
162  **/
163 class PC_EXPORT ProcessSet : public boost::enable_shared_from_this<ProcessSet>
164 {
165    friend class ThreadSet;
166   private:
167    int_processSet *procset;
168    PSetFeatures *features;
169
170    ProcessSet();
171    ~ProcessSet();
172
173    friend void boost::checked_delete<ProcessSet>(ProcessSet *) CHECKED_DELETE_NOEXCEPT;
174  public:
175    int_processSet *getIntProcessSet(); //Not for public use
176    typedef boost::shared_ptr<ProcessSet> ptr;
177    typedef boost::shared_ptr<const ProcessSet> const_ptr;
178    typedef boost::weak_ptr<ProcessSet> weak_ptr;
179    typedef boost::weak_ptr<const ProcessSet> const_weak_ptr;
180
181    /**
182     * Create new ProcessSets from existing Process objects
183     **/
184    static ProcessSet::ptr newProcessSet();
185    static ProcessSet::ptr newProcessSet(Process::const_ptr p);
186    static ProcessSet::ptr newProcessSet(ProcessSet::const_ptr pp);
187    static ProcessSet::ptr newProcessSet(const std::set<Process::const_ptr> &procs);
188    static ProcessSet::ptr newProcessSet(AddressSet::const_iterator, AddressSet::const_iterator);
189
190    //These non-const factories may seem redundant, but gcc 4.1 gets confused without them
191    static ProcessSet::ptr newProcessSet(Process::ptr p); 
192    static ProcessSet::ptr newProcessSet(ProcessSet::ptr pp);
193    static ProcessSet::ptr newProcessSet(const std::set<Process::ptr> &procs);
194
195    /**
196     * Create new ProcessSets by attaching/creating new Process objects
197     **/
198    struct CreateInfo {
199       std::string executable;
200       std::vector<std::string> argv;
201       std::vector<std::string> envp;
202       std::map<int, int> fds;
203       ProcControlAPI::err_t error_ret; //Set on return
204       Process::ptr proc;               //Set on return
205    };
206    static ProcessSet::ptr createProcessSet(std::vector<CreateInfo> &cinfo);
207
208    struct AttachInfo {
209       Dyninst::PID pid;
210       std::string executable;
211       ProcControlAPI::err_t error_ret; //Set on return
212       Process::ptr proc;               //Set on return
213    };
214    static ProcessSet::ptr attachProcessSet(std::vector<AttachInfo> &ainfo);
215
216    /**
217     * Return a new set by performing these set operations with another set.
218     **/
219    ProcessSet::ptr set_union(ProcessSet::ptr pp) const;
220    ProcessSet::ptr set_intersection(ProcessSet::ptr pp) const;
221    ProcessSet::ptr set_difference(ProcessSet::ptr pp) const;
222
223    /**
224     * Iterator and standard set utilities
225     **/
226    class PC_EXPORT iterator {
227       friend class Dyninst::ProcControlAPI::ProcessSet;
228      private:
229       int_processSet::iterator int_iter;
230       iterator(int_processSet::iterator i);
231      public:
232       iterator();
233       ~iterator();
234           Process::ptr operator*() const;
235       bool operator==(const iterator &i) const;
236       bool operator!=(const iterator &i) const;
237       ProcessSet::iterator operator++();
238       ProcessSet::iterator operator++(int);
239
240           typedef Process::ptr value_type;
241           typedef int difference_type;
242           typedef Process::ptr *pointer;
243           typedef Process::ptr &reference;
244           typedef std::forward_iterator_tag iterator_category;
245    };
246
247    class PC_EXPORT const_iterator {
248       friend class Dyninst::ProcControlAPI::ProcessSet;
249      private:
250       int_processSet::iterator int_iter;
251           const_iterator(int_processSet::iterator i) : int_iter(i) {};
252      public:
253       const_iterator();
254       ~const_iterator();
255       Process::ptr operator*() const;
256       bool operator==(const const_iterator &i) const;
257       bool operator!=(const const_iterator &i) const;
258       ProcessSet::const_iterator operator++();
259       ProcessSet::const_iterator operator++(int);
260
261           typedef Process::ptr value_type;
262           typedef int difference_type;
263           typedef Process::ptr *pointer;
264           typedef Process::ptr &reference;
265           typedef std::forward_iterator_tag iterator_category;
266    };
267
268    iterator begin();
269    iterator end();
270    iterator find(Process::const_ptr p);
271    iterator find(Dyninst::PID p);
272    const_iterator begin() const;
273    const_iterator end() const;
274    const_iterator find(Process::const_ptr p) const;
275    const_iterator find(Dyninst::PID p) const;
276
277    bool empty() const;
278    size_t size() const;
279
280    std::pair<iterator, bool> insert(Process::const_ptr p);
281    void erase(iterator pos);
282    size_t erase(Process::const_ptr);
283    void clear();
284
285    /**
286     * Error management.  
287     * 
288     * Return the subset of processes that had any error on the last operation, or
289     * group them into subsets based on unique error codes.
290     **/
291    ProcessSet::ptr getErrorSubset() const;
292    void getErrorSubsets(std::map<ProcControlAPI::err_t, ProcessSet::ptr> &err_sets) const;
293
294    /**
295     * Test state of processes
296     **/
297    bool anyTerminated() const;
298    bool anyExited() const;
299    bool anyCrashed() const;
300    bool anyDetached() const;
301    bool anyThreadStopped() const;
302    bool anyThreadRunning() const;
303    bool allTerminated() const;
304    bool allExited() const;
305    bool allCrashed() const;
306    bool allDetached() const;
307    bool allThreadsStopped() const;
308    bool allThreadsRunning() const;
309
310    /**
311     * Create new ProcessSets that are subsets of this set, and only
312     * including processes with the specified state.
313     **/
314    ProcessSet::ptr getTerminatedSubset() const;
315    ProcessSet::ptr getExitedSubset() const;
316    ProcessSet::ptr getCrashedSubset() const;
317    ProcessSet::ptr getDetachedSubset() const;
318    ProcessSet::ptr getAllThreadRunningSubset() const;
319    ProcessSet::ptr getAnyThreadRunningSubset() const;
320    ProcessSet::ptr getAllThreadStoppedSubset() const;
321    ProcessSet::ptr getAnyThreadStoppedSubset() const;
322
323    /**
324     * Move all processes in set to specified state
325     **/
326    bool continueProcs() const;
327    bool stopProcs() const;
328    bool detach(bool leaveStopped = false) const;
329    bool terminate() const;
330    bool temporaryDetach() const;
331    bool reAttach() const;
332
333    /**
334     * Memory management
335     **/
336    AddressSet::ptr mallocMemory(size_t size) const;
337    bool mallocMemory(size_t size, AddressSet::ptr location) const;
338    bool freeMemory(AddressSet::ptr addrs) const;
339
340    /**
341     * Read/Write memory
342     * - Use the AddressSet forms to read/write from the same memory location in each process
343     * - Use the read_t/write_t forms to read/write from different memory locations/sizes in each process
344     * - The AddressSet forms of readMemory need to have their memory free'd by the user.
345     * - The readMemory form that outputs 'std::map<void *, ProcessSet::ptr> &result' groups processes 
346     *   based on having the same memory contents.
347     **/
348    struct write_t {
349       void *buffer;
350       Dyninst::Address addr;
351       size_t size;
352       err_t err;
353       bool operator<(const write_t &w) { return (addr < w.addr) && (size < w.size) && (buffer < w.buffer); }
354    };
355    struct read_t {
356       Dyninst::Address addr;
357       void *buffer;
358       size_t size;
359       err_t err;
360       bool operator<(const read_t &w) { return (addr < w.addr) && (size < w.size) && (buffer < w.buffer); }
361    };
362
363    bool readMemory(AddressSet::ptr addr, std::multimap<Process::ptr, void *> &result, size_t size) const;
364    bool readMemory(AddressSet::ptr addr, std::map<void *, ProcessSet::ptr> &result, size_t size, bool use_checksum = true) const;
365    bool readMemory(std::multimap<Process::const_ptr, read_t> &addrs) const;
366
367    bool writeMemory(AddressSet::ptr addr, const void *buffer, size_t size) const;
368    bool writeMemory(std::multimap<Process::const_ptr, write_t> &addrs) const;
369
370    /**
371     * Breakpoints
372     **/
373    bool addBreakpoint(AddressSet::ptr addrs, Breakpoint::ptr bp) const;
374    bool rmBreakpoint(AddressSet::ptr addrs, Breakpoint::ptr bp) const;
375
376    /**
377     * IRPC
378     * The user may pass multiple IRPCs, which are each posted to their respective processes.
379     * The user may pass a single example IRPC, copies of which are posted to each process and returned.
380     * The user may pass a single example IRPC and an AddressSet. Copies of that IRPC are posted to each
381     *  process at the addresses provided.
382     **/
383    bool postIRPC(const std::multimap<Process::const_ptr, IRPC::ptr> &rpcs) const;
384    bool postIRPC(IRPC::ptr irpc, std::multimap<Process::ptr, IRPC::ptr> *result = NULL) const;
385    bool postIRPC(IRPC::ptr irpc, AddressSet::ptr addrs, std::multimap<Process::ptr, IRPC::ptr> *result = NULL) const;
386
387    /**
388     * Perform specific operations.  Interface objects will only be returned
389     * on appropriately supported platforms, others will return NULL.
390     **/
391    LibraryTrackingSet *getLibraryTracking();
392    ThreadTrackingSet *getThreadTracking();
393    LWPTrackingSet *getLWPTracking();
394    FollowForkSet *getFollowFork();
395    RemoteIOSet *getRemoteIO();
396    MemoryUsageSet *getMemoryUsage();
397    const LibraryTrackingSet *getLibraryTracking() const;
398    const ThreadTrackingSet *getThreadTracking() const;
399    const LWPTrackingSet *getLWPTracking() const;
400    const FollowForkSet *getFollowFork() const;
401    const RemoteIOSet *getRemoteIO() const;
402    const MemoryUsageSet *getMemoryUsage() const;
403 };
404
405 /**
406  * Return a unique ProcessSet representing every running process.  It is an error to try to
407  * manually modify this ProcessSet.  Modifications are done automatically by ProcControlAPI
408  * as processes are created and destroyed.
409  **/
410 ProcessSet::const_ptr getAllProcs();
411
412 class PC_EXPORT ThreadSet : public boost::enable_shared_from_this<ThreadSet> {
413   private:
414    int_threadSet *ithrset;
415    TSetFeatures *features;
416    
417    ThreadSet();
418    ~ThreadSet();
419    friend void boost::checked_delete<ThreadSet>(ThreadSet *) CHECKED_DELETE_NOEXCEPT;
420   public:
421    typedef boost::shared_ptr<ThreadSet> ptr;
422    typedef boost::shared_ptr<const ThreadSet> const_ptr;
423    typedef boost::weak_ptr<ThreadSet> weak_ptr;
424    typedef boost::weak_ptr<const ThreadSet> const_weak_ptr;
425
426    int_threadSet *getIntThreadSet() const;
427
428    /**
429     * Create a new ThreadSet given existing threads
430     **/
431    static ThreadSet::ptr newThreadSet();
432    static ThreadSet::ptr newThreadSet(Thread::ptr thr);
433    static ThreadSet::ptr newThreadSet(const ThreadPool &threadp);
434    static ThreadSet::ptr newThreadSet(const std::set<Thread::const_ptr> &threads);
435    static ThreadSet::ptr newThreadSet(ProcessSet::ptr ps, bool initial_only = false);
436
437    /**
438     * Modify current set by performing these set operations with another set.
439     **/
440    ThreadSet::ptr set_union(ThreadSet::ptr tp) const;
441    ThreadSet::ptr set_intersection(ThreadSet::ptr tp) const;
442    ThreadSet::ptr set_difference(ThreadSet::ptr tp) const;
443
444    /**
445     * Iterator and standard set utilities
446     **/
447    class PC_EXPORT iterator {
448       friend class Dyninst::ProcControlAPI::ThreadSet;
449      protected:
450       std::set<Thread::ptr>::iterator int_iter;
451       iterator(int_threadSet::iterator i);
452      public:
453       iterator();
454       ~iterator();
455       Thread::ptr operator*();
456       bool operator==(const iterator &i);
457       bool operator!=(const iterator &i);
458       ThreadSet::iterator operator++();
459       ThreadSet::iterator operator++(int);
460    };
461
462    class PC_EXPORT const_iterator {
463       friend class Dyninst::ProcControlAPI::ThreadSet;
464      protected:
465       std::set<Thread::ptr>::iterator int_iter;
466       const_iterator(int_threadSet::iterator i);
467      public:
468       const_iterator();
469       ~const_iterator();
470       Thread::ptr operator*();
471       bool operator==(const const_iterator &i);
472       bool operator!=(const const_iterator &i);
473       ThreadSet::const_iterator operator++();
474       ThreadSet::const_iterator operator++(int);
475    };
476
477    iterator begin();
478    iterator end();
479    iterator find(Thread::const_ptr p);
480    const_iterator begin() const;
481    const_iterator end() const;
482    const_iterator find(Thread::const_ptr p) const;
483    bool empty() const;
484    size_t size() const;
485
486    std::pair<iterator, bool> insert(Thread::const_ptr p);
487    void erase(iterator pos);
488    size_t erase(Thread::const_ptr t);
489    void clear();
490
491    /**
492     * Error management.
493     *
494     * Return the subset of threads that had any error on the last operation, or
495     * group them into subsets based on unique error codes.
496     **/
497    ThreadSet::ptr getErrorSubset() const;
498    void getErrorSubsets(std::map<ProcControlAPI::err_t, ThreadSet::ptr> &err_sets) const;
499
500    /**
501     * Query thread states
502     **/
503    bool allStopped() const;
504    bool allRunning() const;
505    bool allTerminated() const;
506    bool allSingleStepMode() const;
507    bool allHaveUserThreadInfo() const;
508    bool anyStopped() const;
509    bool anyRunning() const;
510    bool anyTerminated() const;
511    bool anySingleStepMode() const;
512    bool anyHaveUserThreadInfo() const;
513    ThreadSet::ptr getStoppedSubset() const;
514    ThreadSet::ptr getRunningSubset() const;
515    ThreadSet::ptr getTerminatedSubset() const;
516    ThreadSet::ptr getSingleStepSubset() const;
517    ThreadSet::ptr getHaveUserThreadInfoSubset() const;
518
519    /**
520     * Query user thread info
521     **/
522    bool getStartFunctions(AddressSet::ptr result) const;
523    bool getStackBases(AddressSet::ptr result) const;
524    bool getTLSs(AddressSet::ptr result) const;
525
526    /**
527     * Move all threads to a specified state.
528     **/
529    bool stopThreads() const;
530    bool continueThreads() const;
531    bool setSingleStepMode(bool v) const;
532
533    /**
534     * Get and set individual registers.
535     * - The getRegister form that outputs 'std::map<Dyninst::MachRegisterVal, ThreadSet::ptr>' groups 
536     *   processes based on similar return values of registers.
537     **/
538    bool getRegister(Dyninst::MachRegister reg, std::map<Thread::ptr, Dyninst::MachRegisterVal> &results) const;
539    bool getRegister(Dyninst::MachRegister reg, std::map<Dyninst::MachRegisterVal, ThreadSet::ptr> &results) const;
540    bool setRegister(Dyninst::MachRegister reg, const std::map<Thread::const_ptr, Dyninst::MachRegisterVal> &vals) const;
541    bool setRegister(Dyninst::MachRegister reg, Dyninst::MachRegisterVal val) const;
542
543    bool getAllRegisters(std::map<Thread::ptr, RegisterPool> &results) const;
544    bool setAllRegisters(const std::map<Thread::const_ptr, RegisterPool> &reg_vals) const;
545
546    /**
547     * IRPC
548     * The user may pass multiple IRPCs, which are posted to their respective threads.
549     * The user may pass a single example IRPC, copies of which are posted to each process and returned.
550     **/
551    bool postIRPC(const std::multimap<Thread::const_ptr, IRPC::ptr> &rpcs) const;
552    bool postIRPC(IRPC::ptr irpc, std::multimap<Thread::ptr, IRPC::ptr> *result = NULL) const;
553
554    /**
555     * Perform specific operations.  Interface objects will only be returned
556     * on appropriately supported platforms, others will return NULL.
557     **/
558    CallStackUnwindingSet *getCallStackUnwinding();
559    const CallStackUnwindingSet *getCallStackUnwinding() const;
560 };
561
562 }
563 }
564
565 #endif