From pgollucci@p6m7g8.com Tue Jul 11 08:03:27 2006 Return-Path: Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 5DE7B16A4DF for ; Tue, 11 Jul 2006 08:03:27 +0000 (UTC) (envelope-from pgollucci@p6m7g8.com) Received: from piccollo.p6m7g8.net (c66-236-219-70.ip.panth.com [66.236.219.70]) by mx1.FreeBSD.org (Postfix) with ESMTP id 58A0843D45 for ; Tue, 11 Jul 2006 08:03:26 +0000 (GMT) (envelope-from pgollucci@p6m7g8.com) Received: from [192.168.0.210] (c-24-130-79-25.hsd1.ca.comcast.net [24.130.79.25]) (authenticated bits=0) by piccollo.p6m7g8.net (8.13.6/8.13.6) with ESMTP id k6B83G9v014546 (version=TLSv1/SSLv3 cipher=DHE-DSS-AES256-SHA bits=256 verify=NO); Tue, 11 Jul 2006 04:03:18 -0400 (EDT) (envelope-from pgollucci@p6m7g8.com) Message-Id: <44B35B4A.9010007@p6m7g8.com> Date: Tue, 11 Jul 2006 01:03:22 -0700 From: "Philip M. Gollucci" To: "Philip M. Gollucci" Cc: FreeBSD-gnats-submit@freebsd.org, dev@httpd.apache.org, dev@perl.apache.org, chip@force-elite.com In-Reply-To: <200607110754.k6B7se5L014262@piccollo.p6m7g8.net> Subject: Re: New port: devel/gdb65 GNU GDB 6.5 References: <200607110754.k6B7se5L014262@piccollo.p6m7g8.net> >Number: 100069 >Category: ports >Synopsis: Re: ports/100067: New port: devel/gdb65 GNU GDB 6.5 >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-ports-bugs >State: closed >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Jul 11 08:10:21 GMT 2006 >Closed-Date: Tue Jul 11 13:43:12 GMT 2006 >Last-Modified: Tue Jul 11 13:43:12 GMT 2006 >Originator: >Release: >Organization: >Environment: >Description: Sorry for the spam, I meant to send this e-mail with the link to the pr http://www.freebsd.org/cgi/query-pr.cgi?pr=100067 Philip M. Gollucci wrote: >> Submitter-Id: current-users >> Originator: Philip M. Gollucci >> Organization: P6M7G8 Consulting >> Confidential: no >> Synopsis: New port: devel/gdb65 GNU GDB 6.5 >> Severity: serious >> Priority: medium >> Category: ports >> Class: change-request >> Release: FreeBSD 6.1-STABLE i386 >> Environment: > System: FreeBSD home.p6m7g8.net 6.1-STABLE FreeBSD 6.1-STABLE #0: Mon Jul 3 23:24:44 PDT 2006 pgollucci@home.p6m7g8.net /usr/src/sys/HOME i386 > >Description: > sudo gdb ./httpd > gdb>r > GDB itself segfaults (all current versions in base and ports) > > This allows you for the first time since 2004 to debug httpd startup code on FreeBSD > Personally, I think its mission critical considering the applicationS it affects. > > This is currently only for the i386 architecture, and does not includet the KGDB patches. > > [I was having issues with set_context() and regcache_* functions] > >> Fix: > Use this new port - version 6.5. I haven't tried versions 6.2->6.4, but > why use outdated software. Its killing me that we haven't seen a gdb update > in almost 2 years even in ports. Base system I understand completely. > > --- gdb65.shar begins here --- > # This is a shell archive. Save it in a file, remove anything before > # this line, and then unpack it by entering "sh file". Note, it may > # create directories; files and directories will be owned by you and > # have default permissions. > # > # This archive contains: > # > # gdb65 > # gdb65/Makefile > # gdb65/distinfo > # gdb65/pkg-descr > # gdb65/files > # gdb65/files/fbsd4.h > # gdb65/files/freebsd-uthread.c > # gdb65/files/patch-gdb-Makefile.in > # gdb65/files/nm-fbsd.h > # gdb65/files/patch-gdb-version.in > # gdb65/pkg-plist > # > echo c - gdb65 > mkdir -p gdb65 > /dev/null 2>&1 > echo x - gdb65/Makefile > sed 's/^X//' >gdb65/Makefile << 'END-of-gdb65/Makefile' > X# ex:ts=8 > X# Ports collection makefile for: GDB 6.5 > X# Date created: 10 July 2006 > X# Whom: Philip M. Gollucci > X# > X# $FreeBSD$ > X# > X > XPORTNAME= gdb > XPORTVERSION= 6.5 > XCATEGORIES= devel > XMASTER_SITES= ${MASTER_SITE_GNU} > XMASTER_SITE_SUBDIR= gdb > XDISTNAME= gdb-${PORTVERSION} > X > XMAINTAINER= pgollucci@p6m7g8.com > XCOMMENT= GNU GDB 6.5 > X > XUSE_BZIP2= yes > XGNU_CONFIGURE= yes > XCONFIGURE_ARGS= --program-suffix=6.5 > XCFLAGS+= -DRL_NO_COMPAT -DKGDB > X > X.include > X > X.if ${OSVERSION} < 500000 > XCFLAGS+= -include ${FILESDIR}/fbsd4.h > X.endif > X > X.if ${ARCH} == "amd64" > XCONFIGURE_TARGET= x86_64-portbld-freebsd${OSREL} > X.endif > X > Xpre-configure: > X cd ${WRKSRC} ; ${RM} -rf dejagnu expect readline sim tcl texinfo > X ${LN} -sf ${FILESDIR}/freebsd-uthread.c ${WRKSRC}/gdb/freebsd-uthread.c > X ${LN} -sf ${FILESDIR}/nm-fbsd.h ${WRKSRC}/gdb/config > X > Xdo-install: > X ${INSTALL_PROGRAM} ${WRKSRC}/gdb/gdb \ > X ${PREFIX}/bin/${PORTNAME}${PORTVERSION:S/.//g} > X > X.include > END-of-gdb65/Makefile > echo x - gdb65/distinfo > sed 's/^X//' >gdb65/distinfo << 'END-of-gdb65/distinfo' > XMD5 (gdb-6.5.tar.bz2) = af6c8335230d7604aee0803b1df14f54 > XSHA256 (gdb-6.5.tar.bz2) = 0011318d9720781d486c835e88b915f90f2c10e7101d648b64dd4739218d3faf > XSIZE (gdb-6.5.tar.bz2) = 14303558 > END-of-gdb65/distinfo > echo x - gdb65/pkg-descr > sed 's/^X//' >gdb65/pkg-descr << 'END-of-gdb65/pkg-descr' > XGNU GDB 6.5 > X > XWWW: http://www.gnu.org/software/gdb/bugs/ > END-of-gdb65/pkg-descr > echo c - gdb65/files > mkdir -p gdb65/files > /dev/null 2>&1 > echo x - gdb65/files/fbsd4.h > sed 's/^X//' >gdb65/files/fbsd4.h << 'END-of-gdb65/files/fbsd4.h' > X// $FreeBSD: ports/devel/gdb6/files/fbsd4.h,v 1.2 2005/03/11 04:52:49 obrien Exp $ > X > Xextern void _rl_set_screen_size (int, int); > X > X#define rl_set_screen_size _rl_set_screen_size > X#define rl_filename_completion_function filename_completion_function > X > Xextern int screenwidth, screenheight; > X > Xstatic inline void > Xrl_get_screen_size (int *rows, int *cols) > X{ > X if (rows) *rows = screenheight; > X if (cols) *cols = screenwidth; > X} > X > X#if 0 > X#define savestring > X#include > X#undef savestring > X#endif > END-of-gdb65/files/fbsd4.h > echo x - gdb65/files/freebsd-uthread.c > sed 's/^X//' >gdb65/files/freebsd-uthread.c << 'END-of-gdb65/files/freebsd-uthread.c' > X/* Low level interface for debugging FreeBSD user threads for GDB, the GNU debugger. > X Copyright 1996, 1999 Free Software Foundation, Inc. > X > XThis file is part of GDB. > X > XThis program is free software; you can redistribute it and/or modify > Xit under the terms of the GNU General Public License as published by > Xthe Free Software Foundation; either version 2 of the License, or > X(at your option) any later version. > X > XThis program is distributed in the hope that it will be useful, > Xbut WITHOUT ANY WARRANTY; without even the implied warranty of > XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > XGNU General Public License for more details. > X > XYou should have received a copy of the GNU General Public License > Xalong with this program; if not, write to the Free Software > XFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ > X > X/* $FreeBSD: ports/devel/gdb6/files/freebsd-uthread.c,v 1.4 2004/10/20 19:37:48 obrien Exp $ */ > X > X/* This module implements a sort of half target that sits between the > X machine-independent parts of GDB and the ptrace interface (infptrace.c) to > X provide access to the FreeBSD user-mode thread implementation. > X > X FreeBSD threads are true user-mode threads, which are invoked via > X the pthread_* interfaces. These are mostly implemented in > X user-space, with all thread context kept in various structures that > X live in the user's heap. For the most part, the kernel has no > X knowlege of these threads. > X > X Based largely on hpux-thread.c > X > X */ > X > X > X#include "defs.h" > X#include > X#include > X#include > X#include > X#include "gdbthread.h" > X#include "target.h" > X#include "inferior.h" > X#include > X#include > X#include > X#include > X#include "gdbcore.h" > X#include "regcache.h" > X > Xextern int child_suppress_run; > Xextern struct target_ops child_ops; /* target vector for inftarg.c */ > X > Xextern void _initialize_freebsd_uthread PARAMS ((void)); > X > X/* Set to true while we are part-way through attaching */ > Xstatic int freebsd_uthread_attaching; > X > Xstatic int freebsd_uthread_active = 0; > Xstatic CORE_ADDR P_thread_list; > Xstatic CORE_ADDR P_thread_run; > X > X/* Pointer to the next function on the objfile event chain. */ > Xstatic void (*target_new_objfile_chain) (struct objfile *objfile); > X > Xstatic void freebsd_uthread_resume PARAMS ((ptid_t pid, int step, > X enum target_signal signo)); > X > Xstatic void init_freebsd_uthread_ops PARAMS ((void)); > X > Xstatic struct target_ops freebsd_uthread_ops; > X > Xstatic ptid_t find_active_ptid PARAMS ((void)); > X > Xstruct cached_pthread { > X u_int64_t uniqueid; > X int state; > X CORE_ADDR name; > X union { > X ucontext_t uc; > X jmp_buf jb; > X } ctx; > X}; > X > Xstatic ptid_t cached_ptid; > Xstatic struct cached_pthread cached_pthread; > Xstatic CORE_ADDR cached_pthread_addr; > X > XLIST_HEAD(idmaplist, idmap); > X > Xstruct idmap { > X LIST_ENTRY(idmap) link; > X u_int64_t uniqueid; > X int tid; > X}; > X > X#define MAPHASH_SIZE 257 > X#define TID_MIN 1 > X#define TID_MAX 16383 > X > Xstatic int tid_to_hash[TID_MAX + 1]; /* set to map_hash index */ > Xstatic struct idmaplist map_hash[MAPHASH_SIZE]; > Xstatic int next_free_tid = TID_MIN; /* first available tid */ > Xstatic int last_free_tid = TID_MIN; /* first unavailable */ > X > Xstatic CORE_ADDR P_thread_next_offset; > Xstatic CORE_ADDR P_thread_uniqueid_offset; > Xstatic CORE_ADDR P_thread_state_offset; > Xstatic CORE_ADDR P_thread_name_offset; > Xstatic CORE_ADDR P_thread_ctx_offset; > Xstatic CORE_ADDR P_thread_PS_RUNNING_value; > Xstatic CORE_ADDR P_thread_PS_DEAD_value; > X > Xstatic int next_offset; > Xstatic int uniqueid_offset; > Xstatic int state_offset; > Xstatic int name_offset; > Xstatic int ctx_offset; > Xstatic int PS_RUNNING_value; > Xstatic int PS_DEAD_value; > X > X#define UNIQUEID_HASH(id) (id % MAPHASH_SIZE) > X#define TID_ADD1(tid) (((tid) + 1) == TID_MAX + 1 \ > X ? TID_MIN : (tid) + 1) > X#define IS_TID_FREE(tid) (tid_to_hash[tid] == -1) > X > Xstatic int > Xget_new_tid(int h) > X{ > X int tid = next_free_tid; > X > X tid_to_hash[tid] = h; > X next_free_tid = TID_ADD1(next_free_tid); > X if (next_free_tid == last_free_tid) > X { > X int i; > X > X for (i = last_free_tid; TID_ADD1(i) != last_free_tid; i = TID_ADD1(i)) > X if (IS_TID_FREE(i)) > X break; > X if (TID_ADD1(i) == last_free_tid) > X { > X error("too many threads"); > X return 0; > X } > X next_free_tid = i; > X for (i = TID_ADD1(i); IS_TID_FREE(i); i = TID_ADD1(i)) > X ; > X last_free_tid = i; > X } > X > X return tid; > X} > X > Xstatic ptid_t > Xfind_ptid(u_int64_t uniqueid) > X{ > X int h = UNIQUEID_HASH(uniqueid); > X struct idmap *im; > X > X LIST_FOREACH(im, &map_hash[h], link) > X if (im->uniqueid == uniqueid) > X return MERGEPID(PIDGET(inferior_ptid), im->tid); > X > X im = xmalloc(sizeof(struct idmap)); > X im->uniqueid = uniqueid; > X im->tid = get_new_tid(h); > X LIST_INSERT_HEAD(&map_hash[h], im, link); > X > X return MERGEPID(PIDGET(inferior_ptid), im->tid); > X} > X > Xstatic void > Xfree_ptid(ptid_t ptid) > X{ > X int tid = TIDGET(ptid); > X int h = tid_to_hash[tid]; > X struct idmap *im; > X > X if (!tid) return; > X > X LIST_FOREACH(im, &map_hash[h], link) > X if (im->tid == tid) > X break; > X > X if (!im) return; > X > X LIST_REMOVE(im, link); > X tid_to_hash[tid] = -1; > X free(im); > X} > X > X#define READ_OFFSET(field) read_memory(P_thread_##field##_offset, \ > X (char *) &field##_offset, \ > X sizeof(field##_offset)) > X > X#define READ_VALUE(name) read_memory(P_thread_##name##_value, \ > X (char *) &name##_value, \ > X sizeof(name##_value)) > X > Xstatic void > Xread_thread_offsets (void) > X{ > X READ_OFFSET(next); > X READ_OFFSET(uniqueid); > X READ_OFFSET(state); > X READ_OFFSET(name); > X READ_OFFSET(ctx); > X > X READ_VALUE(PS_RUNNING); > X READ_VALUE(PS_DEAD); > X} > X > X#define READ_FIELD(ptr, T, field, result) \ > X read_memory ((ptr) + field##_offset, (char *) &(result), sizeof result) > X > Xstatic u_int64_t > Xread_pthread_uniqueid (CORE_ADDR ptr) > X{ > X u_int64_t uniqueid; > X READ_FIELD(ptr, u_int64_t, uniqueid, uniqueid); > X return uniqueid; > X} > X > Xstatic CORE_ADDR > Xread_pthread_next (CORE_ADDR ptr) > X{ > X CORE_ADDR next; > X READ_FIELD(ptr, CORE_ADDR, next, next); > X return next; > X} > X > Xstatic void > Xread_cached_pthread (CORE_ADDR ptr, struct cached_pthread *cache) > X{ > X READ_FIELD(ptr, u_int64_t, uniqueid, cache->uniqueid); > X READ_FIELD(ptr, int, state, cache->state); > X READ_FIELD(ptr, CORE_ADDR, name, cache->name); > X READ_FIELD(ptr, ucontext_t, ctx, cache->ctx); > X} > X > Xstatic ptid_t > Xfind_active_ptid (void) > X{ > X CORE_ADDR ptr; > X > X read_memory ((CORE_ADDR)P_thread_run, > X (char *)&ptr, > X sizeof ptr); > X > X return find_ptid(read_pthread_uniqueid(ptr)); > X} > X > Xstatic CORE_ADDR find_pthread_addr PARAMS ((ptid_t ptid)); > Xstatic struct cached_pthread * find_pthread PARAMS ((ptid_t ptid)); > X > Xstatic CORE_ADDR > Xfind_pthread_addr (ptid_t ptid) > X{ > X CORE_ADDR ptr; > X > X if (ptid_equal(ptid, cached_ptid)) > X return cached_pthread_addr; > X > X read_memory ((CORE_ADDR)P_thread_list, > X (char *)&ptr, > X sizeof ptr); > X > X while (ptr != 0) > X { > X if (ptid_equal(find_ptid(read_pthread_uniqueid(ptr)), ptid)) > X { > X cached_ptid = ptid; > X cached_pthread_addr = ptr; > X read_cached_pthread(ptr, &cached_pthread); > X return ptr; > X } > X ptr = read_pthread_next(ptr); > X } > X > X return NULL; > X} > X > Xstatic struct cached_pthread * > Xfind_pthread (ptid_t ptid) > X{ > X CORE_ADDR ptr; > X > X if (ptid_equal(ptid, cached_ptid)) > X return &cached_pthread; > X > X read_memory ((CORE_ADDR)P_thread_list, > X (char *)&ptr, > X sizeof ptr); > X > X while (ptr != 0) > X { > X if (ptid_equal(find_ptid(read_pthread_uniqueid(ptr)), ptid)) > X { > X cached_ptid = ptid; > X cached_pthread_addr = ptr; > X read_cached_pthread(ptr, &cached_pthread); > X return &cached_pthread; > X } > X ptr = read_pthread_next(ptr); > X } > X > X#if 0 > X error ("Can't find pthread %d,%d", PIDGET(ptid), TIDGET(ptid)); > X#endif > X return NULL; > X} > X > X > X/* Most target vector functions from here on actually just pass through to > X inftarg.c, as they don't need to do anything specific for threads. */ > X > X/* ARGSUSED */ > Xstatic void > Xfreebsd_uthread_open (char *arg, int from_tty) > X{ > X child_ops.to_open (arg, from_tty); > X} > X > X/* Attach to process PID, then initialize for debugging it > X and wait for the trace-trap that results from attaching. */ > X > Xstatic void > Xfreebsd_uthread_attach (char *args, int from_tty) > X{ > X child_ops.to_attach (args, from_tty); > X push_target (&freebsd_uthread_ops); > X freebsd_uthread_attaching = 1; > X} > X > X/* After an attach, see if the target is threaded */ > X > Xstatic void > Xfreebsd_uthread_post_attach (int pid) > X{ > X if (freebsd_uthread_active) > X { > X read_thread_offsets (); > X inferior_ptid = find_active_ptid (); > X add_thread (inferior_ptid); > X } > X else > X { > X unpush_target (&freebsd_uthread_ops); > X push_target (&child_ops); > X } > X > X freebsd_uthread_attaching = 0; > X} > X > X/* Take a program previously attached to and detaches it. > X The program resumes execution and will no longer stop > X on signals, etc. We'd better not have left any breakpoints > X in the program or it'll die when it hits one. For this > X to work, it may be necessary for the process to have been > X previously attached. It *might* work if the program was > X started via the normal ptrace (PTRACE_TRACEME). */ > X > Xstatic void > Xfreebsd_uthread_detach (char *args, int from_tty) > X{ > X child_ops.to_detach (args, from_tty); > X} > X > X/* Resume execution of process PID. If STEP is nozero, then > X just single step it. If SIGNAL is nonzero, restart it with that > X signal activated. We may have to convert pid from a thread-id to an LWP id > X for procfs. */ > X > Xstatic void > Xfreebsd_uthread_resume (ptid_t ptid, int step, enum target_signal signo) > X{ > X if (freebsd_uthread_attaching) > X { > X child_ops.to_resume (ptid, step, signo); > X return; > X } > X > X child_ops.to_resume (ptid, step, signo); > X cached_ptid = MERGEPID(0, 0); > X} > X > X/* Wait for any threads to stop. We may have to convert PID from a thread id > X to a LWP id, and vice versa on the way out. */ > X > Xstatic ptid_t > Xfreebsd_uthread_wait (ptid_t ptid, struct target_waitstatus *ourstatus) > X{ > X ptid_t rtnval; > X > X if (freebsd_uthread_attaching) > X { > X return child_ops.to_wait (ptid, ourstatus); > X } > X > X rtnval = child_ops.to_wait (ptid, ourstatus); > X > X if (PIDGET(rtnval) >= 0) > X { > X rtnval = find_active_ptid (); > X if (!in_thread_list (rtnval)) > X add_thread (rtnval); > X } > X > X return rtnval; > X} > X > X/* XXX: this needs to be selected by target, not [build] host */ > X#ifdef __i386__ > X > X#include "i386-tdep.h" > X > Xstatic char sigmap[I386_SSE_NUM_REGS] = /* map reg to sigcontext */ > X{ > X 12, /* eax */ > X 11, /* ecx */ > X 10, /* edx */ > X 9, /* ebx */ > X 8, /* esp */ > X 7, /* ebp */ > X 6, /* esi */ > X 5, /* edi */ > X 15, /* eip */ > X 17, /* eflags */ > X 16, /* cs */ > X 19, /* ss */ > X 4, /* ds */ > X 3, /* es */ > X 2, /* fs */ > X 1, /* gs */ > X -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */ > X -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */ > X -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */ > X -1, /* mxcsr */ > X}; > X > Xstatic char jmpmap[I386_SSE_NUM_REGS] = /* map reg to jmp_buf */ > X{ > X 6, /* eax */ > X -1, /* ecx */ > X -1, /* edx */ > X 1, /* ebx */ > X 2, /* esp */ > X 3, /* ebp */ > X 4, /* esi */ > X 5, /* edi */ > X 0, /* eip */ > X -1, /* eflags */ > X -1, /* cs */ > X -1, /* ss */ > X -1, /* ds */ > X -1, /* es */ > X -1, /* fs */ > X -1, /* gs */ > X -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */ > X -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */ > X -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */ > X -1, /* mxcsr */ > X}; > X > X#endif > X > X#ifdef __amd64__ > X > X#include "amd64-tdep.h" > X > X// XXX:DEO not fully ported from i386 yet!! > X > Xstatic char sigmap[AMD64_NUM_REGS_TOTAL] = /* map reg to sigcontext */ > X{ > X 12, /* rax */ > X 11, /* rcx */ > X 10, /* rdx */ > X 9, /* rbx */ > X 8, /* rsp */ > X 7, /* rbp */ > X 6, /* rsi */ > X 5, /* rdi */ > X 15, /* rip */ > X 17, /* rflags */ > X 16, /* cs */ > X 19, /* ss */ > X 4, /* ds */ > X 3, /* es */ > X 2, /* fs */ > X 1, /* gs */ > X -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */ > X -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */ > X -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */ > X -1, /* mxcsr */ > X}; > X > Xstatic char jmpmap[AMD64_NUM_REGS_TOTAL] = /* map reg to jmp_buf */ > X{ > X 6, /* rax */ > X -1, /* rcx */ > X -1, /* rdx */ > X 1, /* rbx */ > X 2, /* rsp */ > X 3, /* rbp */ > X 4, /* rsi */ > X 5, /* rdi */ > X 0, /* rip */ > X -1, /* rflags */ > X -1, /* cs */ > X -1, /* ss */ > X -1, /* ds */ > X -1, /* es */ > X -1, /* fs */ > X -1, /* gs */ > X -1, -1, -1, -1, -1, -1, -1, /* st0-st7 */ > X -1, -1, -1, -1, -1, -1, -1, /* fctrl-fop */ > X -1, -1, -1, -1, -1, -1, -1, /* xmm0-xmm7 */ > X -1, /* mxcsr */ > X}; > X > X#endif > X > X#ifdef __alpha__ > X > X#include "alpha-tdep.h" > X > Xstatic char sigmap[ALPHA_NUM_REGS] = /* map reg to sigcontext */ > X{ > X 1, 2, 3, 4, 5, 6, 7, 8, /* v0 - t6 */ > X 9, 10, 11, 12, 13, 14, 15, 16, /* t7 - fp */ > X 17, 18, 19, 20, 21, 22, 23, 24, /* a0 - t9 */ > X 25, 26, 27, 28, 29, 30, 31, 32, /* t10 - zero */ > X 38, 39, 40, 41, 42, 43, 44, 45, /* f0 - f7 */ > X 46, 47, 48, 49, 50, 51, 52, 53, /* f8 - f15 */ > X 54, 55, 56, 57, 58, 59, 60, 61, /* f16 - f23 */ > X 62, 63, 64, 65, 66, 67, 68, 69, /* f24 - f31 */ > X 33, -1 /* pc, vfp */ > X}; > Xstatic char jmpmap[ALPHA_NUM_REGS] = { > X 4, 5, 6, 7, 8, 9, 10, 11, /* v0 - t6 */ > X 12, 13, 14, 15, 16, 17, 18, 19, /* t7 - fp */ > X 20, 21, 22, 23, 24, 25, 26, 27, /* a0 - t9 */ > X 28, 29, 30, 31, 32, 33, 34, 35, /* t10 - zero */ > X 37, 38, 39, 40, 41, 42, 43, 44, /* f0 - f7 */ > X 45, 46, 47, 48, 49, 50, 51, 52, /* f8 - f15 */ > X 53, 54, 55, 56, 57, 58, 59, 60, /* f16 - f23 */ > X 61, 62, 63, 64, 65, 66, 67, 68, /* f24 - f31 */ > X 2, -1, /* pc, vfp */ > X}; > X > X#endif > X > X#ifdef __sparc64__ > X > Xstatic char sigmap[125] = /* map reg to sigcontext */ > X{ > X -1 > X}; > Xstatic char jmpmap[125] = { > X -1 > X}; > X > X#endif > X > Xstatic void > Xfreebsd_uthread_fetch_registers (int regno) > X{ > X struct cached_pthread *thread; > X int active; > X int first_regno, last_regno; > X register_t *regbase; > X char *regmap; > X > X if (freebsd_uthread_attaching || TIDGET(inferior_ptid) == 0) > X { > X child_ops.to_fetch_registers (regno); > X return; > X } > X > X thread = find_pthread (inferior_ptid); > X active = (ptid_equal(inferior_ptid, find_active_ptid())); > X > X if (active) > X { > X child_ops.to_fetch_registers (regno); > X return; > X } > X > X if (regno == -1) > X { > X first_regno = 0; > X last_regno = NUM_REGS - 1; > X } > X else > X { > X first_regno = regno; > X last_regno = regno; > X } > X > X regbase = (register_t*) &thread->ctx.jb[0]; > X regmap = jmpmap; > X > X for (regno = first_regno; regno <= last_regno; regno++) > X { > X if (regmap[regno] == -1) > X child_ops.to_fetch_registers (regno); > X else > X if (thread) > X regcache_raw_supply (current_regcache, regno, (char*) ®base[regmap[regno]]); > X else > X regcache_raw_supply (current_regcache, regno, NULL); > X } > X} > X > Xstatic void > Xfreebsd_uthread_store_registers (int regno) > X{ > X struct cached_pthread *thread; > X CORE_ADDR ptr; > X int first_regno, last_regno; > X u_int32_t *regbase; > X char *regmap; > X > X if (freebsd_uthread_attaching) > X { > X child_ops.to_store_registers (regno); > X return; > X } > X > X thread = find_pthread (inferior_ptid); > X > X if (thread->state == PS_RUNNING_value) > X { > X child_ops.to_store_registers (regno); > X return; > X } > X > X if (regno == -1) > X { > X first_regno = 0; > X last_regno = NUM_REGS - 1; > X } > X else > X { > X first_regno = regno; > X last_regno = regno; > X } > X > X regbase = (u_int32_t*) &thread->ctx.jb[0]; > X regmap = jmpmap; > X > X ptr = find_pthread_addr (inferior_ptid); > X for (regno = first_regno; regno <= last_regno; regno++) > X { > X if (regmap[regno] == -1) > X child_ops.to_store_registers (regno); > X else > X { > X u_int32_t *reg = ®base[regmap[regno]]; > X int off; > X > X /* Hang onto cached value */ > X/*DEO:XXX*/ > X memcpy(reg, deprecated_registers /*regcache_collect ()*/+ DEPRECATED_REGISTER_BYTE (regno), > X register_size (current_gdbarch, regno)); > X > X /* And push out to inferior */ > X off = (char *) reg - (char *) thread; > X write_memory (ptr + off, > X/*DEO:XXX*/ > X deprecated_registers /*regcache_collect ()*/+ DEPRECATED_REGISTER_BYTE (regno), > X register_size (current_gdbarch, regno)); > X } > X } > X} > X > X/* Get ready to modify the registers array. On machines which store > X individual registers, this doesn't need to do anything. On machines > X which store all the registers in one fell swoop, this makes sure > X that registers contains all the registers from the program being > X debugged. */ > X > Xstatic void > Xfreebsd_uthread_prepare_to_store (void) > X{ > X child_ops.to_prepare_to_store (); > X} > X > Xstatic int > Xfreebsd_uthread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, > X int dowrite, struct mem_attrib *attrib, > X struct target_ops *target) > X{ > X return child_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, > X attrib, target); > X} > X > X/* Print status information about what we're accessing. */ > X > Xstatic void > Xfreebsd_uthread_files_info (struct target_ops *ignore) > X{ > X child_ops.to_files_info (ignore); > X} > X > Xstatic void > Xfreebsd_uthread_kill_inferior (void) > X{ > X child_ops.to_kill (); > X} > X > Xstatic void > Xfreebsd_uthread_notice_signals (ptid_t ptid) > X{ > X child_ops.to_notice_signals (ptid); > X} > X > X/* Fork an inferior process, and start debugging it with /proc. */ > X > Xstatic void > Xfreebsd_uthread_create_inferior (char *exec_file, char *allargs, char **env, > X int from_tty) > X{ > X child_ops.to_create_inferior (exec_file, allargs, env, from_tty); > X > X if (PIDGET(inferior_ptid) && freebsd_uthread_active) > X { > X read_thread_offsets (); > X push_target (&freebsd_uthread_ops); > X inferior_ptid = find_active_ptid (); > X add_thread (inferior_ptid); > X } > X} > X > X/* This routine is called to find out if the inferior is using threads. > X We check for the _thread_run and _thread_list globals. */ > X > Xvoid > Xfreebsd_uthread_new_objfile (struct objfile *objfile) > X{ > X struct minimal_symbol *ms; > X > X if (!objfile) > X { > X freebsd_uthread_active = 0; > X return; > X } > X > X ms = lookup_minimal_symbol ("_thread_run", NULL, objfile); > X > X if (!ms) > X return; > X > X P_thread_run = SYMBOL_VALUE_ADDRESS (ms); > X > X ms = lookup_minimal_symbol ("_thread_list", NULL, objfile); > X > X if (!ms) > X return; > X > X P_thread_list = SYMBOL_VALUE_ADDRESS (ms); > X > X#define OFFSET_SYM(field) "_thread_" #field "_offset" > X#define LOOKUP_OFFSET(field) \ > X do { \ > X ms = lookup_minimal_symbol (OFFSET_SYM(field), NULL, objfile); \ > X if (!ms) \ > X return; \ > X P_thread_##field##_offset = SYMBOL_VALUE_ADDRESS (ms); \ > X } while (0); > X > X#define VALUE_SYM(name) "_thread_" #name "_value" > X#define LOOKUP_VALUE(name) \ > X do { \ > X ms = lookup_minimal_symbol (VALUE_SYM(name), NULL, objfile); \ > X if (!ms) \ > X return; \ > X P_thread_##name##_value = SYMBOL_VALUE_ADDRESS (ms); \ > X } while (0); > X > X LOOKUP_OFFSET(next); > X LOOKUP_OFFSET(uniqueid); > X LOOKUP_OFFSET(state); > X LOOKUP_OFFSET(name); > X LOOKUP_OFFSET(ctx); > X > X LOOKUP_VALUE(PS_RUNNING); > X LOOKUP_VALUE(PS_DEAD); > X > X freebsd_uthread_active = 1; > X} > X > X/* Clean up after the inferior dies. */ > X > Xstatic void > Xfreebsd_uthread_mourn_inferior () > X{ > X child_ops.to_mourn_inferior (); > X unpush_target (&freebsd_uthread_ops); > X} > X > X/* Mark our target-struct as eligible for stray "run" and "attach" commands. */ > X > Xstatic int > Xfreebsd_uthread_can_run () > X{ > X return child_suppress_run; > X} > X > Xstatic int > Xfreebsd_uthread_thread_alive (ptid_t ptid) > X{ > X struct cached_pthread *thread; > X int ret = 0; > X > X if (freebsd_uthread_attaching) > X return 1; > X > X /* > X * We can get called from child_ops.to_wait() which passes the underlying > X * pid (without a thread number). > X */ > X if (TIDGET(ptid) == 0) > X return 1; > X > X if (find_pthread_addr (ptid) != 0) > X { > X thread = find_pthread (ptid); > X ret = (thread->state != PS_DEAD_value); > X } > X > X if (!ret) > X free_ptid(ptid); > X > X return ret; > X} > X > Xstatic void > Xfreebsd_uthread_stop (void) > X{ > X child_ops.to_stop (); > X} > X > Xstatic void > Xfreebsd_uthread_find_new_threads (void) > X{ > X CORE_ADDR ptr; > X int state; > X u_int64_t uniqueid; > X > X read_memory ((CORE_ADDR)P_thread_list, > X (char *)&ptr, > X sizeof ptr); > X > X while (ptr != 0) > X { > X READ_FIELD(ptr, int, state, state); > X READ_FIELD(ptr, u_int64_t, uniqueid, uniqueid); > X if (state != PS_DEAD_value && > X !in_thread_list (find_ptid(uniqueid))) > X add_thread (find_ptid(uniqueid)); > X ptr = read_pthread_next(ptr); > X } > X} > X > X/* MUST MATCH enum pthread_state */ > Xstatic const char *statenames[] = { > X "RUNNING", > X "SIGTHREAD", > X "MUTEX_WAIT", > X "COND_WAIT", > X "FDLR_WAIT", > X "FDLW_WAIT", > X "FDR_WAIT", > X "FDW_WAIT", > X "POLL_WAIT", > X "FILE_WAIT", > X "SELECT_WAIT", > X "SLEEP_WAIT", > X "WAIT_WAIT", > X "SIGSUSPEND", > X "SIGWAIT", > X "SPINBLOCK", > X "JOIN", > X "SUSPENDED", > X "DEAD", > X "DEADLOCK", > X}; > X > X#if 0 > X > Xstatic int > Xfreebsd_uthread_get_thread_info (ref, selection, info) > X gdb_threadref *ref; > X int selection; > X struct gdb_ext_thread_info *info; > X{ > X int pid = *ref; > X struct cached_pthread *thread = find_pthread (pid); > X struct cleanup *old_chain; > X > X old_chain = save_inferior_pid (); > X inferior_pid = main_pid; > X > X memset(&info->threadid, 0, OPAQUETHREADBYTES); > X > X memcpy(&info->threadid, ref, sizeof *ref); > X info->active = thread->state == PS_RUNNING_value; > X strcpy(info->display, statenames[thread->state]); > X if (thread->name) > X read_memory ((CORE_ADDR) thread->name, info->shortname, 32); > X else > X strcpy(info->shortname, ""); > X > X do_cleanups (old_chain); > X return (0); > X} > X > X#endif > X > Xchar * > Xfreebsd_uthread_pid_to_str (ptid_t ptid) > X{ > X static char buf[30]; > X > X if (DEPRECATED_STREQ (current_target.to_shortname, "freebsd-uthreads")) > X sprintf (buf, "Process %d, Thread %ld", > X PIDGET(ptid), TIDGET(ptid)); > X else > X sprintf (buf, "Process %d", PIDGET(ptid)); > X > X return buf; > X} > X > X > Xstatic void > Xinit_freebsd_uthread_ops () > X{ > X freebsd_uthread_ops.to_shortname = "freebsd-uthreads"; > X freebsd_uthread_ops.to_longname = "FreeBSD uthreads"; > X freebsd_uthread_ops.to_doc = "FreeBSD user threads support."; > X freebsd_uthread_ops.to_open = freebsd_uthread_open; > X freebsd_uthread_ops.to_attach = freebsd_uthread_attach; > X freebsd_uthread_ops.to_post_attach = freebsd_uthread_post_attach; > X freebsd_uthread_ops.to_detach = freebsd_uthread_detach; > X freebsd_uthread_ops.to_resume = freebsd_uthread_resume; > X freebsd_uthread_ops.to_wait = freebsd_uthread_wait; > X freebsd_uthread_ops.to_fetch_registers = freebsd_uthread_fetch_registers; > X freebsd_uthread_ops.to_store_registers = freebsd_uthread_store_registers; > X freebsd_uthread_ops.to_prepare_to_store = freebsd_uthread_prepare_to_store; > X freebsd_uthread_ops.to_xfer_memory = freebsd_uthread_xfer_memory; > X freebsd_uthread_ops.to_files_info = freebsd_uthread_files_info; > X freebsd_uthread_ops.to_insert_breakpoint = memory_insert_breakpoint; > X freebsd_uthread_ops.to_remove_breakpoint = memory_remove_breakpoint; > X freebsd_uthread_ops.to_terminal_init = terminal_init_inferior; > X freebsd_uthread_ops.to_terminal_inferior = terminal_inferior; > X freebsd_uthread_ops.to_terminal_ours_for_output = terminal_ours_for_output; > X freebsd_uthread_ops.to_terminal_ours = terminal_ours; > X freebsd_uthread_ops.to_terminal_info = child_terminal_info; > X freebsd_uthread_ops.to_kill = freebsd_uthread_kill_inferior; > X freebsd_uthread_ops.to_create_inferior = freebsd_uthread_create_inferior; > X freebsd_uthread_ops.to_mourn_inferior = freebsd_uthread_mourn_inferior; > X freebsd_uthread_ops.to_can_run = freebsd_uthread_can_run; > X freebsd_uthread_ops.to_notice_signals = freebsd_uthread_notice_signals; > X freebsd_uthread_ops.to_thread_alive = freebsd_uthread_thread_alive; > X freebsd_uthread_ops.to_stop = freebsd_uthread_stop; > X freebsd_uthread_ops.to_stratum = process_stratum; > X freebsd_uthread_ops.to_has_all_memory = 1; > X freebsd_uthread_ops.to_has_memory = 1; > X freebsd_uthread_ops.to_has_stack = 1; > X freebsd_uthread_ops.to_has_registers = 1; > X freebsd_uthread_ops.to_has_execution = 1; > X freebsd_uthread_ops.to_has_thread_control = 0; > X freebsd_uthread_ops.to_magic = OPS_MAGIC; > X freebsd_uthread_ops.to_find_new_threads = freebsd_uthread_find_new_threads; > X freebsd_uthread_ops.to_pid_to_str = freebsd_uthread_pid_to_str; > X#if 0 > X freebsd_uthread_vec.get_thread_info = freebsd_uthread_get_thread_info; > X#endif > X} > X > Xvoid > X_initialize_freebsd_uthread () > X{ > X init_freebsd_uthread_ops (); > X add_target (&freebsd_uthread_ops); > X > X target_new_objfile_chain = deprecated_target_new_objfile_hook; > X deprecated_target_new_objfile_hook = freebsd_uthread_new_objfile; > X > X child_suppress_run = 1; > X} > END-of-gdb65/files/freebsd-uthread.c > echo x - gdb65/files/patch-gdb-Makefile.in > sed 's/^X//' >gdb65/files/patch-gdb-Makefile.in << 'END-of-gdb65/files/patch-gdb-Makefile.in' > X--- gdb/Makefile.in.orig Mon Jul 10 23:49:02 2006 > X+++ gdb/Makefile.in Mon Jul 10 23:50:38 2006 > X@@ -122,10 +122,10 @@ > X BFD_CFLAGS = -I$(BFD_DIR) -I$(BFD_SRC) > X > X # Where is the READLINE library? Typically in ../readline. > X-READLINE_DIR = ../readline > X-READLINE = $(READLINE_DIR)/libreadline.a > X-READLINE_SRC = $(srcdir)/$(READLINE_DIR) > X-READLINE_CFLAGS = -I$(READLINE_SRC)/.. > X+#READLINE_DIR = ../readline > X+#READLINE = $(READLINE_DIR)/libreadline.a > X+#READLINE_SRC = $(srcdir)/$(READLINE_DIR) > X+#READLINE_CFLAGS = -I$(READLINE_SRC)/.. > X > X WARN_CFLAGS = @WARN_CFLAGS@ > X WERROR_CFLAGS = @WERROR_CFLAGS@ > X@@ -590,9 +590,9 @@ > X demangle_h = $(INCLUDE_DIR)/demangle.h > X obstack_h = $(INCLUDE_DIR)/obstack.h > X opcode_m68hc11_h = $(INCLUDE_DIR)/opcode/m68hc11.h > X-readline_h = $(READLINE_SRC)/readline.h > X-readline_tilde_h = $(READLINE_SRC)/tilde.h > X-readline_history_h = $(READLINE_SRC)/history.h > X+#readline_h = $(READLINE_SRC)/readline.h > X+#readline_tilde_h = $(READLINE_SRC)/tilde.h > X+#readline_history_h = $(READLINE_SRC)/history.h > X frv_desc_h = $(OPCODES_SRC)/frv-desc.h > X sh_opc_h = $(OPCODES_SRC)/sh-opc.h > X gdb_callback_h = $(INCLUDE_DIR)/gdb/callback.h > X@@ -3171,3 +3171,4 @@ > X $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tui-winsource.c > X > X ### end of the gdb Makefile.in. > X+READLINE = -lreadline > END-of-gdb65/files/patch-gdb-Makefile.in > echo x - gdb65/files/nm-fbsd.h > sed 's/^X//' >gdb65/files/nm-fbsd.h << 'END-of-gdb65/files/nm-fbsd.h' > X#ifndef CONFIG_NM_FBSD_H > X#define CONFIG_NM_FBSD_H > X > X/* $FreeBSD: ports/devel/gdb6/files/nm-fbsd.h,v 1.1 2004/05/13 04:28:38 obrien Exp $ */ > X > X#ifdef HAVE_SYS_PARAM_H > X#include > X#endif > X > Xextern int kernel_debugging; > Xextern int kernel_writablecore; > X > XCORE_ADDR fbsd_kern_frame_saved_pc(struct frame_info *frame); > X > X#if __FreeBSD_version >= 500032 > X#define KGDB 1 > X#define ADDITIONAL_OPTIONS \ > X {"kernel", no_argument, &kernel_debugging, 1}, \ > X {"k", no_argument, &kernel_debugging, 1}, \ > X {"wcore", no_argument, &kernel_writablecore, 1}, \ > X {"w", no_argument, &kernel_writablecore, 1}, > X > X#define ADDITIONAL_OPTION_HELP \ > X "\ > X --kernel Enable kernel debugging.\n\ > X --wcore Make core file writable (only works for /dev/mem).\n\ > X This option only works while debugging a kernel !!\n\ > X" > X > X#define DEFAULT_PROMPT kernel_debugging?"(kgdb) ":"(gdb) " > X > X/* misuse START_PROGRESS to test whether we're running as kgdb */ > X/* START_PROGRESS is called at the top of main */ > X#undef START_PROGRESS > X#define START_PROGRESS(STR,N) \ > X if (!strcmp (STR, "kgdb")) \ > X kernel_debugging = 1; > X#endif > X#endif /* CONFIG_NM_FBSD_H */ > END-of-gdb65/files/nm-fbsd.h > echo x - gdb65/files/patch-gdb-version.in > sed 's/^X//' >gdb65/files/patch-gdb-version.in << 'END-of-gdb65/files/patch-gdb-version.in' > X--- gdb/version.in.orig Tue Jun 20 22:05:40 2006 > X+++ gdb/version.in Mon Jul 10 23:17:58 2006 > X@@ -1 +1 @@ > X-6.5 > X+6.5 [GDB v6.x for FreeBSD] > END-of-gdb65/files/patch-gdb-version.in > echo x - gdb65/pkg-plist > sed 's/^X//' >gdb65/pkg-plist << 'END-of-gdb65/pkg-plist' > X@comment $FreeBSD$ > Xbin/gdb65 > END-of-gdb65/pkg-plist > exit > --- gdb65.shar ends here --- > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org > For additional commands, e-mail: dev-help@perl.apache.org -- ------------------------------------------------------------------------ Philip M. Gollucci (pgollucci@p6m7g8.com) 323.219.4708 Consultant / http://p6m7g8.net/Resume/resume.shtml Senior Software Engineer - TicketMaster - http://ticketmaster.com 1024D/A79997FA F357 0FDD 2301 6296 690F 6A47 D55A 7172 A799 97F "In all that I've done wrong I know I must have done something right to deserve a hug every morning and butterfly kisses at night." >How-To-Repeat: >Fix: >Release-Note: >Audit-Trail: State-Changed-From-To: open->closed State-Changed-By: linimon State-Changed-When: Tue Jul 11 13:42:19 UTC 2006 State-Changed-Why: Duplicate of ports/100069. Responsible-Changed-From-To: gnats-admin->freebsd-ports-bugs Responsible-Changed-By: linimon Responsible-Changed-When: Tue Jul 11 13:42:19 UTC 2006 Responsible-Changed-Why: http://www.freebsd.org/cgi/query-pr.cgi?pr=100069 >Unformatted: