A first pass at implementing thread stop and continue on FreeBSD.
[dyninst.git] / proccontrol / src / int_thread_db.h
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31 #if !defined(INT_THREAD_DB_H_)
32 #define INT_THREAD_DB_H
33
34 #include "proccontrol/h/Generator.h"
35 #include "proccontrol/h/Event.h"
36 #include "proccontrol/h/Decoder.h"
37 #include "proccontrol/h/Handler.h"
38 #include "proccontrol/src/int_process.h"
39 #include "proccontrol/src/sysv.h"
40 #include "proccontrol/src/int_handler.h"
41
42 #include <thread_db.h>
43 #include <proc_service.h>
44
45 #include <map>
46 using std::map;
47 using std::pair;
48
49 #include <vector>
50 using std::vector;
51
52 #include <string>
53 using std::string;
54
55 using namespace Dyninst;
56 using namespace ProcControlAPI;
57
58 class thread_db_thread;
59
60 class thread_db_process : public sysv_process
61 {
62 public:
63     thread_db_process(Dyninst::PID p, std::string e, std::vector<std::string> a);
64     thread_db_process(Dyninst::PID pid_, int_process *p);
65     virtual ~thread_db_process();
66
67     bool getEventsAtAddr(Dyninst::Address addr, thread_db_thread *eventThread,
68             vector<Event::ptr> &threadEvents);
69
70     /* helper functions for thread_db interactions */
71
72     td_thragent_t *getThreadDBAgent();
73     ps_err_e getSymbolAddr(const char *objName, const char *symName, 
74             psaddr_t *symbolAddr);
75     virtual bool initThreadDB();
76     virtual void freeThreadDBAgent();
77     virtual bool getPostDestroyEvents(vector<Event::ptr> &events);
78     static void addThreadDBHandlers(HandlerPool *hpool);
79
80     /*
81      * When creating a static executable or attaching to a new process,
82      * thread_db initialization needs to occur immediately after
83      * attach or create.
84      *
85      * When creating dynamic executables, initialization needs to happen
86      * when the thread library is loaded.
87      */
88     virtual bool post_attach();
89     virtual bool post_create();
90
91     virtual bool plat_readProcMem(void *local,
92             Dyninst::Address remote, size_t size) = 0;
93     virtual bool plat_writeProcMem(void *local,
94             Dyninst::Address remote, size_t size) = 0;
95     virtual bool plat_getLWPInfo(lwpid_t lwp, void *lwpInfo) = 0;
96     virtual bool plat_contThread(lwpid_t lwp) = 0;
97     virtual bool plat_stopThread(lwpid_t lwp) = 0;
98     virtual string getThreadLibName(const char *symName) = 0;
99     virtual bool isSupportedThreadLib(const string &libName) = 0;
100
101 protected:
102     static volatile bool thread_db_initialized;
103     static Mutex thread_db_init_lock;
104
105     map<Dyninst::Address, pair<int_breakpoint *, EventType> > addr2Event;
106     map<string, pair<LoadedLib *, SymReader *> > symReaders;
107     td_thragent_t *threadAgent;
108
109     struct ps_prochandle *self;
110 };
111
112 /*
113  * libthread_db defines this as opaque. We need to implement it.
114  */
115 struct ps_prochandle {
116     thread_db_process *thread_db_proc;
117 };
118
119 class thread_db_thread : public int_thread
120 {
121 public:
122     thread_db_thread(int_process *p, Dyninst::THR_ID t, Dyninst::LWP l);
123
124     thread_db_thread();
125     virtual ~thread_db_thread();
126
127     Event::ptr getThreadEvent();
128     bool setEventReporting(bool on);
129
130     bool resume();
131     bool suspend();
132     void markDestroyed();
133     bool isDestroyed();
134
135 protected:
136     // Initialization of the thread handle cannot be performed until 
137     // thread_db is loaded and initialized. When creating a process,
138     // we need to be able to create an instance of thread_db_thread
139     // before thread_db is initialized so we lazily initialize the
140     // thread handle
141     bool initThreadHandle();
142
143     td_thrhandle_t *threadHandle;
144
145     // Since a thread destroy event happens at a breakpoint, the 
146     // breakpoint needs to be cleaned up before the thread can be 
147     // removed from the threadPool and deleted.
148     bool destroyed;
149 };
150
151 class ThreadDBCreateHandler : public Handler
152 {
153 public:
154     ThreadDBCreateHandler();
155     virtual ~ThreadDBCreateHandler();
156     virtual bool handleEvent(Event::ptr ev);
157     virtual int getPriority() const;
158     void getEventTypesHandled(vector<EventType> &etypes);
159 };
160
161 class ThreadDBLibHandler : public Handler
162 {
163 public:
164     ThreadDBLibHandler();
165     virtual ~ThreadDBLibHandler();
166     virtual bool handleEvent(Event::ptr ev);
167     virtual int getPriority() const;
168     void getEventTypesHandled(std::vector<EventType> &etypes);
169 };
170
171 class ThreadDBDestroyHandler : public Handler
172 {
173 public:
174     ThreadDBDestroyHandler();
175     virtual ~ThreadDBDestroyHandler();
176     virtual bool handleEvent(Event::ptr ev);
177     virtual int getPriority() const;
178     void getEventTypesHandled(std::vector<EventType> &etypes);
179 };
180 #endif