xref: /freebsd/lib/libthread_db/thread_db.h (revision 3c1e38ea6e2fb9c73d749f283a2c11d0314d280d)
1 /*
2  * Copyright (c) 2004 Marcel Moolenaar
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28 
29 #ifndef _THREAD_DB_H_
30 #define	_THREAD_DB_H_
31 
32 #include <sys/procfs.h>
33 #include <pthread.h>
34 
35 typedef enum {
36 	TD_ERR = -1,		/* Unspecified error. */
37 	TD_OK = 0,		/* No error. */
38 	TD_BADKEY,
39 	TD_BADPH,
40 	TD_BADSH,
41 	TD_BADTA,
42 	TD_BADTH,
43 	TD_DBERR,
44 	TD_MALLOC,
45 	TD_NOAPLIC,
46 	TD_NOCAPAB,
47 	TD_NOEVENT,
48 	TD_NOFPREGS,
49 	TD_NOLIBTHREAD,
50 	TD_NOLWP,
51 	TD_NOMSG,
52 	TD_NOSV,
53 	TD_NOTHR,
54 	TD_NOTSD,
55 	TD_NOXREGS,
56 	TD_PARTIALREG
57 } td_err_e;
58 
59 typedef struct td_thragent td_thragent_t;
60 typedef long thread_t;			/* Must be an integral type. */
61 
62 typedef struct {
63 	const td_thragent_t *th_ta;
64 	psaddr_t	th_thread;
65 	thread_t	th_tid;
66 } td_thrhandle_t;			/* Used non-opaguely. */
67 
68 /*
69  * Events.
70  */
71 
72 typedef enum {
73 	TD_EVENT_NONE = 0,
74 	TD_CREATE =	0x0001,
75 	TD_DEATH =	0x0002,
76 	TD_ALL_EVENTS = ~0
77 } td_thr_events_e;
78 
79 /* Compatibility with Linux. */
80 #define	td_event_e	td_thr_events_e
81 
82 typedef struct {
83 	td_thr_events_e	event;
84 	const td_thrhandle_t *th_p;
85 	uintptr_t	data;
86 } td_event_msg_t;
87 
88 typedef unsigned int td_thr_events_t;
89 
90 /* XXX can't be it... */
91 typedef struct {
92 	union {
93 		psaddr_t bptaddr;
94 	} u;
95 } td_notify_t;
96 
97 static __inline void
98 td_event_addset(td_thr_events_t *es, td_thr_events_e e)
99 {
100 	*es |= e;
101 }
102 
103 static __inline void
104 td_event_delset(td_thr_events_t *es, td_thr_events_e e)
105 {
106 	*es &= ~e;
107 }
108 
109 static __inline void
110 td_event_emptyset(td_thr_events_t *es)
111 {
112 	*es = TD_EVENT_NONE;
113 }
114 
115 static __inline void
116 td_event_fillset(td_thr_events_t *es)
117 {
118 	*es = TD_ALL_EVENTS;
119 }
120 
121 static __inline int
122 td_eventisempty(td_thr_events_t *es)
123 {
124 	return ((*es == TD_EVENT_NONE) ? 1 : 0);
125 }
126 
127 static __inline int
128 td_eventismember(td_thr_events_t *es, td_thr_events_e e)
129 {
130 	return ((*es & e) ? 1 : 0);
131 }
132 
133 /*
134  * Thread info.
135  */
136 
137 typedef enum {
138 	TD_THR_UNKNOWN = -1,
139 	TD_THR_ANY_STATE = 0,
140 	TD_THR_ACTIVE,
141 	TD_THR_RUN,
142 	TD_THR_SLEEP,
143 	TD_THR_STOPPED,
144 	TD_THR_STOPPED_ASLEEP,
145 	TD_THR_ZOMBIE
146 } td_thr_state_e;
147 
148 typedef enum
149 {
150 	TD_THR_SYSTEM = 1,
151 	TD_THR_USER
152 } td_thr_type_e;
153 
154 typedef int thread_key_t;
155 
156 #if 0
157 typedef struct td_thrinfo_t {
158 	unsigned int	ti_user_flags;
159 	psaddr_t	ti_pc;
160 	psaddr_t	ti_sp;
161 	short		ti_flags;
162 	uchar_t		ti_preemptflag;
163 	uchar_t		ti_pirecflag;
164 };
165 #endif
166 
167 typedef struct {
168 	const td_thragent_t *ti_ta_p;
169 	thread_t	ti_tid;
170 	td_thr_state_e	ti_state;
171 	td_thr_type_e	ti_type;
172 	td_thr_events_t	ti_events;
173 	int		ti_pri;
174 	lwpid_t		ti_lid;
175 	char		ti_db_suspended;
176 	char		ti_traceme;
177 	sigset_t	ti_sigmask;
178 	sigset_t	ti_pending;
179 	psaddr_t	ti_tls;
180 	psaddr_t	ti_startfunc;
181 	psaddr_t	ti_stkbase;
182 	size_t		ti_stksize;
183 } td_thrinfo_t;
184 
185 /*
186  * Prototypes.
187  */
188 
189 typedef int td_key_iter_f(thread_key_t, void (*)(void *), void *);
190 typedef int td_thr_iter_f(const td_thrhandle_t *, void *);
191 
192 /* Flags for `td_ta_thr_iter'. */
193 #define	TD_THR_ANY_USER_FLAGS	0xffffffff
194 #define	TD_THR_LOWEST_PRIORITY	-20
195 #define	TD_SIGNO_MASK		NULL
196 
197 __BEGIN_DECLS
198 td_err_e td_init(void);
199 
200 td_err_e td_ta_clear_event(const td_thragent_t *, td_thr_events_t *);
201 td_err_e td_ta_delete(td_thragent_t *);
202 td_err_e td_ta_event_addr(const td_thragent_t *, td_thr_events_e,
203     td_notify_t *);
204 td_err_e td_ta_event_getmsg(const td_thragent_t *, td_event_msg_t *);
205 td_err_e td_ta_map_id2thr(const td_thragent_t *, thread_t, td_thrhandle_t *);
206 td_err_e td_ta_map_lwp2thr(const td_thragent_t *, lwpid_t, td_thrhandle_t *);
207 td_err_e td_ta_new(struct ps_prochandle *, td_thragent_t **);
208 td_err_e td_ta_set_event(const td_thragent_t *, td_thr_events_t *);
209 td_err_e td_ta_thr_iter(const td_thragent_t *, td_thr_iter_f *, void *,
210     td_thr_state_e, int, sigset_t *, unsigned int);
211 td_err_e td_ta_tsd_iter(const td_thragent_t *, td_key_iter_f *, void *);
212 
213 td_err_e td_thr_clear_event(const td_thrhandle_t *, td_thr_events_t *);
214 td_err_e td_thr_dbresume(const td_thrhandle_t *);
215 td_err_e td_thr_dbsuspend(const td_thrhandle_t *);
216 td_err_e td_thr_event_enable(const td_thrhandle_t *, int);
217 td_err_e td_thr_event_getmsg(const td_thrhandle_t *, td_event_msg_t *);
218 td_err_e td_thr_get_info(const td_thrhandle_t *, td_thrinfo_t *);
219 td_err_e td_thr_getfpregs(const td_thrhandle_t *, prfpregset_t *);
220 td_err_e td_thr_getgregs(const td_thrhandle_t *, prgregset_t);
221 td_err_e td_thr_set_event(const td_thrhandle_t *, td_thr_events_t *);
222 td_err_e td_thr_setfpregs(const td_thrhandle_t *, const prfpregset_t *);
223 td_err_e td_thr_setgregs(const td_thrhandle_t *, const prgregset_t);
224 td_err_e td_thr_validate(const td_thrhandle_t *);
225 
226 /* FreeBSD specific extensions. */
227 td_err_e td_thr_sstep(const td_thrhandle_t *, int);
228 __END_DECLS
229 
230 #endif /* _THREAD_DB_H_ */
231