xref: /freebsd-src/lib/libthread_db/thread_db.h (revision b3e7694832e81d7a904a10f525f8797b753bf0d3)
15e53a4f9SPedro F. Giffuni /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
35e53a4f9SPedro F. Giffuni  *
4a7092d30SMarcel Moolenaar  * Copyright (c) 2004 David Xu <davidxu@freebsd.org>
53c1e38eaSMarcel Moolenaar  * Copyright (c) 2004 Marcel Moolenaar
63c1e38eaSMarcel Moolenaar  * All rights reserved.
73c1e38eaSMarcel Moolenaar  *
83c1e38eaSMarcel Moolenaar  * Redistribution and use in source and binary forms, with or without
93c1e38eaSMarcel Moolenaar  * modification, are permitted provided that the following conditions
103c1e38eaSMarcel Moolenaar  * are met:
113c1e38eaSMarcel Moolenaar  *
123c1e38eaSMarcel Moolenaar  * 1. Redistributions of source code must retain the above copyright
133c1e38eaSMarcel Moolenaar  *    notice, this list of conditions and the following disclaimer.
143c1e38eaSMarcel Moolenaar  * 2. Redistributions in binary form must reproduce the above copyright
153c1e38eaSMarcel Moolenaar  *    notice, this list of conditions and the following disclaimer in the
163c1e38eaSMarcel Moolenaar  *    documentation and/or other materials provided with the distribution.
173c1e38eaSMarcel Moolenaar  *
183c1e38eaSMarcel Moolenaar  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
193c1e38eaSMarcel Moolenaar  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
203c1e38eaSMarcel Moolenaar  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
213c1e38eaSMarcel Moolenaar  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
223c1e38eaSMarcel Moolenaar  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
233c1e38eaSMarcel Moolenaar  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
243c1e38eaSMarcel Moolenaar  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
253c1e38eaSMarcel Moolenaar  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
263c1e38eaSMarcel Moolenaar  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
273c1e38eaSMarcel Moolenaar  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
283c1e38eaSMarcel Moolenaar  */
293c1e38eaSMarcel Moolenaar 
303c1e38eaSMarcel Moolenaar #ifndef _THREAD_DB_H_
313c1e38eaSMarcel Moolenaar #define	_THREAD_DB_H_
323c1e38eaSMarcel Moolenaar 
333c1e38eaSMarcel Moolenaar #include <sys/procfs.h>
343c1e38eaSMarcel Moolenaar #include <pthread.h>
353c1e38eaSMarcel Moolenaar 
363c1e38eaSMarcel Moolenaar typedef enum {
373c1e38eaSMarcel Moolenaar 	TD_ERR = -1,		/* Unspecified error. */
383c1e38eaSMarcel Moolenaar 	TD_OK = 0,		/* No error. */
393c1e38eaSMarcel Moolenaar 	TD_BADKEY,
403c1e38eaSMarcel Moolenaar 	TD_BADPH,
413c1e38eaSMarcel Moolenaar 	TD_BADSH,
423c1e38eaSMarcel Moolenaar 	TD_BADTA,
433c1e38eaSMarcel Moolenaar 	TD_BADTH,
443c1e38eaSMarcel Moolenaar 	TD_DBERR,
453c1e38eaSMarcel Moolenaar 	TD_MALLOC,
463c1e38eaSMarcel Moolenaar 	TD_NOAPLIC,
473c1e38eaSMarcel Moolenaar 	TD_NOCAPAB,
483c1e38eaSMarcel Moolenaar 	TD_NOEVENT,
493c1e38eaSMarcel Moolenaar 	TD_NOFPREGS,
503c1e38eaSMarcel Moolenaar 	TD_NOLIBTHREAD,
513c1e38eaSMarcel Moolenaar 	TD_NOLWP,
523c1e38eaSMarcel Moolenaar 	TD_NOMSG,
533c1e38eaSMarcel Moolenaar 	TD_NOSV,
543c1e38eaSMarcel Moolenaar 	TD_NOTHR,
553c1e38eaSMarcel Moolenaar 	TD_NOTSD,
563c1e38eaSMarcel Moolenaar 	TD_NOXREGS,
573c1e38eaSMarcel Moolenaar 	TD_PARTIALREG
583c1e38eaSMarcel Moolenaar } td_err_e;
593c1e38eaSMarcel Moolenaar 
60a80845eaSDavid Xu struct ps_prochandle;
613c1e38eaSMarcel Moolenaar typedef struct td_thragent td_thragent_t;
623c1e38eaSMarcel Moolenaar typedef long thread_t;			/* Must be an integral type. */
633c1e38eaSMarcel Moolenaar 
643c1e38eaSMarcel Moolenaar typedef struct {
653c1e38eaSMarcel Moolenaar 	const td_thragent_t *th_ta;
663c1e38eaSMarcel Moolenaar 	psaddr_t	th_thread;
673c1e38eaSMarcel Moolenaar 	thread_t	th_tid;
683c1e38eaSMarcel Moolenaar } td_thrhandle_t;			/* Used non-opaguely. */
693c1e38eaSMarcel Moolenaar 
703c1e38eaSMarcel Moolenaar /*
713c1e38eaSMarcel Moolenaar  * Events.
723c1e38eaSMarcel Moolenaar  */
733c1e38eaSMarcel Moolenaar 
743c1e38eaSMarcel Moolenaar typedef enum {
753c1e38eaSMarcel Moolenaar 	TD_EVENT_NONE = 0,
76a7092d30SMarcel Moolenaar 	TD_CATCHSIG =	0x0001,
77a7092d30SMarcel Moolenaar 	TD_CONCURRENCY=	0x0002,
78a7092d30SMarcel Moolenaar 	TD_CREATE =	0x0004,
79a7092d30SMarcel Moolenaar 	TD_DEATH =	0x0008,
80a7092d30SMarcel Moolenaar 	TD_IDLE =	0x0010,
81a7092d30SMarcel Moolenaar 	TD_LOCK_TRY =	0x0020,
82a7092d30SMarcel Moolenaar 	TD_PREEMPT =	0x0040,
83a7092d30SMarcel Moolenaar 	TD_PRI_INHERIT=	0x0080,
84a7092d30SMarcel Moolenaar 	TD_READY =	0x0100,
85a7092d30SMarcel Moolenaar 	TD_REAP =	0x0200,
86a7092d30SMarcel Moolenaar 	TD_SLEEP =	0x0400,
87a7092d30SMarcel Moolenaar 	TD_SWITCHFROM =	0x0800,
88a7092d30SMarcel Moolenaar 	TD_SWITCHTO =	0x1000,
89a7092d30SMarcel Moolenaar 	TD_TIMEOUT =	0x2000,
903c1e38eaSMarcel Moolenaar 	TD_ALL_EVENTS = ~0
913c1e38eaSMarcel Moolenaar } td_thr_events_e;
923c1e38eaSMarcel Moolenaar 
933c1e38eaSMarcel Moolenaar /* Compatibility with Linux. */
943c1e38eaSMarcel Moolenaar #define	td_event_e	td_thr_events_e
953c1e38eaSMarcel Moolenaar 
963c1e38eaSMarcel Moolenaar typedef struct {
973c1e38eaSMarcel Moolenaar 	td_thr_events_e	event;
9803fad2adSMarcel Moolenaar 	psaddr_t	th_p;
993c1e38eaSMarcel Moolenaar 	uintptr_t	data;
1003c1e38eaSMarcel Moolenaar } td_event_msg_t;
1013c1e38eaSMarcel Moolenaar 
1023c1e38eaSMarcel Moolenaar typedef unsigned int td_thr_events_t;
1033c1e38eaSMarcel Moolenaar 
104a7092d30SMarcel Moolenaar typedef enum {
105a7092d30SMarcel Moolenaar 	NOTIFY_BPT,		/* User inserted breakpoint. */
106a7092d30SMarcel Moolenaar 	NOTIFY_AUTOBPT,		/* Automatic breakpoint. */
107a7092d30SMarcel Moolenaar 	NOTIFY_SYSCALL		/* Invocation of system call. */
108a7092d30SMarcel Moolenaar } td_notify_e;
109a7092d30SMarcel Moolenaar 
1103c1e38eaSMarcel Moolenaar typedef struct {
111a7092d30SMarcel Moolenaar 	td_notify_e	type;
1123c1e38eaSMarcel Moolenaar 	union {
1133c1e38eaSMarcel Moolenaar 		psaddr_t bptaddr;
114a7092d30SMarcel Moolenaar 		int syscallno;
1153c1e38eaSMarcel Moolenaar 	} u;
1163c1e38eaSMarcel Moolenaar } td_notify_t;
1173c1e38eaSMarcel Moolenaar 
1183c1e38eaSMarcel Moolenaar static __inline void
td_event_addset(td_thr_events_t * es,td_thr_events_e e)1193c1e38eaSMarcel Moolenaar td_event_addset(td_thr_events_t *es, td_thr_events_e e)
1203c1e38eaSMarcel Moolenaar {
1213c1e38eaSMarcel Moolenaar 	*es |= e;
1223c1e38eaSMarcel Moolenaar }
1233c1e38eaSMarcel Moolenaar 
1243c1e38eaSMarcel Moolenaar static __inline void
td_event_delset(td_thr_events_t * es,td_thr_events_e e)1253c1e38eaSMarcel Moolenaar td_event_delset(td_thr_events_t *es, td_thr_events_e e)
1263c1e38eaSMarcel Moolenaar {
1273c1e38eaSMarcel Moolenaar 	*es &= ~e;
1283c1e38eaSMarcel Moolenaar }
1293c1e38eaSMarcel Moolenaar 
1303c1e38eaSMarcel Moolenaar static __inline void
td_event_emptyset(td_thr_events_t * es)1313c1e38eaSMarcel Moolenaar td_event_emptyset(td_thr_events_t *es)
1323c1e38eaSMarcel Moolenaar {
1333c1e38eaSMarcel Moolenaar 	*es = TD_EVENT_NONE;
1343c1e38eaSMarcel Moolenaar }
1353c1e38eaSMarcel Moolenaar 
1363c1e38eaSMarcel Moolenaar static __inline void
td_event_fillset(td_thr_events_t * es)1373c1e38eaSMarcel Moolenaar td_event_fillset(td_thr_events_t *es)
1383c1e38eaSMarcel Moolenaar {
1393c1e38eaSMarcel Moolenaar 	*es = TD_ALL_EVENTS;
1403c1e38eaSMarcel Moolenaar }
1413c1e38eaSMarcel Moolenaar 
1423c1e38eaSMarcel Moolenaar static __inline int
td_eventisempty(td_thr_events_t * es)1433c1e38eaSMarcel Moolenaar td_eventisempty(td_thr_events_t *es)
1443c1e38eaSMarcel Moolenaar {
1453c1e38eaSMarcel Moolenaar 	return ((*es == TD_EVENT_NONE) ? 1 : 0);
1463c1e38eaSMarcel Moolenaar }
1473c1e38eaSMarcel Moolenaar 
1483c1e38eaSMarcel Moolenaar static __inline int
td_eventismember(td_thr_events_t * es,td_thr_events_e e)1493c1e38eaSMarcel Moolenaar td_eventismember(td_thr_events_t *es, td_thr_events_e e)
1503c1e38eaSMarcel Moolenaar {
1513c1e38eaSMarcel Moolenaar 	return ((*es & e) ? 1 : 0);
1523c1e38eaSMarcel Moolenaar }
1533c1e38eaSMarcel Moolenaar 
1543c1e38eaSMarcel Moolenaar /*
1553c1e38eaSMarcel Moolenaar  * Thread info.
1563c1e38eaSMarcel Moolenaar  */
1573c1e38eaSMarcel Moolenaar 
1583c1e38eaSMarcel Moolenaar typedef enum {
1593c1e38eaSMarcel Moolenaar 	TD_THR_UNKNOWN = -1,
1603c1e38eaSMarcel Moolenaar 	TD_THR_ANY_STATE = 0,
1613c1e38eaSMarcel Moolenaar 	TD_THR_ACTIVE,
1623c1e38eaSMarcel Moolenaar 	TD_THR_RUN,
1633c1e38eaSMarcel Moolenaar 	TD_THR_SLEEP,
1643c1e38eaSMarcel Moolenaar 	TD_THR_STOPPED,
1653c1e38eaSMarcel Moolenaar 	TD_THR_STOPPED_ASLEEP,
1663c1e38eaSMarcel Moolenaar 	TD_THR_ZOMBIE
1673c1e38eaSMarcel Moolenaar } td_thr_state_e;
1683c1e38eaSMarcel Moolenaar 
1693c1e38eaSMarcel Moolenaar typedef enum
1703c1e38eaSMarcel Moolenaar {
1713c1e38eaSMarcel Moolenaar 	TD_THR_SYSTEM = 1,
1723c1e38eaSMarcel Moolenaar 	TD_THR_USER
1733c1e38eaSMarcel Moolenaar } td_thr_type_e;
1743c1e38eaSMarcel Moolenaar 
175a7092d30SMarcel Moolenaar typedef pthread_key_t thread_key_t;
1763c1e38eaSMarcel Moolenaar 
1773c1e38eaSMarcel Moolenaar typedef struct {
1783c1e38eaSMarcel Moolenaar 	const td_thragent_t *ti_ta_p;
1793c1e38eaSMarcel Moolenaar 	thread_t	ti_tid;
1802ec2da86SDavid Xu 	psaddr_t	ti_thread;
1813c1e38eaSMarcel Moolenaar 	td_thr_state_e	ti_state;
1823c1e38eaSMarcel Moolenaar 	td_thr_type_e	ti_type;
1833c1e38eaSMarcel Moolenaar 	td_thr_events_t	ti_events;
1843c1e38eaSMarcel Moolenaar 	int		ti_pri;
1853c1e38eaSMarcel Moolenaar 	lwpid_t		ti_lid;
1863c1e38eaSMarcel Moolenaar 	char		ti_db_suspended;
18718860a1cSDag-Erling Smørgrav 	char		ti_traceme;
1883c1e38eaSMarcel Moolenaar 	sigset_t	ti_sigmask;
1893c1e38eaSMarcel Moolenaar 	sigset_t	ti_pending;
1903c1e38eaSMarcel Moolenaar 	psaddr_t	ti_tls;
1913c1e38eaSMarcel Moolenaar 	psaddr_t	ti_startfunc;
1923c1e38eaSMarcel Moolenaar 	psaddr_t	ti_stkbase;
1933c1e38eaSMarcel Moolenaar 	size_t		ti_stksize;
194098d0537SKonstantin Belousov 	siginfo_t	ti_siginfo;
1953c1e38eaSMarcel Moolenaar } td_thrinfo_t;
1963c1e38eaSMarcel Moolenaar 
1973c1e38eaSMarcel Moolenaar /*
1983c1e38eaSMarcel Moolenaar  * Prototypes.
1993c1e38eaSMarcel Moolenaar  */
2003c1e38eaSMarcel Moolenaar 
2013c1e38eaSMarcel Moolenaar typedef int td_key_iter_f(thread_key_t, void (*)(void *), void *);
2023c1e38eaSMarcel Moolenaar typedef int td_thr_iter_f(const td_thrhandle_t *, void *);
2033c1e38eaSMarcel Moolenaar 
2043c1e38eaSMarcel Moolenaar /* Flags for `td_ta_thr_iter'. */
2053c1e38eaSMarcel Moolenaar #define	TD_THR_ANY_USER_FLAGS	0xffffffff
2063c1e38eaSMarcel Moolenaar #define	TD_THR_LOWEST_PRIORITY	-20
2073c1e38eaSMarcel Moolenaar #define	TD_SIGNO_MASK		NULL
2083c1e38eaSMarcel Moolenaar 
2093c1e38eaSMarcel Moolenaar __BEGIN_DECLS
2103c1e38eaSMarcel Moolenaar td_err_e td_init(void);
2113c1e38eaSMarcel Moolenaar 
2123c1e38eaSMarcel Moolenaar td_err_e td_ta_clear_event(const td_thragent_t *, td_thr_events_t *);
2133c1e38eaSMarcel Moolenaar td_err_e td_ta_delete(td_thragent_t *);
2143c1e38eaSMarcel Moolenaar td_err_e td_ta_event_addr(const td_thragent_t *, td_thr_events_e,
2153c1e38eaSMarcel Moolenaar     td_notify_t *);
2163c1e38eaSMarcel Moolenaar td_err_e td_ta_event_getmsg(const td_thragent_t *, td_event_msg_t *);
2173c1e38eaSMarcel Moolenaar td_err_e td_ta_map_id2thr(const td_thragent_t *, thread_t, td_thrhandle_t *);
2183c1e38eaSMarcel Moolenaar td_err_e td_ta_map_lwp2thr(const td_thragent_t *, lwpid_t, td_thrhandle_t *);
2193c1e38eaSMarcel Moolenaar td_err_e td_ta_new(struct ps_prochandle *, td_thragent_t **);
2203c1e38eaSMarcel Moolenaar td_err_e td_ta_set_event(const td_thragent_t *, td_thr_events_t *);
2213c1e38eaSMarcel Moolenaar td_err_e td_ta_thr_iter(const td_thragent_t *, td_thr_iter_f *, void *,
2223c1e38eaSMarcel Moolenaar     td_thr_state_e, int, sigset_t *, unsigned int);
2233c1e38eaSMarcel Moolenaar td_err_e td_ta_tsd_iter(const td_thragent_t *, td_key_iter_f *, void *);
2243c1e38eaSMarcel Moolenaar 
2253c1e38eaSMarcel Moolenaar td_err_e td_thr_clear_event(const td_thrhandle_t *, td_thr_events_t *);
2263c1e38eaSMarcel Moolenaar td_err_e td_thr_dbresume(const td_thrhandle_t *);
2273c1e38eaSMarcel Moolenaar td_err_e td_thr_dbsuspend(const td_thrhandle_t *);
2283c1e38eaSMarcel Moolenaar td_err_e td_thr_event_enable(const td_thrhandle_t *, int);
2293c1e38eaSMarcel Moolenaar td_err_e td_thr_event_getmsg(const td_thrhandle_t *, td_event_msg_t *);
2303c1e38eaSMarcel Moolenaar td_err_e td_thr_get_info(const td_thrhandle_t *, td_thrinfo_t *);
2318d7681bbSDoug Rabson #ifdef __i386__
2328d7681bbSDoug Rabson td_err_e td_thr_getxmmregs(const td_thrhandle_t *, char *);
2338d7681bbSDoug Rabson #endif
2343c1e38eaSMarcel Moolenaar td_err_e td_thr_getfpregs(const td_thrhandle_t *, prfpregset_t *);
2353c1e38eaSMarcel Moolenaar td_err_e td_thr_getgregs(const td_thrhandle_t *, prgregset_t);
2363c1e38eaSMarcel Moolenaar td_err_e td_thr_set_event(const td_thrhandle_t *, td_thr_events_t *);
2378d7681bbSDoug Rabson #ifdef __i386__
2388d7681bbSDoug Rabson td_err_e td_thr_setxmmregs(const td_thrhandle_t *, const char *);
2398d7681bbSDoug Rabson #endif
2403c1e38eaSMarcel Moolenaar td_err_e td_thr_setfpregs(const td_thrhandle_t *, const prfpregset_t *);
2413c1e38eaSMarcel Moolenaar td_err_e td_thr_setgregs(const td_thrhandle_t *, const prgregset_t);
2423c1e38eaSMarcel Moolenaar td_err_e td_thr_validate(const td_thrhandle_t *);
24316b0c20cSMarcel Moolenaar td_err_e td_thr_tls_get_addr(const td_thrhandle_t *, psaddr_t, size_t,
24416b0c20cSMarcel Moolenaar     psaddr_t *);
2453c1e38eaSMarcel Moolenaar 
2463c1e38eaSMarcel Moolenaar /* FreeBSD specific extensions. */
2473c1e38eaSMarcel Moolenaar td_err_e td_thr_sstep(const td_thrhandle_t *, int);
2483c1e38eaSMarcel Moolenaar __END_DECLS
2493c1e38eaSMarcel Moolenaar 
2503c1e38eaSMarcel Moolenaar #endif /* _THREAD_DB_H_ */
251