Add rudimentary support and stubs for libthr and libc_r on alpha, amd64,
i386, ia64 and sparc64. Add stubs for alpha, amd64, ia64 and sparc64 for libpthread. Restructure the source files to avoid unnecessary use of subdirectories that also force us to use non-portable compilation flags to deal with the uncommon compilation requirements (building archive libraries for linkage into a shared library). The libpthread support has been copied from the original local and cleaned-up to make them WARNS=2 clean. that also force us to use non-portable compilation flags to deal with the uncommon compilation requirements (building archive libraries for linkage into a shared library). The libpthread support has been copied from the original local and cleaned-up to make them WARNS=2 clean. Tested on: amd64, i386, ia64
This commit is contained in:
parent
606ea367ae
commit
03a64a6205
@ -1,5 +1,28 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SUBDIR=pthread src
|
||||
.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
LIB= thread_db
|
||||
SHLIB_MAJOR= 1
|
||||
SRCS= thread_db.c
|
||||
SRCS+= libpthread_db.c libpthread_md.c
|
||||
SRCS+= libc_r_db.c libc_r_md.c
|
||||
SRCS+= libthr_db.c
|
||||
INCS= thread_db.h
|
||||
WARNS?= 2
|
||||
|
||||
CFLAGS+=-I. -I${.CURDIR}
|
||||
|
||||
SRCS+= libpthread.h
|
||||
CLEANFILES+= libpthread.h
|
||||
|
||||
LIBPTHREAD= ${.CURDIR}/../libpthread
|
||||
LIBPTHREAD_ARCH= ${LIBPTHREAD}/arch/${MACHINE_ARCH}/include
|
||||
|
||||
libpthread.h:
|
||||
@echo '#define LIBTHREAD_DB 1' > ${.TARGET}
|
||||
@echo '#include "${LIBPTHREAD}/sys/lock.h"' >> ${.TARGET}
|
||||
@echo '#include "${LIBPTHREAD_ARCH}/pthread_md.h"' >> ${.TARGET}
|
||||
@echo '#include "${LIBPTHREAD}/thread/thr_private.h"' >> ${.TARGET}
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
73
lib/libthread_db/arch/alpha/libc_r_md.c
Normal file
73
lib/libthread_db/arch/alpha/libc_r_md.c
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Marcel Moolenaar
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/procfs.h>
|
||||
#include <machine/setjmp.h>
|
||||
|
||||
void
|
||||
libc_r_md_getgregs(jmp_buf jb, prgregset_t *r)
|
||||
{
|
||||
r->r_regs[R_V0] = jb->_jb[4];
|
||||
r->r_regs[R_T0] = jb->_jb[5];
|
||||
r->r_regs[R_T1] = jb->_jb[6];
|
||||
r->r_regs[R_T2] = jb->_jb[7];
|
||||
r->r_regs[R_T3] = jb->_jb[8];
|
||||
r->r_regs[R_T4] = jb->_jb[9];
|
||||
r->r_regs[R_T5] = jb->_jb[10];
|
||||
r->r_regs[R_T6] = jb->_jb[11];
|
||||
r->r_regs[R_T7] = jb->_jb[12];
|
||||
r->r_regs[R_S0] = jb->_jb[13];
|
||||
r->r_regs[R_S1] = jb->_jb[14];
|
||||
r->r_regs[R_S2] = jb->_jb[15];
|
||||
r->r_regs[R_S3] = jb->_jb[16];
|
||||
r->r_regs[R_S4] = jb->_jb[17];
|
||||
r->r_regs[R_S5] = jb->_jb[18];
|
||||
r->r_regs[R_S6] = jb->_jb[19];
|
||||
r->r_regs[R_A0] = jb->_jb[20];
|
||||
r->r_regs[R_A1] = jb->_jb[21];
|
||||
r->r_regs[R_A2] = jb->_jb[22];
|
||||
r->r_regs[R_A3] = jb->_jb[23];
|
||||
r->r_regs[R_A4] = jb->_jb[24];
|
||||
r->r_regs[R_A5] = jb->_jb[25];
|
||||
r->r_regs[R_T8] = jb->_jb[26];
|
||||
r->r_regs[R_T9] = jb->_jb[27];
|
||||
r->r_regs[R_T10] = jb->_jb[28];
|
||||
r->r_regs[R_T11] = jb->_jb[29];
|
||||
r->r_regs[R_RA] = jb->_jb[30];
|
||||
r->r_regs[R_T12] = jb->_jb[31];
|
||||
r->r_regs[R_AT] = jb->_jb[32];
|
||||
r->r_regs[R_GP] = jb->_jb[33];
|
||||
r->r_regs[R_SP] = jb->_jb[34];
|
||||
r->r_regs[R_ZERO] = jb->_jb[35];
|
||||
}
|
||||
|
||||
void
|
||||
libc_r_md_getfpregs(jmp_buf jb, prfpregset_t *r)
|
||||
{
|
||||
}
|
59
lib/libthread_db/arch/alpha/libpthread_md.c
Normal file
59
lib/libthread_db/arch/alpha/libpthread_md.c
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Marcel Moolenaar
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
void
|
||||
pt_reg_to_ucontext(const struct reg *r, ucontext_t *uc)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
pt_ucontext_to_reg(const ucontext_t *uc, struct reg *r)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
pt_fpreg_to_ucontext(const struct fpreg* r, ucontext_t *uc)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
pt_ucontext_to_fpreg(const ucontext_t *uc, struct fpreg *r)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
pt_md_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
pt_reg_sstep(struct reg *reg, int step)
|
||||
{
|
||||
return (0);
|
||||
}
|
41
lib/libthread_db/arch/amd64/libc_r_md.c
Normal file
41
lib/libthread_db/arch/amd64/libc_r_md.c
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Marcel Moolenaar
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/procfs.h>
|
||||
#include <machine/setjmp.h>
|
||||
|
||||
void
|
||||
libc_r_md_getgregs(jmp_buf jb, prgregset_t *r)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
libc_r_md_getfpregs(jmp_buf jb, prfpregset_t *r)
|
||||
{
|
||||
}
|
59
lib/libthread_db/arch/amd64/libpthread_md.c
Normal file
59
lib/libthread_db/arch/amd64/libpthread_md.c
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Marcel Moolenaar
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
void
|
||||
pt_reg_to_ucontext(const struct reg *r, ucontext_t *uc)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
pt_ucontext_to_reg(const ucontext_t *uc, struct reg *r)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
pt_fpreg_to_ucontext(const struct fpreg* r, ucontext_t *uc)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
pt_ucontext_to_fpreg(const ucontext_t *uc, struct fpreg *r)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
pt_md_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
pt_reg_sstep(struct reg *reg, int step)
|
||||
{
|
||||
return (0);
|
||||
}
|
48
lib/libthread_db/arch/i386/libc_r_md.c
Normal file
48
lib/libthread_db/arch/i386/libc_r_md.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Marcel Moolenaar
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/procfs.h>
|
||||
#include <machine/setjmp.h>
|
||||
|
||||
void
|
||||
libc_r_md_getgregs(jmp_buf jb, prgregset_t r)
|
||||
{
|
||||
r->r_eip = jb->_jb[0];
|
||||
r->r_ebx = jb->_jb[1];
|
||||
r->r_esp = jb->_jb[2];
|
||||
r->r_ebp = jb->_jb[3];
|
||||
r->r_esi = jb->_jb[4];
|
||||
r->r_edi = jb->_jb[5];
|
||||
r->r_eax = jb->_jb[6];
|
||||
}
|
||||
|
||||
void
|
||||
libc_r_md_getfpregs(jmp_buf jb, prfpregset_t *r)
|
||||
{
|
||||
}
|
@ -33,7 +33,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <thread_db.h>
|
||||
#include <machine/npx.h>
|
||||
|
||||
#include "pthread_db.h"
|
||||
#include "libpthread_db.h"
|
||||
|
||||
static int has_xmm_regs;
|
||||
|
41
lib/libthread_db/arch/ia64/libc_r_md.c
Normal file
41
lib/libthread_db/arch/ia64/libc_r_md.c
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Marcel Moolenaar
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/procfs.h>
|
||||
#include <machine/setjmp.h>
|
||||
|
||||
void
|
||||
libc_r_md_getgregs(jmp_buf jb, prgregset_t *r)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
libc_r_md_getfpregs(jmp_buf jb, prfpregset_t *r)
|
||||
{
|
||||
}
|
59
lib/libthread_db/arch/ia64/libpthread_md.c
Normal file
59
lib/libthread_db/arch/ia64/libpthread_md.c
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Marcel Moolenaar
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
void
|
||||
pt_reg_to_ucontext(const struct reg *r, ucontext_t *uc)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
pt_ucontext_to_reg(const ucontext_t *uc, struct reg *r)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
pt_fpreg_to_ucontext(const struct fpreg* r, ucontext_t *uc)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
pt_ucontext_to_fpreg(const ucontext_t *uc, struct fpreg *r)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
pt_md_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
pt_reg_sstep(struct reg *reg, int step)
|
||||
{
|
||||
return (0);
|
||||
}
|
41
lib/libthread_db/arch/sparc64/libc_r_md.c
Normal file
41
lib/libthread_db/arch/sparc64/libc_r_md.c
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Marcel Moolenaar
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/procfs.h>
|
||||
#include <machine/setjmp.h>
|
||||
|
||||
void
|
||||
libc_r_md_getgregs(jmp_buf jb, prgregset_t *r)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
libc_r_md_getfpregs(jmp_buf jb, prfpregset_t *r)
|
||||
{
|
||||
}
|
59
lib/libthread_db/arch/sparc64/libpthread_md.c
Normal file
59
lib/libthread_db/arch/sparc64/libpthread_md.c
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Marcel Moolenaar
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
void
|
||||
pt_reg_to_ucontext(const struct reg *r, ucontext_t *uc)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
pt_ucontext_to_reg(const ucontext_t *uc, struct reg *r)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
pt_fpreg_to_ucontext(const struct fpreg* r, ucontext_t *uc)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
pt_ucontext_to_fpreg(const ucontext_t *uc, struct fpreg *r)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
pt_md_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
pt_reg_sstep(struct reg *reg, int step)
|
||||
{
|
||||
return (0);
|
||||
}
|
@ -1,287 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 David Xu <davidxu@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _THREAD_DB_H_
|
||||
#define _THREAD_DB_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <pthread.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TD_OK,
|
||||
TD_ERR,
|
||||
TD_NOTHR,
|
||||
TD_NOSV,
|
||||
TD_NOLWP,
|
||||
TD_BADPH,
|
||||
TD_BADTH,
|
||||
TD_BADSH,
|
||||
TD_BADTA,
|
||||
TD_BADKEY,
|
||||
TD_NOMSG,
|
||||
TD_NOFPREGS,
|
||||
TD_NOLIBTHREAD,
|
||||
TD_NOEVENT,
|
||||
TD_NOCAPAB,
|
||||
TD_DBERR,
|
||||
TD_NOAPLIC,
|
||||
TD_NOTSD,
|
||||
TD_MALLOC,
|
||||
TD_PARTIALREG,
|
||||
TD_NOXREGS
|
||||
} td_err_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TD_THR_ANY_STATE,
|
||||
TD_THR_UNKNOWN,
|
||||
TD_THR_STOPPED,
|
||||
TD_THR_RUN,
|
||||
TD_THR_ACTIVE,
|
||||
TD_THR_ZOMBIE,
|
||||
TD_THR_SLEEP,
|
||||
TD_THR_STOPPED_ASLEEP
|
||||
} td_thr_state_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TD_THR_ANY_TYPE,
|
||||
TD_THR_USER,
|
||||
TD_THR_SYSTEM
|
||||
} td_thr_type_e;
|
||||
|
||||
typedef long thread_t;
|
||||
typedef pthread_key_t thread_key_t;
|
||||
typedef struct td_thragent td_thragent_t;
|
||||
|
||||
typedef struct td_thrhandle
|
||||
{
|
||||
td_thragent_t *th_ta_p;
|
||||
thread_t th_unique;
|
||||
int th_ta_data;
|
||||
} td_thrhandle_t;
|
||||
|
||||
/* Flags for `td_ta_thr_iter'. */
|
||||
#define TD_THR_ANY_USER_FLAGS 0xffffffff
|
||||
#define TD_THR_LOWEST_PRIORITY 0
|
||||
#define TD_SIGNO_MASK NULL
|
||||
|
||||
typedef uint32_t td_thr_events_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TD_ALL_EVENTS,
|
||||
TD_EVENT_NONE = TD_ALL_EVENTS,
|
||||
TD_CREATE,
|
||||
TD_DEATH,
|
||||
TD_REAP,
|
||||
TD_READY,
|
||||
TD_SLEEP,
|
||||
TD_SWITCHTO,
|
||||
TD_SWITCHFROM,
|
||||
TD_LOCK_TRY,
|
||||
TD_CATCHSIG,
|
||||
TD_IDLE,
|
||||
TD_PREEMPT,
|
||||
TD_PRI_INHERIT,
|
||||
TD_CONCURRENCY,
|
||||
TD_TIMEOUT,
|
||||
TD_MIN_EVENT_NUM = TD_READY,
|
||||
TD_MAX_EVENT_NUM = TD_TIMEOUT,
|
||||
TD_EVENTS_ENABLE = 31
|
||||
} td_event_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NOTIFY_BPT,
|
||||
NOTIFY_AUTOBPT,
|
||||
NOTIFY_SYSCALL
|
||||
} td_notify_e;
|
||||
|
||||
typedef struct td_notify
|
||||
{
|
||||
td_notify_e type;
|
||||
union {
|
||||
psaddr_t bptaddr;
|
||||
int syscallno;
|
||||
} u;
|
||||
} td_notify_t;
|
||||
|
||||
typedef struct td_event_msg
|
||||
{
|
||||
td_event_e event;
|
||||
const td_thrhandle_t *th_p;
|
||||
union {
|
||||
#if 0
|
||||
td_synchandle_t *sh;
|
||||
#endif
|
||||
uintptr_t data;
|
||||
} msg;
|
||||
} td_event_msg_t;
|
||||
|
||||
/* Structure containing event data available in each thread structure. */
|
||||
typedef struct
|
||||
{
|
||||
td_thr_events_t eventmask; /* Mask of enabled events. */
|
||||
td_event_e eventnum; /* Number of last event. */
|
||||
void *eventdata; /* Data associated with event. */
|
||||
} td_eventbuf_t;
|
||||
|
||||
/* Gathered statistics about the process. */
|
||||
typedef struct td_ta_stats
|
||||
{
|
||||
int nthreads; /* Total number of threads in use. */
|
||||
int r_concurrency; /* Concurrency level requested by user. */
|
||||
int nrunnable_num; /* Average runnable threads, numerator. */
|
||||
int nrunnable_den; /* Average runnable threads, denominator. */
|
||||
int a_concurrency_num; /* Achieved concurrency level, numerator. */
|
||||
int a_concurrency_den; /* Achieved concurrency level, denominator. */
|
||||
int nlwps_num; /* Average number of processes in use,
|
||||
numerator. */
|
||||
int nlwps_den; /* Average number of processes in use,
|
||||
denominator. */
|
||||
int nidle_num; /* Average number of idling processes,
|
||||
numerator. */
|
||||
int nidle_den; /* Average number of idling processes,
|
||||
denominator. */
|
||||
} td_ta_stats_t;
|
||||
|
||||
static inline void
|
||||
td_event_emptyset(td_thr_events_t *setp)
|
||||
{
|
||||
*setp = 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
td_event_fillset(td_thr_events_t *setp)
|
||||
{
|
||||
*setp = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
static inline void
|
||||
td_event_addset(td_thr_events_t *setp, int n)
|
||||
{
|
||||
*setp |= (1 << (n-1));
|
||||
}
|
||||
|
||||
static inline void
|
||||
td_event_delset(td_thr_events_t *setp, int n)
|
||||
{
|
||||
*setp &= ~(1 << (n-1));
|
||||
}
|
||||
|
||||
static inline int
|
||||
td_eventismember(td_thr_events_t *setp, int n)
|
||||
{
|
||||
return (*setp & (1 << (n-1)) ? 1 : 0);
|
||||
}
|
||||
|
||||
static inline int
|
||||
td_eventisempty(td_thr_events_t *setp)
|
||||
{
|
||||
return (*setp == 0);
|
||||
}
|
||||
|
||||
typedef int td_thr_iter_f(const td_thrhandle_t *, void *);
|
||||
typedef int td_key_iter_f(thread_key_t, void (*) (void *), void *);
|
||||
|
||||
struct ps_prochandle;
|
||||
|
||||
typedef struct td_thrinfo
|
||||
{
|
||||
td_thragent_t *ti_ta_p;
|
||||
unsigned int ti_user_flags;
|
||||
thread_t ti_tid;
|
||||
char *ti_tls;
|
||||
psaddr_t ti_startfunc;
|
||||
psaddr_t ti_stkbase;
|
||||
long int ti_stksize;
|
||||
psaddr_t ti_ro_area;
|
||||
int ti_ro_size;
|
||||
td_thr_state_e ti_state;
|
||||
unsigned char ti_db_suspended;
|
||||
td_thr_type_e ti_type;
|
||||
intptr_t ti_pc;
|
||||
intptr_t ti_sp;
|
||||
short int ti_flags;
|
||||
int ti_pri;
|
||||
lwpid_t ti_lid;
|
||||
sigset_t ti_sigmask;
|
||||
unsigned char ti_traceme;
|
||||
unsigned char ti_preemptflag;
|
||||
unsigned char ti_pirecflag;
|
||||
sigset_t ti_pending;
|
||||
td_thr_events_t ti_events;
|
||||
} td_thrinfo_t;
|
||||
|
||||
td_err_e td_init(void);
|
||||
td_err_e td_log(void);
|
||||
td_err_e td_ta_new(struct ps_prochandle *, td_thragent_t **);
|
||||
td_err_e td_ta_delete(td_thragent_t *);
|
||||
td_err_e td_ta_get_nthreads(const td_thragent_t *, int *);
|
||||
td_err_e td_ta_get_ph(const td_thragent_t *, struct ps_prochandle **);
|
||||
td_err_e td_ta_map_id2thr(const td_thragent_t *, thread_t, td_thrhandle_t *);
|
||||
td_err_e td_ta_map_lwp2thr(const td_thragent_t *, lwpid_t lwpid,
|
||||
td_thrhandle_t *);
|
||||
td_err_e td_ta_thr_iter(const td_thragent_t *, td_thr_iter_f *, void *,
|
||||
td_thr_state_e, int, sigset_t *, unsigned int);
|
||||
td_err_e td_ta_tsd_iter(const td_thragent_t *, td_key_iter_f *, void *);
|
||||
td_err_e td_ta_event_addr(const td_thragent_t *, td_event_e , td_notify_t *);
|
||||
td_err_e td_ta_set_event(const td_thragent_t *, td_thr_events_t *);
|
||||
td_err_e td_ta_clear_event(const td_thragent_t *, td_thr_events_t *);
|
||||
td_err_e td_ta_event_getmsg(const td_thragent_t *, td_event_msg_t *);
|
||||
td_err_e td_ta_setconcurrency(const td_thragent_t *, int);
|
||||
td_err_e td_ta_enable_stats(const td_thragent_t *, int);
|
||||
td_err_e td_ta_reset_stats(const td_thragent_t *);
|
||||
td_err_e td_ta_get_stats(const td_thragent_t *, td_ta_stats_t *);
|
||||
td_err_e td_thr_validate(const td_thrhandle_t *);
|
||||
td_err_e td_thr_get_info(const td_thrhandle_t *, td_thrinfo_t *);
|
||||
td_err_e td_thr_getfpregs(const td_thrhandle_t *, prfpregset_t *);
|
||||
td_err_e td_thr_getgregs(const td_thrhandle_t *, prgregset_t);
|
||||
td_err_e td_thr_getxregs(const td_thrhandle_t *, void *);
|
||||
td_err_e td_thr_getxregsize(const td_thrhandle_t *, int *);
|
||||
td_err_e td_thr_setfpregs(const td_thrhandle_t *, const prfpregset_t *);
|
||||
td_err_e td_thr_setgregs(const td_thrhandle_t *, const prgregset_t);
|
||||
td_err_e td_thr_setxregs(const td_thrhandle_t *, const void *);
|
||||
td_err_e td_thr_event_enable(const td_thrhandle_t *, int);
|
||||
td_err_e td_thr_set_event(const td_thrhandle_t *, td_thr_events_t *);
|
||||
td_err_e td_thr_clear_event(const td_thrhandle_t *, td_thr_events_t *);
|
||||
td_err_e td_thr_event_getmsg(const td_thrhandle_t *, td_event_msg_t *);
|
||||
td_err_e td_thr_setprio(const td_thrhandle_t *, int);
|
||||
td_err_e td_thr_setsigpending(const td_thrhandle_t *, unsigned char,
|
||||
const sigset_t *);
|
||||
td_err_e td_thr_sigsetmask(const td_thrhandle_t *, const sigset_t *);
|
||||
td_err_e td_thr_tsd(const td_thrhandle_t *, const thread_key_t, void **);
|
||||
td_err_e td_thr_dbsuspend(const td_thrhandle_t *);
|
||||
td_err_e td_thr_dbresume(const td_thrhandle_t *);
|
||||
td_err_e td_get_ta(int pid, td_thragent_t **);
|
||||
td_err_e td_ta_activated(td_thragent_t *, int *);
|
||||
td_err_e td_thr_sstep(td_thrhandle_t *, int);
|
||||
|
||||
#endif
|
328
lib/libthread_db/libc_r_db.c
Normal file
328
lib/libthread_db/libc_r_db.c
Normal file
@ -0,0 +1,328 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Marcel Moolenaar
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <machine/setjmp.h>
|
||||
#include <proc_service.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <thread_db.h>
|
||||
|
||||
#include "thread_db_int.h"
|
||||
|
||||
void libc_r_md_getfpregs(jmp_buf jb, prfpregset_t *);
|
||||
void libc_r_md_getgregs(jmp_buf jb, prgregset_t);
|
||||
|
||||
struct td_thragent {
|
||||
TD_THRAGENT_FIELDS;
|
||||
struct ps_prochandle *ta_ph;
|
||||
psaddr_t ta_thread_initial;
|
||||
psaddr_t ta_thread_list;
|
||||
psaddr_t ta_thread_run;
|
||||
int ta_ofs_ctx;
|
||||
int ta_ofs_next;
|
||||
int ta_ofs_uniqueid;
|
||||
};
|
||||
|
||||
static td_err_e
|
||||
libc_r_db_init()
|
||||
{
|
||||
return (TD_OK);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libc_r_db_ta_clear_event(const td_thragent_t *ta, td_thr_events_t *ev)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libc_r_db_ta_delete(td_thragent_t *ta)
|
||||
{
|
||||
free(ta);
|
||||
return (TD_OK);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libc_r_db_ta_event_addr(const td_thragent_t *ta, td_thr_events_e ev,
|
||||
td_notify_t *n)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libc_r_db_ta_event_getmsg(const td_thragent_t *ta, td_event_msg_t *msg)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libc_r_db_ta_map_id2thr(const td_thragent_t *ta, thread_t tid,
|
||||
td_thrhandle_t *th)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libc_r_db_ta_map_lwp2thr(const td_thragent_t *ta, lwpid_t lwpid,
|
||||
td_thrhandle_t *th)
|
||||
{
|
||||
psaddr_t addr;
|
||||
ps_err_e err;
|
||||
|
||||
th->th_ta = ta;
|
||||
err = ps_pread(ta->ta_ph, ta->ta_thread_initial, &addr, sizeof(addr));
|
||||
if (err != PS_OK)
|
||||
return (TD_ERR);
|
||||
if (addr == NULL)
|
||||
return (TD_NOLWP);
|
||||
err = ps_pread(ta->ta_ph, ta->ta_thread_run, &th->th_thread,
|
||||
sizeof(psaddr_t));
|
||||
return ((err == PS_OK) ? TD_OK : TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libc_r_db_ta_new(struct ps_prochandle *ph, td_thragent_t **ta_p)
|
||||
{
|
||||
td_thragent_t *ta;
|
||||
psaddr_t addr;
|
||||
ps_err_e err;
|
||||
|
||||
ta = malloc(sizeof(td_thragent_t));
|
||||
if (ta == NULL)
|
||||
return (TD_MALLOC);
|
||||
|
||||
ta->ta_ph = ph;
|
||||
|
||||
err = ps_pglobal_lookup(ph, NULL, "_thread_initial",
|
||||
&ta->ta_thread_initial);
|
||||
if (err != PS_OK)
|
||||
goto fail;
|
||||
err = ps_pglobal_lookup(ph, NULL, "_thread_list", &ta->ta_thread_list);
|
||||
if (err != PS_OK)
|
||||
goto fail;
|
||||
err = ps_pglobal_lookup(ph, NULL, "_thread_run", &ta->ta_thread_run);
|
||||
if (err != PS_OK)
|
||||
goto fail;
|
||||
err = ps_pglobal_lookup(ph, NULL, "_thread_ctx_offset", &addr);
|
||||
if (err != PS_OK)
|
||||
goto fail;
|
||||
err = ps_pread(ph, addr, &ta->ta_ofs_ctx, sizeof(int));
|
||||
if (err != PS_OK)
|
||||
goto fail;
|
||||
err = ps_pglobal_lookup(ph, NULL, "_thread_next_offset", &addr);
|
||||
if (err != PS_OK)
|
||||
goto fail;
|
||||
err = ps_pread(ph, addr, &ta->ta_ofs_next, sizeof(int));
|
||||
if (err != PS_OK)
|
||||
goto fail;
|
||||
err = ps_pglobal_lookup(ph, NULL, "_thread_uniqueid_offset", &addr);
|
||||
if (err != PS_OK)
|
||||
goto fail;
|
||||
err = ps_pread(ph, addr, &ta->ta_ofs_uniqueid, sizeof(int));
|
||||
if (err != PS_OK)
|
||||
goto fail;
|
||||
|
||||
*ta_p = ta;
|
||||
return (TD_OK);
|
||||
|
||||
fail:
|
||||
free(ta);
|
||||
*ta_p = NULL;
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libc_r_db_ta_set_event(const td_thragent_t *ta, td_thr_events_t *ev)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libc_r_db_ta_thr_iter(const td_thragent_t *ta, td_thr_iter_f *cb, void *data,
|
||||
td_thr_state_e state, int pri, sigset_t *mask, unsigned int flags)
|
||||
{
|
||||
td_thrhandle_t th;
|
||||
psaddr_t addr;
|
||||
ps_err_e err;
|
||||
|
||||
th.th_ta = ta;
|
||||
|
||||
err = ps_pread(ta->ta_ph, ta->ta_thread_list, &th.th_thread,
|
||||
sizeof(th.th_thread));
|
||||
if (err != PS_OK)
|
||||
return (TD_ERR);
|
||||
while (th.th_thread != NULL) {
|
||||
if (cb(&th, data) != 0)
|
||||
return (TD_OK);
|
||||
addr = (psaddr_t)((uintptr_t)th.th_thread + ta->ta_ofs_next);
|
||||
err = ps_pread(ta->ta_ph, addr, &th.th_thread,
|
||||
sizeof(th.th_thread));
|
||||
if (err != PS_OK)
|
||||
return (TD_ERR);
|
||||
}
|
||||
return (TD_OK);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libc_r_db_thr_clear_event(const td_thrhandle_t *th, td_thr_events_t *ev)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libc_r_db_thr_event_enable(const td_thrhandle_t *th, int oo)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libc_r_db_thr_event_getmsg(const td_thrhandle_t *th, td_event_msg_t *msg)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libc_r_db_thr_get_info(const td_thrhandle_t *th, td_thrinfo_t *ti)
|
||||
{
|
||||
const td_thragent_t *ta;
|
||||
psaddr_t addr, current;
|
||||
ps_err_e err;
|
||||
|
||||
ta = th->th_ta;
|
||||
ti->ti_ta_p = ta;
|
||||
err = ps_pread(ta->ta_ph, ta->ta_thread_run, ¤t,
|
||||
sizeof(psaddr_t));
|
||||
if (err != PS_OK)
|
||||
return (TD_ERR);
|
||||
ti->ti_lid = (th->th_thread == current) ? -1 : 0;
|
||||
addr = (psaddr_t)((uintptr_t)th->th_thread + ta->ta_ofs_uniqueid);
|
||||
err = ps_pread(ta->ta_ph, addr, &ti->ti_tid, sizeof(thread_t));
|
||||
/* libc_r numbers its threads starting with 0. Not smart. */
|
||||
ti->ti_tid++;
|
||||
return ((err == PS_OK) ? TD_OK : TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libc_r_db_thr_getfpregs(const td_thrhandle_t *th, prfpregset_t *r)
|
||||
{
|
||||
jmp_buf jb;
|
||||
const td_thragent_t *ta;
|
||||
psaddr_t addr;
|
||||
ps_err_e err;
|
||||
|
||||
ta = th->th_ta;
|
||||
err = ps_lgetfpregs(ta->ta_ph, -1, r);
|
||||
if (err != PS_OK)
|
||||
return (TD_ERR);
|
||||
err = ps_pread(ta->ta_ph, ta->ta_thread_run, &addr, sizeof(psaddr_t));
|
||||
if (err != PS_OK)
|
||||
return (TD_ERR);
|
||||
if (th->th_thread == addr)
|
||||
return (TD_OK);
|
||||
addr = (psaddr_t)((uintptr_t)th->th_thread + ta->ta_ofs_ctx);
|
||||
err = ps_pread(ta->ta_ph, addr, jb, sizeof(jb));
|
||||
if (err != PS_OK)
|
||||
return (TD_ERR);
|
||||
libc_r_md_getfpregs(jb, r);
|
||||
return (TD_OK);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libc_r_db_thr_getgregs(const td_thrhandle_t *th, prgregset_t r)
|
||||
{
|
||||
jmp_buf jb;
|
||||
const td_thragent_t *ta;
|
||||
psaddr_t addr;
|
||||
ps_err_e err;
|
||||
|
||||
ta = th->th_ta;
|
||||
err = ps_lgetregs(ta->ta_ph, -1, r);
|
||||
if (err != PS_OK)
|
||||
return (TD_ERR);
|
||||
err = ps_pread(ta->ta_ph, ta->ta_thread_run, &addr, sizeof(psaddr_t));
|
||||
if (err != PS_OK)
|
||||
return (TD_ERR);
|
||||
if (th->th_thread == addr)
|
||||
return (TD_OK);
|
||||
addr = (psaddr_t)((uintptr_t)th->th_thread + ta->ta_ofs_ctx);
|
||||
err = ps_pread(ta->ta_ph, addr, jb, sizeof(jb));
|
||||
if (err != PS_OK)
|
||||
return (TD_ERR);
|
||||
libc_r_md_getgregs(jb, r);
|
||||
return (TD_OK);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libc_r_db_thr_set_event(const td_thrhandle_t *th, td_thr_events_t *ev)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libc_r_db_thr_setfpregs(const td_thrhandle_t *th, const prfpregset_t *r)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libc_r_db_thr_setgregs(const td_thrhandle_t *th, const prgregset_t r)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libc_r_db_thr_validate(const td_thrhandle_t *th)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
struct ta_ops libc_r_db_ops = {
|
||||
.to_init = libc_r_db_init,
|
||||
|
||||
.to_ta_clear_event = libc_r_db_ta_clear_event,
|
||||
.to_ta_delete = libc_r_db_ta_delete,
|
||||
.to_ta_event_addr = libc_r_db_ta_event_addr,
|
||||
.to_ta_event_getmsg = libc_r_db_ta_event_getmsg,
|
||||
.to_ta_map_id2thr = libc_r_db_ta_map_id2thr,
|
||||
.to_ta_map_lwp2thr = libc_r_db_ta_map_lwp2thr,
|
||||
.to_ta_new = libc_r_db_ta_new,
|
||||
.to_ta_set_event = libc_r_db_ta_set_event,
|
||||
.to_ta_thr_iter = libc_r_db_ta_thr_iter,
|
||||
|
||||
.to_thr_clear_event = libc_r_db_thr_clear_event,
|
||||
.to_thr_event_enable = libc_r_db_thr_event_enable,
|
||||
.to_thr_event_getmsg = libc_r_db_thr_event_getmsg,
|
||||
.to_thr_get_info = libc_r_db_thr_get_info,
|
||||
.to_thr_getfpregs = libc_r_db_thr_getfpregs,
|
||||
.to_thr_getgregs = libc_r_db_thr_getgregs,
|
||||
.to_thr_set_event = libc_r_db_thr_set_event,
|
||||
.to_thr_setfpregs = libc_r_db_thr_setfpregs,
|
||||
.to_thr_setgregs = libc_r_db_thr_setgregs,
|
||||
.to_thr_validate = libc_r_db_thr_validate
|
||||
};
|
File diff suppressed because it is too large
Load Diff
@ -26,29 +26,39 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _PTHREAD_DB_H
|
||||
#define _PTHREAD_DB_H
|
||||
#ifndef _LIBPTHREAD_DB_H_
|
||||
#define _LIBPTHREAD_DB_H_
|
||||
|
||||
#include <sys/ucontext.h>
|
||||
#include <machine/reg.h>
|
||||
|
||||
#include "thread_db_int.h"
|
||||
|
||||
struct pt_thragent {
|
||||
struct td_thragent base;
|
||||
struct ps_prochandle *ph;
|
||||
psaddr_t libkse_debug_addr;
|
||||
psaddr_t thread_list_addr;
|
||||
psaddr_t thread_listgen_addr;
|
||||
psaddr_t thread_activated_addr;
|
||||
psaddr_t thread_active_threads_addr;
|
||||
psaddr_t thread_keytable_addr;
|
||||
int thread_activated;
|
||||
struct pt_map *map;
|
||||
int map_len;
|
||||
struct pt_map {
|
||||
enum {
|
||||
PT_NONE,
|
||||
PT_USER,
|
||||
PT_LWP
|
||||
} type;
|
||||
|
||||
union {
|
||||
lwpid_t lwp;
|
||||
psaddr_t thr;
|
||||
};
|
||||
};
|
||||
|
||||
typedef struct pt_thragent pt_thragent_t;
|
||||
struct td_thragent {
|
||||
TD_THRAGENT_FIELDS;
|
||||
psaddr_t libkse_debug_addr;
|
||||
psaddr_t thread_list_addr;
|
||||
psaddr_t thread_listgen_addr;
|
||||
psaddr_t thread_activated_addr;
|
||||
psaddr_t thread_active_threads_addr;
|
||||
psaddr_t thread_keytable_addr;
|
||||
int thread_activated;
|
||||
struct pt_map *map;
|
||||
int map_len;
|
||||
};
|
||||
|
||||
void pt_md_init(void);
|
||||
void pt_reg_to_ucontext(const struct reg *, ucontext_t *);
|
||||
@ -57,4 +67,4 @@ void pt_fpreg_to_ucontext(const struct fpreg *, ucontext_t *);
|
||||
void pt_ucontext_to_fpreg(const ucontext_t *, struct fpreg *);
|
||||
int pt_reg_sstep(struct reg *reg, int step);
|
||||
|
||||
#endif
|
||||
#endif /* _LIBPTHREAD_DB_H_ */
|
311
lib/libthread_db/libthr_db.c
Normal file
311
lib/libthread_db/libthr_db.c
Normal file
@ -0,0 +1,311 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Marcel Moolenaar
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <proc_service.h>
|
||||
#include <stdlib.h>
|
||||
#include <thread_db.h>
|
||||
|
||||
#include "thread_db_int.h"
|
||||
|
||||
struct td_thragent {
|
||||
TD_THRAGENT_FIELDS;
|
||||
struct ps_prochandle *ta_ph;
|
||||
psaddr_t ta_thread_list;
|
||||
int ta_ofs_ctx;
|
||||
int ta_ofs_next;
|
||||
int ta_ofs_thr_id;
|
||||
};
|
||||
|
||||
static td_err_e
|
||||
libthr_db_init()
|
||||
{
|
||||
return (TD_OK);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libthr_db_ta_clear_event(const td_thragent_t *ta, td_thr_events_t *ev)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libthr_db_ta_delete(td_thragent_t *ta)
|
||||
{
|
||||
free(ta);
|
||||
return (TD_OK);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libthr_db_ta_event_addr(const td_thragent_t *ta, td_thr_events_e event,
|
||||
td_notify_t *n)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libthr_db_ta_event_getmsg(const td_thragent_t *ta, td_event_msg_t *msg)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libthr_db_ta_map_id2thr(const td_thragent_t *ta, thread_t tid,
|
||||
td_thrhandle_t *th)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libthr_db_ta_map_lwp2thr(const td_thragent_t *ta, lwpid_t lwpid,
|
||||
td_thrhandle_t *th)
|
||||
{
|
||||
psaddr_t addr;
|
||||
thread_t tid;
|
||||
ps_err_e err;
|
||||
|
||||
th->th_ta = ta;
|
||||
|
||||
err = ps_pread(ta->ta_ph, ta->ta_thread_list, &th->th_thread,
|
||||
sizeof(th->th_thread));
|
||||
if (err != PS_OK)
|
||||
return (TD_ERR);
|
||||
while (th->th_thread != NULL) {
|
||||
addr = (psaddr_t)((uintptr_t)th->th_thread +
|
||||
ta->ta_ofs_thr_id);
|
||||
err = ps_pread(ta->ta_ph, addr, &tid, sizeof(thread_t));
|
||||
if (err != PS_OK)
|
||||
return (TD_ERR);
|
||||
if (tid == lwpid)
|
||||
return (TD_OK);
|
||||
addr = (psaddr_t)((uintptr_t)th->th_thread + ta->ta_ofs_next);
|
||||
err = ps_pread(ta->ta_ph, addr, &th->th_thread,
|
||||
sizeof(th->th_thread));
|
||||
if (err != PS_OK)
|
||||
return (TD_ERR);
|
||||
}
|
||||
return (TD_NOLWP);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libthr_db_ta_new(struct ps_prochandle *ph, td_thragent_t **ta_p)
|
||||
{
|
||||
td_thragent_t *ta;
|
||||
psaddr_t addr;
|
||||
ps_err_e err;
|
||||
|
||||
err = ps_pglobal_lookup(ph, NULL, "_libthr_debug", &addr);
|
||||
if (err != PS_OK)
|
||||
return (TD_NOLIBTHREAD);
|
||||
|
||||
ta = malloc(sizeof(td_thragent_t));
|
||||
if (ta == NULL)
|
||||
return (TD_MALLOC);
|
||||
|
||||
ta->ta_ph = ph;
|
||||
|
||||
err = ps_pglobal_lookup(ph, NULL, "_thread_list", &ta->ta_thread_list);
|
||||
if (err != PS_OK)
|
||||
goto fail;
|
||||
err = ps_pglobal_lookup(ph, NULL, "_thread_ctx_offset", &addr);
|
||||
if (err != PS_OK)
|
||||
goto fail;
|
||||
err = ps_pread(ph, addr, &ta->ta_ofs_ctx, sizeof(int));
|
||||
if (err != PS_OK)
|
||||
goto fail;
|
||||
err = ps_pglobal_lookup(ph, NULL, "_thread_next_offset", &addr);
|
||||
if (err != PS_OK)
|
||||
goto fail;
|
||||
err = ps_pread(ph, addr, &ta->ta_ofs_next, sizeof(int));
|
||||
if (err != PS_OK)
|
||||
goto fail;
|
||||
err = ps_pglobal_lookup(ph, NULL, "_thread_thr_id_offset", &addr);
|
||||
if (err != PS_OK)
|
||||
goto fail;
|
||||
err = ps_pread(ph, addr, &ta->ta_ofs_thr_id, sizeof(int));
|
||||
if (err != PS_OK)
|
||||
goto fail;
|
||||
|
||||
*ta_p = ta;
|
||||
return (TD_OK);
|
||||
|
||||
fail:
|
||||
free(ta);
|
||||
*ta_p = NULL;
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libthr_db_ta_set_event(const td_thragent_t *ta, td_thr_events_t *ev)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libthr_db_ta_thr_iter(const td_thragent_t *ta, td_thr_iter_f *cb, void *data,
|
||||
td_thr_state_e state, int pri, sigset_t *mask, unsigned int flags)
|
||||
{
|
||||
td_thrhandle_t th;
|
||||
psaddr_t addr;
|
||||
ps_err_e err;
|
||||
|
||||
th.th_ta = ta;
|
||||
|
||||
err = ps_pread(ta->ta_ph, ta->ta_thread_list, &th.th_thread,
|
||||
sizeof(th.th_thread));
|
||||
if (err != PS_OK)
|
||||
return (TD_ERR);
|
||||
while (th.th_thread != NULL) {
|
||||
if (cb(&th, data) != 0)
|
||||
return (TD_OK);
|
||||
addr = (psaddr_t)((uintptr_t)th.th_thread + ta->ta_ofs_next);
|
||||
err = ps_pread(ta->ta_ph, addr, &th.th_thread,
|
||||
sizeof(th.th_thread));
|
||||
if (err != PS_OK)
|
||||
return (TD_ERR);
|
||||
}
|
||||
return (TD_OK);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libthr_db_thr_clear_event(const td_thrhandle_t *th, td_thr_events_t *ev)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libthr_db_thr_event_enable(const td_thrhandle_t *th, int oo)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libthr_db_thr_event_getmsg(const td_thrhandle_t *th, td_event_msg_t *msg)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libthr_db_thr_get_info(const td_thrhandle_t *th, td_thrinfo_t *ti)
|
||||
{
|
||||
const td_thragent_t *ta;
|
||||
psaddr_t addr;
|
||||
thread_t tid;
|
||||
ps_err_e err;
|
||||
|
||||
ta = th->th_ta;
|
||||
ti->ti_ta_p = ta;
|
||||
addr = (psaddr_t)((uintptr_t)th->th_thread + ta->ta_ofs_thr_id);
|
||||
err = ps_pread(ta->ta_ph, addr, &tid, sizeof(thread_t));
|
||||
ti->ti_lid = tid;
|
||||
ti->ti_tid = tid;
|
||||
return ((err == PS_OK) ? TD_OK : TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libthr_db_thr_getfpregs(const td_thrhandle_t *th, prfpregset_t *r)
|
||||
{
|
||||
const td_thragent_t *ta;
|
||||
psaddr_t addr;
|
||||
thread_t tid;
|
||||
ps_err_e err;
|
||||
|
||||
ta = th->th_ta;
|
||||
addr = (psaddr_t)((uintptr_t)th->th_thread + ta->ta_ofs_thr_id);
|
||||
err = ps_pread(ta->ta_ph, addr, &tid, sizeof(thread_t));
|
||||
if (err != PS_OK)
|
||||
return (TD_ERR);
|
||||
err = ps_lgetfpregs(ta->ta_ph, tid, r);
|
||||
return ((err == PS_OK) ? TD_OK : TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libthr_db_thr_getgregs(const td_thrhandle_t *th, prgregset_t r)
|
||||
{
|
||||
const td_thragent_t *ta;
|
||||
psaddr_t addr;
|
||||
thread_t tid;
|
||||
ps_err_e err;
|
||||
|
||||
ta = th->th_ta;
|
||||
addr = (psaddr_t)((uintptr_t)th->th_thread + ta->ta_ofs_thr_id);
|
||||
err = ps_pread(ta->ta_ph, addr, &tid, sizeof(thread_t));
|
||||
if (err != PS_OK)
|
||||
return (TD_ERR);
|
||||
err = ps_lgetregs(ta->ta_ph, tid, r);
|
||||
return ((err == PS_OK) ? TD_OK : TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libthr_db_thr_set_event(const td_thrhandle_t *th, td_thr_events_t *ev)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libthr_db_thr_setfpregs(const td_thrhandle_t *th, const prfpregset_t *r)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libthr_db_thr_setgregs(const td_thrhandle_t *th, const prgregset_t r)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
static td_err_e
|
||||
libthr_db_thr_validate(const td_thrhandle_t *th)
|
||||
{
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
struct ta_ops libthr_db_ops = {
|
||||
.to_init = libthr_db_init,
|
||||
|
||||
.to_ta_clear_event = libthr_db_ta_clear_event,
|
||||
.to_ta_delete = libthr_db_ta_delete,
|
||||
.to_ta_event_addr = libthr_db_ta_event_addr,
|
||||
.to_ta_event_getmsg = libthr_db_ta_event_getmsg,
|
||||
.to_ta_map_id2thr = libthr_db_ta_map_id2thr,
|
||||
.to_ta_map_lwp2thr = libthr_db_ta_map_lwp2thr,
|
||||
.to_ta_new = libthr_db_ta_new,
|
||||
.to_ta_set_event = libthr_db_ta_set_event,
|
||||
.to_ta_thr_iter = libthr_db_ta_thr_iter,
|
||||
|
||||
.to_thr_clear_event = libthr_db_thr_clear_event,
|
||||
.to_thr_event_enable = libthr_db_thr_event_enable,
|
||||
.to_thr_event_getmsg = libthr_db_thr_event_getmsg,
|
||||
.to_thr_get_info = libthr_db_thr_get_info,
|
||||
.to_thr_getfpregs = libthr_db_thr_getfpregs,
|
||||
.to_thr_getgregs = libthr_db_thr_getgregs,
|
||||
.to_thr_set_event = libthr_db_thr_set_event,
|
||||
.to_thr_setfpregs = libthr_db_thr_setfpregs,
|
||||
.to_thr_setgregs = libthr_db_thr_setgregs,
|
||||
.to_thr_validate = libthr_db_thr_validate
|
||||
};
|
@ -1,19 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
LIB=pthread_db
|
||||
INTERNALLIB=yes
|
||||
NOPROFILE=yes
|
||||
NOPIC=yes
|
||||
CFLAGS+=-DPTHREAD_KERNEL -fpic -DPIC
|
||||
CFLAGS+=-I${.CURDIR}/../include \
|
||||
-I${.CURDIR}/../../libc/include -I${.CURDIR}/../../libpthread/thread \
|
||||
-I${.CURDIR}/../../../include
|
||||
CFLAGS+=-I${.CURDIR}/../../libpthread/arch/${MACHINE_ARCH}/include
|
||||
CFLAGS+=-I${.CURDIR}/../../libpthread/sys
|
||||
CFLAGS+=-Wall
|
||||
|
||||
.PATH: ${.CURDIR}
|
||||
|
||||
SRCS+=pthread_db.c pthread_db_${MACHINE_ARCH}.c
|
||||
|
||||
.include <bsd.lib.mk>
|
@ -1,15 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SHLIB_NAME=libthread_db.so.1
|
||||
NOPROFILE=yes
|
||||
CFLAGS+=-Wall -I${.CURDIR}/../../../include -I${.CURDIR}/../include
|
||||
LDADD=../pthread/libpthread_db.a
|
||||
|
||||
PRECIOUSLIB=yes
|
||||
|
||||
.PATH: ${.CURDIR}
|
||||
|
||||
SRCS+=thread_db.c
|
||||
INCS=../include/thread_db.h
|
||||
|
||||
.include <bsd.lib.mk>
|
@ -1,359 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 David Xu <davidxu@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <proc_service.h>
|
||||
#include <thread_db.h>
|
||||
#include "thread_db_int.h"
|
||||
|
||||
static TAILQ_HEAD(, td_thragent) proclist = TAILQ_HEAD_INITIALIZER(proclist);
|
||||
|
||||
extern struct ta_ops pthread_ops;
|
||||
#if 0
|
||||
extern struct ta_ops thr_ops;
|
||||
extern struct ta_ops c_r_ops;
|
||||
#endif
|
||||
|
||||
static struct ta_ops *ops[] = {
|
||||
&pthread_ops,
|
||||
#if 0
|
||||
&thr_ops,
|
||||
&c_r_ops
|
||||
#endif
|
||||
};
|
||||
|
||||
td_err_e
|
||||
td_init(void)
|
||||
{
|
||||
int i, ret = 0;
|
||||
|
||||
for (i = 0; i < sizeof(ops)/sizeof(ops[0]); ++i) {
|
||||
int tmp;
|
||||
if ((tmp = ops[i]->to_init()) != 0)
|
||||
ret = tmp;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_new(struct ps_prochandle *ph, td_thragent_t **pta)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(ops)/sizeof(ops[0]); ++i) {
|
||||
if (ops[i]->to_ta_new(ph, pta) == 0) {
|
||||
(*pta)->ta_ops = ops[i];
|
||||
TAILQ_INSERT_HEAD(&proclist, *pta, ta_next);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
return (TD_NOLIBTHREAD);
|
||||
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_delete(td_thragent_t *ta)
|
||||
{
|
||||
TAILQ_REMOVE(&proclist, ta, ta_next);
|
||||
return ta->ta_ops->to_ta_delete(ta);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_get_nthreads(const td_thragent_t *ta, int *np)
|
||||
{
|
||||
return ta->ta_ops->to_ta_get_nthreads(ta, np);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_get_ph(const td_thragent_t *ta, struct ps_prochandle **ph)
|
||||
{
|
||||
return ta->ta_ops->to_ta_get_ph(ta, ph);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_map_id2thr(const td_thragent_t *ta, thread_t id, td_thrhandle_t *th)
|
||||
{
|
||||
return ta->ta_ops->to_ta_map_id2thr(ta, id, th);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_map_lwp2thr(const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th)
|
||||
{
|
||||
return ta->ta_ops->to_ta_map_lwp2thr(ta, lwpid, th);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_thr_iter(const td_thragent_t *ta,
|
||||
td_thr_iter_f *callback, void *cbdata_p,
|
||||
td_thr_state_e state, int ti_pri,
|
||||
sigset_t *ti_sigmask_p,
|
||||
unsigned int ti_user_flags)
|
||||
{
|
||||
return ta->ta_ops->to_ta_thr_iter(ta, callback, cbdata_p, state,
|
||||
ti_pri, ti_sigmask_p, ti_user_flags);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_tsd_iter(const td_thragent_t *ta, td_key_iter_f *ki, void *arg)
|
||||
{
|
||||
return ta->ta_ops->to_ta_tsd_iter(ta, ki, arg);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_event_addr(const td_thragent_t *ta, td_event_e event, td_notify_t *ptr)
|
||||
{
|
||||
return ta->ta_ops->to_ta_event_addr(ta, event, ptr);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_set_event(const td_thragent_t *ta, td_thr_events_t *events)
|
||||
{
|
||||
return ta->ta_ops->to_ta_set_event(ta, events);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_clear_event(const td_thragent_t *ta, td_thr_events_t *events)
|
||||
{
|
||||
return ta->ta_ops->to_ta_clear_event(ta, events);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_event_getmsg(const td_thragent_t *ta, td_event_msg_t *msg)
|
||||
{
|
||||
return ta->ta_ops->to_ta_event_getmsg(ta, msg);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_setconcurrency(const td_thragent_t *ta, int level)
|
||||
{
|
||||
return ta->ta_ops->to_ta_setconcurrency(ta, level);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_enable_stats(const td_thragent_t *ta, int enable)
|
||||
{
|
||||
return ta->ta_ops->to_ta_enable_stats(ta, enable);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_reset_stats(const td_thragent_t *ta)
|
||||
{
|
||||
return ta->ta_ops->to_ta_reset_stats(ta);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_get_stats(const td_thragent_t *ta, td_ta_stats_t *statsp)
|
||||
{
|
||||
return ta->ta_ops->to_ta_get_stats(ta, statsp);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_validate(const td_thrhandle_t *th)
|
||||
{
|
||||
td_thragent_t *ta = th->th_ta_p;
|
||||
|
||||
return ta->ta_ops->to_thr_validate(th);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_get_info(const td_thrhandle_t *th, td_thrinfo_t *info)
|
||||
{
|
||||
td_thragent_t *ta = th->th_ta_p;
|
||||
|
||||
return ta->ta_ops->to_thr_get_info(th, info);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_getfpregs(const td_thrhandle_t *th, prfpregset_t *fpregset)
|
||||
{
|
||||
td_thragent_t *ta = th->th_ta_p;
|
||||
|
||||
return ta->ta_ops->to_thr_getfpregs(th, fpregset);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_getgregs(const td_thrhandle_t *th, prgregset_t gregs)
|
||||
{
|
||||
td_thragent_t *ta = th->th_ta_p;
|
||||
|
||||
return ta->ta_ops->to_thr_getgregs(th, gregs);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_getxregs(const td_thrhandle_t *th, void *xregs)
|
||||
{
|
||||
td_thragent_t *ta = th->th_ta_p;
|
||||
|
||||
return ta->ta_ops->to_thr_getxregs(th, xregs);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_getxregsize(const td_thrhandle_t *th, int *sizep)
|
||||
{
|
||||
td_thragent_t *ta = th->th_ta_p;
|
||||
|
||||
return ta->ta_ops->to_thr_getxregsize(th, sizep);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_setfpregs(const td_thrhandle_t *th, const prfpregset_t *fpregs)
|
||||
{
|
||||
td_thragent_t *ta = th->th_ta_p;
|
||||
|
||||
return ta->ta_ops->to_thr_setfpregs(th, fpregs);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_setgregs(const td_thrhandle_t *th, const prgregset_t gregs)
|
||||
{
|
||||
td_thragent_t *ta = th->th_ta_p;
|
||||
|
||||
return ta->ta_ops->to_thr_setgregs(th, gregs);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_setxregs(const td_thrhandle_t *th, const void *addr)
|
||||
{
|
||||
td_thragent_t *ta = th->th_ta_p;
|
||||
|
||||
return ta->ta_ops->to_thr_setxregs(th, addr);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_event_enable(const td_thrhandle_t *th, int en)
|
||||
{
|
||||
td_thragent_t *ta = th->th_ta_p;
|
||||
|
||||
return ta->ta_ops->to_thr_event_enable(th, en);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_set_event(const td_thrhandle_t *th, td_thr_events_t *setp)
|
||||
{
|
||||
td_thragent_t *ta = th->th_ta_p;
|
||||
|
||||
return ta->ta_ops->to_thr_set_event(th, setp);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_clear_event(const td_thrhandle_t *th, td_thr_events_t *setp)
|
||||
{
|
||||
td_thragent_t *ta = th->th_ta_p;
|
||||
|
||||
return ta->ta_ops->to_thr_clear_event(th, setp);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_event_getmsg(const td_thrhandle_t *th, td_event_msg_t *msg)
|
||||
{
|
||||
td_thragent_t *ta = th->th_ta_p;
|
||||
|
||||
return ta->ta_ops->to_thr_event_getmsg(th, msg);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_setprio(const td_thrhandle_t *th, int pri)
|
||||
{
|
||||
td_thragent_t *ta = th->th_ta_p;
|
||||
|
||||
return ta->ta_ops->to_thr_setprio(th, pri);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_setsigpending(const td_thrhandle_t *th, unsigned char n,
|
||||
const sigset_t *set)
|
||||
{
|
||||
td_thragent_t *ta = th->th_ta_p;
|
||||
|
||||
return ta->ta_ops->to_thr_setsigpending(th, n, set);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_sigsetmask(const td_thrhandle_t *th, const sigset_t *set)
|
||||
{
|
||||
td_thragent_t *ta = th->th_ta_p;
|
||||
|
||||
return ta->ta_ops->to_thr_sigsetmask(th, set);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_tsd(const td_thrhandle_t *th, const thread_key_t key, void **data)
|
||||
{
|
||||
td_thragent_t *ta = th->th_ta_p;
|
||||
|
||||
return ta->ta_ops->to_thr_tsd(th, key, data);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_dbsuspend(const td_thrhandle_t *th)
|
||||
{
|
||||
td_thragent_t *ta = th->th_ta_p;
|
||||
|
||||
return ta->ta_ops->to_thr_dbsuspend(th);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_dbresume(const td_thrhandle_t *th)
|
||||
{
|
||||
td_thragent_t *ta = th->th_ta_p;
|
||||
|
||||
return ta->ta_ops->to_thr_dbresume(th);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_get_ta(int pid, td_thragent_t **ta_p)
|
||||
{
|
||||
td_thragent_t *ta;
|
||||
struct ps_prochandle *ph;
|
||||
|
||||
TAILQ_FOREACH(ta, &proclist, ta_next) {
|
||||
td_ta_get_ph(ta, &ph);
|
||||
if (ps_getpid(ph) == pid) {
|
||||
*ta_p = ta;
|
||||
return (TD_OK);
|
||||
}
|
||||
}
|
||||
return (TD_ERR);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_activated(td_thragent_t *ta, int *a)
|
||||
{
|
||||
return ta->ta_ops->to_ta_activated(ta, a);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_sstep(td_thrhandle_t *th, int step)
|
||||
{
|
||||
td_thragent_t *ta = th->th_ta_p;
|
||||
|
||||
return ta->ta_ops->to_thr_sstep(th, step);
|
||||
}
|
236
lib/libthread_db/thread_db.c
Normal file
236
lib/libthread_db/thread_db.c
Normal file
@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Copyright (c) 2004 David Xu <davidxu@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <proc_service.h>
|
||||
#include <stddef.h>
|
||||
#include <thread_db.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "thread_db_int.h"
|
||||
|
||||
struct td_thragent
|
||||
{
|
||||
TD_THRAGENT_FIELDS;
|
||||
};
|
||||
|
||||
static TAILQ_HEAD(, td_thragent) proclist = TAILQ_HEAD_INITIALIZER(proclist);
|
||||
|
||||
extern struct ta_ops libc_r_db_ops;
|
||||
extern struct ta_ops libpthread_db_ops;
|
||||
extern struct ta_ops libthr_db_ops;
|
||||
|
||||
static struct ta_ops *ops[] = {
|
||||
&libpthread_db_ops,
|
||||
&libthr_db_ops,
|
||||
&libc_r_db_ops
|
||||
};
|
||||
|
||||
td_err_e
|
||||
td_init(void)
|
||||
{
|
||||
td_err_e ret, tmp;
|
||||
size_t i;
|
||||
|
||||
ret = 0;
|
||||
for (i = 0; i < sizeof(ops)/sizeof(ops[0]); i++) {
|
||||
if (ops[i]->to_init != NULL) {
|
||||
tmp = ops[i]->to_init();
|
||||
if (tmp != TD_OK)
|
||||
ret = tmp;
|
||||
}
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_clear_event(const td_thragent_t *ta, td_thr_events_t *events)
|
||||
{
|
||||
return (ta->ta_ops->to_ta_clear_event(ta, events));
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_delete(td_thragent_t *ta)
|
||||
{
|
||||
TAILQ_REMOVE(&proclist, ta, ta_next);
|
||||
return (ta->ta_ops->to_ta_delete(ta));
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_event_addr(const td_thragent_t *ta, td_event_e event, td_notify_t *ptr)
|
||||
{
|
||||
return (ta->ta_ops->to_ta_event_addr(ta, event, ptr));
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_event_getmsg(const td_thragent_t *ta, td_event_msg_t *msg)
|
||||
{
|
||||
return (ta->ta_ops->to_ta_event_getmsg(ta, msg));
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_map_id2thr(const td_thragent_t *ta, thread_t id, td_thrhandle_t *th)
|
||||
{
|
||||
return (ta->ta_ops->to_ta_map_id2thr(ta, id, th));
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_map_lwp2thr(const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th)
|
||||
{
|
||||
return (ta->ta_ops->to_ta_map_lwp2thr(ta, lwpid, th));
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_new(struct ps_prochandle *ph, td_thragent_t **pta)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sizeof(ops)/sizeof(ops[0]); ++i) {
|
||||
if (ops[i]->to_ta_new(ph, pta) == TD_OK) {
|
||||
TAILQ_INSERT_HEAD(&proclist, *pta, ta_next);
|
||||
(*pta)->ta_ops = ops[i];
|
||||
return (TD_OK);
|
||||
}
|
||||
}
|
||||
return (TD_NOLIBTHREAD);
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_set_event(const td_thragent_t *ta, td_thr_events_t *events)
|
||||
{
|
||||
return (ta->ta_ops->to_ta_set_event(ta, events));
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_thr_iter(const td_thragent_t *ta, td_thr_iter_f *callback,
|
||||
void *cbdata_p, td_thr_state_e state, int ti_pri, sigset_t *ti_sigmask_p,
|
||||
unsigned int ti_user_flags)
|
||||
{
|
||||
return (ta->ta_ops->to_ta_thr_iter(ta, callback, cbdata_p, state,
|
||||
ti_pri, ti_sigmask_p, ti_user_flags));
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_ta_tsd_iter(const td_thragent_t *ta, td_key_iter_f *callback,
|
||||
void *cbdata_p)
|
||||
{
|
||||
return (ta->ta_ops->to_ta_tsd_iter(ta, callback, cbdata_p));
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_clear_event(const td_thrhandle_t *th, td_thr_events_t *events)
|
||||
{
|
||||
const td_thragent_t *ta = th->th_ta;
|
||||
return (ta->ta_ops->to_thr_clear_event(th, events));
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_dbresume(const td_thrhandle_t *th)
|
||||
{
|
||||
const td_thragent_t *ta = th->th_ta;
|
||||
return (ta->ta_ops->to_thr_dbresume(th));
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_dbsuspend(const td_thrhandle_t *th)
|
||||
{
|
||||
const td_thragent_t *ta = th->th_ta;
|
||||
return (ta->ta_ops->to_thr_dbsuspend(th));
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_event_enable(const td_thrhandle_t *th, int en)
|
||||
{
|
||||
const td_thragent_t *ta = th->th_ta;
|
||||
return (ta->ta_ops->to_thr_event_enable(th, en));
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_event_getmsg(const td_thrhandle_t *th, td_event_msg_t *msg)
|
||||
{
|
||||
const td_thragent_t *ta = th->th_ta;
|
||||
return (ta->ta_ops->to_thr_event_getmsg(th, msg));
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_get_info(const td_thrhandle_t *th, td_thrinfo_t *info)
|
||||
{
|
||||
const td_thragent_t *ta = th->th_ta;
|
||||
return (ta->ta_ops->to_thr_get_info(th, info));
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_getfpregs(const td_thrhandle_t *th, prfpregset_t *fpregset)
|
||||
{
|
||||
const td_thragent_t *ta = th->th_ta;
|
||||
return (ta->ta_ops->to_thr_getfpregs(th, fpregset));
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_getgregs(const td_thrhandle_t *th, prgregset_t gregs)
|
||||
{
|
||||
const td_thragent_t *ta = th->th_ta;
|
||||
return (ta->ta_ops->to_thr_getgregs(th, gregs));
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_set_event(const td_thrhandle_t *th, td_thr_events_t *events)
|
||||
{
|
||||
const td_thragent_t *ta = th->th_ta;
|
||||
return (ta->ta_ops->to_thr_set_event(th, events));
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_setfpregs(const td_thrhandle_t *th, const prfpregset_t *fpregs)
|
||||
{
|
||||
const td_thragent_t *ta = th->th_ta;
|
||||
return (ta->ta_ops->to_thr_setfpregs(th, fpregs));
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_setgregs(const td_thrhandle_t *th, const prgregset_t gregs)
|
||||
{
|
||||
const td_thragent_t *ta = th->th_ta;
|
||||
return (ta->ta_ops->to_thr_setgregs(th, gregs));
|
||||
}
|
||||
|
||||
td_err_e
|
||||
td_thr_validate(const td_thrhandle_t *th)
|
||||
{
|
||||
const td_thragent_t *ta = th->th_ta;
|
||||
return (ta->ta_ops->to_thr_validate(th));
|
||||
}
|
||||
|
||||
/* FreeBSD specific extensions. */
|
||||
|
||||
td_err_e
|
||||
td_thr_sstep(const td_thrhandle_t *th, int step)
|
||||
{
|
||||
const td_thragent_t *ta = th->th_ta;
|
||||
return (ta->ta_ops->to_thr_sstep(th, step));
|
||||
}
|
230
lib/libthread_db/thread_db.h
Normal file
230
lib/libthread_db/thread_db.h
Normal file
@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Marcel Moolenaar
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _THREAD_DB_H_
|
||||
#define _THREAD_DB_H_
|
||||
|
||||
#include <sys/procfs.h>
|
||||
#include <pthread.h>
|
||||
|
||||
typedef enum {
|
||||
TD_ERR = -1, /* Unspecified error. */
|
||||
TD_OK = 0, /* No error. */
|
||||
TD_BADKEY,
|
||||
TD_BADPH,
|
||||
TD_BADSH,
|
||||
TD_BADTA,
|
||||
TD_BADTH,
|
||||
TD_DBERR,
|
||||
TD_MALLOC,
|
||||
TD_NOAPLIC,
|
||||
TD_NOCAPAB,
|
||||
TD_NOEVENT,
|
||||
TD_NOFPREGS,
|
||||
TD_NOLIBTHREAD,
|
||||
TD_NOLWP,
|
||||
TD_NOMSG,
|
||||
TD_NOSV,
|
||||
TD_NOTHR,
|
||||
TD_NOTSD,
|
||||
TD_NOXREGS,
|
||||
TD_PARTIALREG
|
||||
} td_err_e;
|
||||
|
||||
typedef struct td_thragent td_thragent_t;
|
||||
typedef long thread_t; /* Must be an integral type. */
|
||||
|
||||
typedef struct {
|
||||
const td_thragent_t *th_ta;
|
||||
psaddr_t th_thread;
|
||||
thread_t th_tid;
|
||||
} td_thrhandle_t; /* Used non-opaguely. */
|
||||
|
||||
/*
|
||||
* Events.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
TD_EVENT_NONE = 0,
|
||||
TD_CREATE = 0x0001,
|
||||
TD_DEATH = 0x0002,
|
||||
TD_ALL_EVENTS = ~0
|
||||
} td_thr_events_e;
|
||||
|
||||
/* Compatibility with Linux. */
|
||||
#define td_event_e td_thr_events_e
|
||||
|
||||
typedef struct {
|
||||
td_thr_events_e event;
|
||||
const td_thrhandle_t *th_p;
|
||||
uintptr_t data;
|
||||
} td_event_msg_t;
|
||||
|
||||
typedef unsigned int td_thr_events_t;
|
||||
|
||||
/* XXX can't be it... */
|
||||
typedef struct {
|
||||
union {
|
||||
psaddr_t bptaddr;
|
||||
} u;
|
||||
} td_notify_t;
|
||||
|
||||
static __inline void
|
||||
td_event_addset(td_thr_events_t *es, td_thr_events_e e)
|
||||
{
|
||||
*es |= e;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
td_event_delset(td_thr_events_t *es, td_thr_events_e e)
|
||||
{
|
||||
*es &= ~e;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
td_event_emptyset(td_thr_events_t *es)
|
||||
{
|
||||
*es = TD_EVENT_NONE;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
td_event_fillset(td_thr_events_t *es)
|
||||
{
|
||||
*es = TD_ALL_EVENTS;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
td_eventisempty(td_thr_events_t *es)
|
||||
{
|
||||
return ((*es == TD_EVENT_NONE) ? 1 : 0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
td_eventismember(td_thr_events_t *es, td_thr_events_e e)
|
||||
{
|
||||
return ((*es & e) ? 1 : 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Thread info.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
TD_THR_UNKNOWN = -1,
|
||||
TD_THR_ANY_STATE = 0,
|
||||
TD_THR_ACTIVE,
|
||||
TD_THR_RUN,
|
||||
TD_THR_SLEEP,
|
||||
TD_THR_STOPPED,
|
||||
TD_THR_STOPPED_ASLEEP,
|
||||
TD_THR_ZOMBIE
|
||||
} td_thr_state_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TD_THR_SYSTEM = 1,
|
||||
TD_THR_USER
|
||||
} td_thr_type_e;
|
||||
|
||||
typedef int thread_key_t;
|
||||
|
||||
#if 0
|
||||
typedef struct td_thrinfo_t {
|
||||
unsigned int ti_user_flags;
|
||||
psaddr_t ti_pc;
|
||||
psaddr_t ti_sp;
|
||||
short ti_flags;
|
||||
uchar_t ti_preemptflag;
|
||||
uchar_t ti_pirecflag;
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
const td_thragent_t *ti_ta_p;
|
||||
thread_t ti_tid;
|
||||
td_thr_state_e ti_state;
|
||||
td_thr_type_e ti_type;
|
||||
td_thr_events_t ti_events;
|
||||
int ti_pri;
|
||||
lwpid_t ti_lid;
|
||||
char ti_db_suspended;
|
||||
char ti_traceme;
|
||||
sigset_t ti_sigmask;
|
||||
sigset_t ti_pending;
|
||||
psaddr_t ti_tls;
|
||||
psaddr_t ti_startfunc;
|
||||
psaddr_t ti_stkbase;
|
||||
size_t ti_stksize;
|
||||
} td_thrinfo_t;
|
||||
|
||||
/*
|
||||
* Prototypes.
|
||||
*/
|
||||
|
||||
typedef int td_key_iter_f(thread_key_t, void (*)(void *), void *);
|
||||
typedef int td_thr_iter_f(const td_thrhandle_t *, void *);
|
||||
|
||||
/* Flags for `td_ta_thr_iter'. */
|
||||
#define TD_THR_ANY_USER_FLAGS 0xffffffff
|
||||
#define TD_THR_LOWEST_PRIORITY -20
|
||||
#define TD_SIGNO_MASK NULL
|
||||
|
||||
__BEGIN_DECLS
|
||||
td_err_e td_init(void);
|
||||
|
||||
td_err_e td_ta_clear_event(const td_thragent_t *, td_thr_events_t *);
|
||||
td_err_e td_ta_delete(td_thragent_t *);
|
||||
td_err_e td_ta_event_addr(const td_thragent_t *, td_thr_events_e,
|
||||
td_notify_t *);
|
||||
td_err_e td_ta_event_getmsg(const td_thragent_t *, td_event_msg_t *);
|
||||
td_err_e td_ta_map_id2thr(const td_thragent_t *, thread_t, td_thrhandle_t *);
|
||||
td_err_e td_ta_map_lwp2thr(const td_thragent_t *, lwpid_t, td_thrhandle_t *);
|
||||
td_err_e td_ta_new(struct ps_prochandle *, td_thragent_t **);
|
||||
td_err_e td_ta_set_event(const td_thragent_t *, td_thr_events_t *);
|
||||
td_err_e td_ta_thr_iter(const td_thragent_t *, td_thr_iter_f *, void *,
|
||||
td_thr_state_e, int, sigset_t *, unsigned int);
|
||||
td_err_e td_ta_tsd_iter(const td_thragent_t *, td_key_iter_f *, void *);
|
||||
|
||||
td_err_e td_thr_clear_event(const td_thrhandle_t *, td_thr_events_t *);
|
||||
td_err_e td_thr_dbresume(const td_thrhandle_t *);
|
||||
td_err_e td_thr_dbsuspend(const td_thrhandle_t *);
|
||||
td_err_e td_thr_event_enable(const td_thrhandle_t *, int);
|
||||
td_err_e td_thr_event_getmsg(const td_thrhandle_t *, td_event_msg_t *);
|
||||
td_err_e td_thr_get_info(const td_thrhandle_t *, td_thrinfo_t *);
|
||||
td_err_e td_thr_getfpregs(const td_thrhandle_t *, prfpregset_t *);
|
||||
td_err_e td_thr_getgregs(const td_thrhandle_t *, prgregset_t);
|
||||
td_err_e td_thr_set_event(const td_thrhandle_t *, td_thr_events_t *);
|
||||
td_err_e td_thr_setfpregs(const td_thrhandle_t *, const prfpregset_t *);
|
||||
td_err_e td_thr_setgregs(const td_thrhandle_t *, const prgregset_t);
|
||||
td_err_e td_thr_validate(const td_thrhandle_t *);
|
||||
|
||||
/* FreeBSD specific extensions. */
|
||||
td_err_e td_thr_sstep(const td_thrhandle_t *, int);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _THREAD_DB_H_ */
|
@ -26,68 +26,65 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _THREAD_DB_INT_H
|
||||
#define _THREAD_DB_INT_H
|
||||
#ifndef _THREAD_DB_INT_H_
|
||||
#define _THREAD_DB_INT_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
struct td_thragent {
|
||||
struct ta_ops *ta_ops;
|
||||
TAILQ_ENTRY(td_thragent) ta_next;
|
||||
};
|
||||
#define TD_THRAGENT_FIELDS \
|
||||
struct ta_ops *ta_ops; \
|
||||
TAILQ_ENTRY(td_thragent) ta_next; \
|
||||
struct ps_prochandle *ph
|
||||
|
||||
struct ta_ops {
|
||||
td_err_e (*to_init)(void);
|
||||
td_err_e (*to_ta_new)(struct ps_prochandle *, td_thragent_t **);
|
||||
|
||||
td_err_e (*to_ta_clear_event)(const td_thragent_t *,
|
||||
td_thr_events_t *);
|
||||
td_err_e (*to_ta_delete)(td_thragent_t *);
|
||||
td_err_e (*to_ta_get_nthreads)(const td_thragent_t *, int *);
|
||||
td_err_e (*to_ta_get_ph)(const td_thragent_t *, struct ps_prochandle **);
|
||||
td_err_e (*to_ta_map_id2thr)(const td_thragent_t *, thread_t, td_thrhandle_t *);
|
||||
td_err_e (*to_ta_map_lwp2thr)(const td_thragent_t *, lwpid_t lwpid,
|
||||
td_thrhandle_t *);
|
||||
td_err_e (*to_ta_thr_iter)(const td_thragent_t *, td_thr_iter_f *, void *,
|
||||
td_thr_state_e, int, sigset_t *, unsigned int);
|
||||
td_err_e (*to_ta_tsd_iter)(const td_thragent_t *, td_key_iter_f *, void *);
|
||||
td_err_e (*to_ta_event_addr)(const td_thragent_t *, td_event_e , td_notify_t *);
|
||||
td_err_e (*to_ta_event_addr)(const td_thragent_t *, td_thr_events_e,
|
||||
td_notify_t *);
|
||||
td_err_e (*to_ta_event_getmsg)(const td_thragent_t *,
|
||||
td_event_msg_t *);
|
||||
td_err_e (*to_ta_map_id2thr)(const td_thragent_t *, thread_t,
|
||||
td_thrhandle_t *);
|
||||
td_err_e (*to_ta_map_lwp2thr)(const td_thragent_t *, lwpid_t,
|
||||
td_thrhandle_t *);
|
||||
td_err_e (*to_ta_new)(struct ps_prochandle *, td_thragent_t **);
|
||||
td_err_e (*to_ta_set_event)(const td_thragent_t *, td_thr_events_t *);
|
||||
td_err_e (*to_ta_clear_event)(const td_thragent_t *, td_thr_events_t *);
|
||||
td_err_e (*to_ta_event_getmsg)(const td_thragent_t *, td_event_msg_t *);
|
||||
td_err_e (*to_ta_setconcurrency)(const td_thragent_t *, int);
|
||||
td_err_e (*to_ta_enable_stats)(const td_thragent_t *, int);
|
||||
td_err_e (*to_ta_reset_stats)(const td_thragent_t *);
|
||||
td_err_e (*to_ta_get_stats)(const td_thragent_t *, td_ta_stats_t *);
|
||||
td_err_e (*to_thr_validate)(const td_thrhandle_t *);
|
||||
td_err_e (*to_ta_thr_iter)(const td_thragent_t *, td_thr_iter_f *,
|
||||
void *, td_thr_state_e, int, sigset_t *, unsigned int);
|
||||
td_err_e (*to_ta_tsd_iter)(const td_thragent_t *, td_key_iter_f *,
|
||||
void *);
|
||||
|
||||
td_err_e (*to_thr_clear_event)(const td_thrhandle_t *,
|
||||
td_thr_events_t *);
|
||||
td_err_e (*to_thr_dbresume)(const td_thrhandle_t *);
|
||||
td_err_e (*to_thr_dbsuspend)(const td_thrhandle_t *);
|
||||
td_err_e (*to_thr_event_enable)(const td_thrhandle_t *, int);
|
||||
td_err_e (*to_thr_event_getmsg)(const td_thrhandle_t *,
|
||||
td_event_msg_t *);
|
||||
td_err_e (*to_thr_get_info)(const td_thrhandle_t *, td_thrinfo_t *);
|
||||
td_err_e (*to_thr_getfpregs)(const td_thrhandle_t *, prfpregset_t *);
|
||||
td_err_e (*to_thr_getgregs)(const td_thrhandle_t *, prgregset_t);
|
||||
td_err_e (*to_thr_getxregs)(const td_thrhandle_t *, void *);
|
||||
td_err_e (*to_thr_getxregsize)(const td_thrhandle_t *, int *);
|
||||
td_err_e (*to_thr_setfpregs)(const td_thrhandle_t *, const prfpregset_t *);
|
||||
td_err_e (*to_thr_set_event)(const td_thrhandle_t *,
|
||||
td_thr_events_t *);
|
||||
td_err_e (*to_thr_setfpregs)(const td_thrhandle_t *,
|
||||
const prfpregset_t *);
|
||||
td_err_e (*to_thr_setgregs)(const td_thrhandle_t *, const prgregset_t);
|
||||
td_err_e (*to_thr_setxregs)(const td_thrhandle_t *, const void *);
|
||||
td_err_e (*to_thr_event_enable)(const td_thrhandle_t *, int);
|
||||
td_err_e (*to_thr_set_event)(const td_thrhandle_t *, td_thr_events_t *);
|
||||
td_err_e (*to_thr_clear_event)(const td_thrhandle_t *, td_thr_events_t *);
|
||||
td_err_e (*to_thr_event_getmsg)(const td_thrhandle_t *, td_event_msg_t *);
|
||||
td_err_e (*to_thr_setprio)(const td_thrhandle_t *, int);
|
||||
td_err_e (*to_thr_setsigpending)(const td_thrhandle_t *, unsigned char,
|
||||
const sigset_t *);
|
||||
td_err_e (*to_thr_sigsetmask)(const td_thrhandle_t *, const sigset_t *);
|
||||
td_err_e (*to_thr_tsd)(const td_thrhandle_t *, const thread_key_t, void **);
|
||||
td_err_e (*to_thr_dbsuspend)(const td_thrhandle_t *);
|
||||
td_err_e (*to_thr_dbresume)(const td_thrhandle_t *);
|
||||
td_err_e (*to_get_ta)(int pid, td_thragent_t **);
|
||||
td_err_e (*to_ta_activated)(td_thragent_t *, int *);
|
||||
td_err_e (*to_thr_sstep)(td_thrhandle_t *, int step);
|
||||
td_err_e (*to_thr_validate)(const td_thrhandle_t *);
|
||||
|
||||
/* FreeBSD specific extensions. */
|
||||
td_err_e (*to_thr_sstep)(const td_thrhandle_t *, int);
|
||||
};
|
||||
|
||||
#ifdef TD_DEBUG
|
||||
#define TDBG(...) ps_plog(__VA_ARGS__)
|
||||
#define TDBG_FUNC() ps_plog(__func__); ps_plog("\n")
|
||||
#define TDBG_FUNC() ps_plog("%s\n", __func__)
|
||||
#else
|
||||
#define TDBG(...)
|
||||
#define TDBG_FUNC()
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* _THREAD_DB_INT_H_ */
|
Loading…
Reference in New Issue
Block a user