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