diff options
author | rsc <devnull@localhost> | 2005-01-23 22:33:04 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2005-01-23 22:33:04 +0000 |
commit | dd944ec72a26d0b380ba2af5f6c00310f2f1651e (patch) | |
tree | 2f40332ca2fcf189d347cf4f577cf613af21108f /src/libmach/pthread.c | |
parent | a0e8d02d093e01fdadf8a16bc86fe18b0c4e82c3 (diff) | |
download | plan9port-dd944ec72a26d0b380ba2af5f6c00310f2f1651e.tar.gz plan9port-dd944ec72a26d0b380ba2af5f6c00310f2f1651e.tar.bz2 plan9port-dd944ec72a26d0b380ba2af5f6c00310f2f1651e.zip |
Start working through proper handling of pthreads when
debugging Linux core dumps. Pthreads for active processes
is still not supported, nor are other systems.
Diffstat (limited to 'src/libmach/pthread.c')
-rw-r--r-- | src/libmach/pthread.c | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/src/libmach/pthread.c b/src/libmach/pthread.c index 46eca4f2..8a2b60a9 100644 --- a/src/libmach/pthread.c +++ b/src/libmach/pthread.c @@ -6,6 +6,103 @@ #include <libc.h> #include <mach.h> +typedef struct Ptprog Ptprog; +struct Pprog +{ + Pthread *t; + uint nt; +}; + +typedef struct Pthread Pthread; +struct Pthread +{ + td_thrhandle_t handle; +}; + +void +pthreadattach(int pid) +{ + +} + +void pthreadattach() + set up mapping + +Regs *pthreadregs() +int npthread(); + + + +static int td_get_allthreads(td_thragent_t*, td_thrhandle_t**); +static int terr(int); + + +Regs* +threadregs() +{ + +} + + + +typedef struct AllThread AllThread; +struct AllThread +{ + td_thrhandle_t *a; + int n; + int err; +}; + +static int +thritercb(const td_thrhandle_t *th, void *cb) +{ + td_thrhandle_t **p; + AllThread *a; + int n; + + a = cb; + if((a->n&(a->n-1)) == 0){ + if(a->n == 0) + n = 1; + else + n = a->n<<1; + if((p = realloc(a->a, n*sizeof a->a[0])) == 0){ + a->err = -1; + return -1; /* stop iteration */ + } + a->a = p; + } + a->a[a->n++] = *th; + return 0; +} + +int +td_get_allthreads(td_thragent_t *ta, td_thrhandle_t **pall) +{ + int e; + AllThread a; + + a.a = nil; + a.n = 0; + a.err = 0; + if((e = td_ta_thr_iter(ta, thritercb, &a, + TD_THR_ANY_STATE, + TD_THR_LOWEST_PRIORITY, + TD_SIGNO_MASK, + TD_THR_ANY_USER_FLAGS)) != TD_OK){ + werrstr("%s", terr(e)); + return -1; + } + + if(a.err){ + free(a.a); + return -1; + } + + *pall = a.a; + return a.n; +} + static char *tderrstr[] = { [TD_OK] "no error", @@ -47,3 +144,146 @@ terr(int e) return tderrstr[e]; } +/* + * bottom-end functions for libthread_db to call + */ +enum +{ + PS_OK, + PS_ERR, + PS_BADPID, + PS_BADLWPID, + PS_BADADDR, + PS_NOSYM, + PS_NOFPREGS, +}; + +pid_t +ps_getpid(struct ps_prochandle *ph) +{ + return ph->pid; +} + +int +ps_pstop(const struct ps_prochandle *ph) +{ + return PS_ERR; +} + +int +ps_pcontinue(const struct ps_prochandle *ph) +{ + return PS_ERR; +} + +int +ps_lstop(const struct ps_prochandle *ph) +{ + return PS_ERR; +} + +int +ps_lcontinue(const struct ps_prochandle *ph) +{ + return PS_ERR; +} + +/* read/write data or text memory */ +int +ps_pdread(struct ps_prochandle *ph, psaddr_t addr, void *v, size_t sz) +{ + if(get1(ph->map, addr, v, sz) < 0) + return PS_ERR; + return PS_OK; +} + +int +ps_pdwrite(struct ps_prochandle *ph, psaddr_t addr, void *v, size_t sz) +{ + if(put1(ph->map, addr, v, sz) < 0) + return PS_ERR; + return PS_OK; +} + +int +ps_ptread(struct ps_prochandle *ph, psaddr_t addr, void *v, size_t sz) +{ + return ps_pdread(ph, addr, v, sz); +} + +int +ps_ptwrite(struct ps_prochandle *ph, psaddr_t addr, void *v, size_t sz) +{ + return ps_pdwrite(ph, addr, v, sz); +} + +int +ps_lgetregs(struct ps_prochandle *ph, lwpid_t lwp, prgregset_t regs) +{ + int i; + + USED(ph); + if(corhdr == nil) + return sys_ps_lgetregs(ph, lwp, regs); + for(i=0; i<corhdr->nthread; i++){ + if(corhdr->thread[i].id == lwp){ + ureg2prgregset(corhdr->thread[i].ureg, regs); + return PS_OK; + } + } + return PS_ERR; +} + +int +ps_lsetregs(struct ps_prochandle *ph, lwpid_t lwp, prgregset_t regs) +{ + if(corhdr == nil) + return sys_ps_lsetregs(ph, lwp, regs); + return PS_ERR; +} + +int +ps_lgetfpregs(struct ps_prochandle *ph, lwpid_t lwp, prfpregset_t *fpregs) +{ + if(corhdr == nil) + return sys_ps_lgetfpregs(ph, lwp, fpregs); + /* BUG - Look in core dump. */ + return PS_ERR: +} + +int +ps_lsetfpregs(struct ps_prochandle *ph, lwpid_t lwp, prfpregset_t *fpregs) +{ + if(corhdr == nil) + return sys_ps_lsetfpregs(ph, lwp, fpregs); + return PS_ERR; +} + +/* Fetch the special per-thread address associated with the given LWP. + This call is only used on a few platforms (most use a normal register). + The meaning of the `int' parameter is machine-dependent. */ +int +ps_get_thread_area(struct ps_prochandle *ph, lwpid_t lwp, int xxx, psaddr_t *addr) +{ + return sys_ps_get_thread_area(ph, lwp, xxx, addr); +} + +int +ps_pglobal_lookup(struct ps_prochandle *ph, char *object_name, char *sym_name, psaddr_t *sym_addr) +{ + Fhdr *fp; + ulong addr; + + if((fp = findhdr(object_name)) == nil){ + print("libmach pthread: lookup %d %s %s => no such hdr\n", ph->pid, object_name, sym_name); + return PS_NOSYM; + } + if(elfsymlookup(fp->elf, sym_name, &addr) < 0){ + print("libmach pthread: lookup %d %s %s => name not found\n", ph->pid, object_name, sym_name); + return PS_NOSYM; + } + /* print("libmach pthread: lookup %d %s %s => 0x%lux\n", ph->pid, object_name, sym_name, addr); */ + *sym_addr = (void*)(addr+fp->base); + return PS_OK; +} + |