Ver código fonte

Add a patch for better debugging of staticly linked threaded apps.
-Erik

Eric Andersen 22 anos atrás
pai
commit
7775f655a9
2 arquivos alterados com 503 adições e 1 exclusões
  1. 3 1
      make/gdb.mk
  2. 500 0
      sources/gdb.patch

+ 3 - 1
make/gdb.mk

@@ -7,12 +7,14 @@
 GDB_SITE:=ftp://ftp.gnu.org/gnu/gdb/
 GDB_SITE:=ftp://ftp.gnu.org/gnu/gdb/
 GDB_DIR:=$(BUILD_DIR)/gdb-5.3
 GDB_DIR:=$(BUILD_DIR)/gdb-5.3
 GDB_SOURCE:=gdb-5.3.tar.gz
 GDB_SOURCE:=gdb-5.3.tar.gz
+GDB_PATCH:=$(SOURCE_DIR)/gdb.patch
 
 
 $(DL_DIR)/$(GDB_SOURCE):
 $(DL_DIR)/$(GDB_SOURCE):
 	$(WGET) -P $(DL_DIR) $(GDB_SITE)/$(GDB_SOURCE)
 	$(WGET) -P $(DL_DIR) $(GDB_SITE)/$(GDB_SOURCE)
 
 
-$(GDB_DIR)/.unpacked: $(DL_DIR)/$(GDB_SOURCE)
+$(GDB_DIR)/.unpacked: $(DL_DIR)/$(GDB_SOURCE) $(GDB_PATCH)
 	gunzip -c $(DL_DIR)/$(GDB_SOURCE) | tar -C $(BUILD_DIR) -xvf -
 	gunzip -c $(DL_DIR)/$(GDB_SOURCE) | tar -C $(BUILD_DIR) -xvf -
+	cat $(GDB_PATCH) | patch -p1 -d $(GDB_DIR)
 	touch  $(GDB_DIR)/.unpacked
 	touch  $(GDB_DIR)/.unpacked
 
 
 $(GDB_DIR)/.configured: $(GDB_DIR)/.unpacked
 $(GDB_DIR)/.configured: $(GDB_DIR)/.unpacked

+ 500 - 0
sources/gdb.patch

@@ -0,0 +1,500 @@
+Patch pending upstream, probably acceptable.
+--------------------------------------------
+
+
+
+Daniel Jacobowitz <drow@mvista.com> writes:
+> I like this.  The way func_frame_chain_valid should really be used is
+> by something like:
+> 
+>   /* NOTE: tm-i386nw.h and tm-i386v4.h override this.  */
+>   set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
+> 
+> (copied from i386-tdep.c).
+> 
+> Does this patch work for you?
+
+Yes, thanks.  I've included a revised version of my patch below.
+
+> I'm curious as to why we can't just set this universally, or at least a
+> little more globally.  Most things that have a main () use it as a
+> normal main ().  I'd propose that we set it as the default frame chain,
+> and provide/document an option to ignore inside_main_func.
+
+Well, gdbarch is never supposed to change the default behavior of
+macros; this helps us convert pre-gdbarch targets incrementally.
+Simply turning on gdbarch for one's target ideally wouldn't change its
+behavior at all.
+
+
+[Patch revised for Debian snapshot]
+--- snap/gdb/i386-linux-tdep.c.orig	2002-08-18 19:53:57.000000000 -0400
++++ snap/gdb/i386-linux-tdep.c	2002-08-18 19:54:31.000000000 -0400
+@@ -452,6 +452,9 @@
+ 
+   set_solib_svr4_fetch_link_map_offsets (gdbarch,
+ 				       i386_linux_svr4_fetch_link_map_offsets);
++
++  set_gdbarch_frame_chain_valid (gdbarch,
++				 generic_func_frame_chain_valid);
+ }
+ 
+ /* Provide a prototype to silence -Wmissing-prototypes.  */
+[Hurd needs 6.  Take 8, since it does no real harm.]
+
+
+Package: gdb
+Severity: normal
+Tags: patch, sid
+
+Hello,
+
+GDB will crash on the Hurd after issuing the 'show' and hitting enter
+a few times:
+
+../../gdb/ui-out.c:130: gdb-internal-error: push_level: Assertion       +`uiout->level >= 0 && uiout->level < MAX_UI_OUT_LEVELS' failed.
+
+the problem is that MAX_UI_OUT_LEVELS is not high enough for the extra
+option we have on the Hurd, it should be rised to 6 then, which works
+fine:
+
+--- gdb-5.2.cvs20020401/gdb/ui-out.c~   Fri May  3 02:19:20 2002
++++ gdb-5.2.cvs20020401/gdb/ui-out.c    Fri May  3 02:19:32 2002
+@@ -45,7 +45,7 @@
+    is always available.  Stack/nested level 0 is reserved for the
+    top-level result. */
+ 
+-enum { MAX_UI_OUT_LEVELS = 5 };
++enum { MAX_UI_OUT_LEVELS = 8 };
+ 
+ struct ui_out_level
+   {
+
+-- 
+Robert Millan
+
+"5 years from now everyone will be running
+free GNU on their 200 MIPS, 64M SPARCstation-5"
+
+              Andrew S. Tanenbaum, 30 Jan 1992
+
+
+Submitted upstream, not liked very much.  It's a hack, but it will do for
+now.
+
+2002-07-31  Daniel Jacobowitz  <drow@mvista.com>
+
+	Fix PR gdb/568
+	* thread-db.c (lwp_from_thread): Only warn if unable to find
+	the thread.
+
+Index: thread-db.c
+===================================================================
+RCS file: /cvs/src/src/gdb/thread-db.c,v
+retrieving revision 1.22
+diff -u -p -r1.22 thread-db.c
+--- gdb/gdb/thread-db.c	23 Mar 2002 17:38:13 -0000	1.22
++++ gdb/gdb/thread-db.c	31 Jul 2002 16:29:52 -0000
+@@ -260,6 +260,12 @@ lwp_from_thread (ptid_t ptid)
+     return ptid;
+ 
+   err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th);
++  if (err == TD_ERR)
++    {
++      warning ("Cannot find thread %ld: %s",
++	       (long) GET_THREAD (ptid), thread_db_err_str (err));
++      return ptid;
++    }
+   if (err != TD_OK)
+     error ("Cannot find thread %ld: %s",
+ 	   (long) GET_THREAD (ptid), thread_db_err_str (err));
+From Michael Fedrowitz <michaelf@debian.org>.  Not submitted to FSF yet.
+
+ Hi,
+
+gdb fails to build from source on m68k because some definitions have
+been removed from tm-m68k.h. The patch below readds them.
+
+-Michael
+
+
+diff -urN gdb-5.2.cvs20020818.orig/gdb/config/m68k/tm-m68k.h gdb-5.2.cvs20020818/gdb/config/m68k/tm-m68k.h
+--- gdb-5.2.cvs20020818.orig/gdb/config/m68k/tm-m68k.h	2002-07-10 19:01:38.000000000 +0200
++++ gdb-5.2.cvs20020818/gdb/config/m68k/tm-m68k.h	2002-10-06 18:01:59.000000000 +0200
+@@ -26,8 +26,11 @@
+ /* Generic 68000 stuff, to be included by other tm-*.h files.  */
+ 
+ /* D0_REGNM and A0_REGNUM must be defined here because they are
+-   used by the monitor.  */
++   used by the monitor. FPC_REGNUM, FPS_REGNUM and FPI_REGNUM are
++   defined here because they are used by m68klinux-nat.c.  */
+ 
+ #define D0_REGNUM 0
+ #define A0_REGNUM 8
+-
++#define FPC_REGNUM 26
++#define FPS_REGNUM 27
++#define FPI_REGNUM 28
+
+
+2002-11-24  Daniel Jacobowitz  <drow@mvista.com>
+
+	* doublest.c (convert_floatformat_to_doublest): Cast exp_bias to int.
+	* config/alpha/alpha-linux.mh (MH_CFLAGS): Add -mieee.
+
+--- gdb-5.2.debian90.cvs20021120/gdb/doublest.c.orig	2002-11-24 17:48:16.000000000 -0500
++++ gdb-5.2.debian90.cvs20021120/gdb/doublest.c	2002-11-24 17:48:25.000000000 -0500
+@@ -177,7 +177,7 @@
+   if (!special_exponent)
+     exponent -= fmt->exp_bias;
+   else if (exponent == 0)
+-    exponent = 1 - fmt->exp_bias;
++    exponent = 1 - (int)fmt->exp_bias;
+ 
+   /* Build the result algebraically.  Might go infinite, underflow, etc;
+      who cares. */
+--- gdb-5.2.debian90.cvs20021120/gdb/config/alpha/alpha-linux.mh.orig	2002-11-24 17:50:30.000000000 -0500
++++ gdb-5.2.debian90.cvs20021120/gdb/config/alpha/alpha-linux.mh	2002-11-24 17:50:41.000000000 -0500
+@@ -8,3 +8,5 @@
+ 
+ MMALLOC = 
+ MMALLOC_CFLAGS = -DNO_MMALLOC 
++
++MH_CFLAGS = -mieee
+In CVS but not in 5.3 branch...
+
+2002-10-23  Daniel Jacobowitz  <drow@mvista.com>
+
+	* lin-lwp.c (lin_lwp_resume): Remove resume_all test for !step.
+
+Index: lin-lwp.c
+===================================================================
+RCS file: /cvs/src/src/gdb/lin-lwp.c,v
+retrieving revision 1.35
+diff -u -p -r1.35 lin-lwp.c
+--- gdb-5.2.90/gdb/lin-lwp.c	27 Aug 2002 22:37:06 -0000	1.35
++++ gdb-5.2.90/gdb/lin-lwp.c	23 Oct 2002 04:23:13 -0000
+@@ -579,11 +579,8 @@ lin_lwp_resume (ptid_t ptid, int step, e
+   struct lwp_info *lp;
+   int resume_all;
+ 
+-  /* Apparently the interpretation of PID is dependent on STEP: If
+-     STEP is non-zero, a specific PID means `step only this process
+-     id'.  But if STEP is zero, then PID means `continue *all*
+-     processes, but give the signal only to this one'.  */
+-  resume_all = (PIDGET (ptid) == -1) || !step;
++  /* A specific PTID means `step only this process id'.  */
++  resume_all = (PIDGET (ptid) == -1);
+ 
+   if (resume_all)
+     iterate_over_lwps (resume_set_callback, NULL);
+
+Not submitted yet, testing.
+
+--- gdb-5.2.90/gdb/alpha-tdep.c.orig	Sun Nov 24 21:42:53 2002
++++ gdb-5.2.90/gdb/alpha-tdep.c	Sun Nov 24 21:48:26 2002
+@@ -99,10 +99,12 @@
+ 
+ static alpha_extra_func_info_t heuristic_proc_desc (CORE_ADDR,
+ 						    CORE_ADDR,
+-						    struct frame_info *);
++						    struct frame_info *,
++						    int);
+ 
+ static alpha_extra_func_info_t find_proc_desc (CORE_ADDR,
+-					       struct frame_info *);
++					       struct frame_info *,
++					       int);
+ 
+ #if 0
+ static int alpha_in_lenient_prologue (CORE_ADDR, CORE_ADDR);
+@@ -512,7 +514,7 @@
+   if (tmp != 0)
+     pc = tmp;
+ 
+-  proc_desc = find_proc_desc (pc, frame->next);
++  proc_desc = find_proc_desc (pc, frame->next, 1);
+   pcreg = proc_desc ? PROC_PC_REG (proc_desc) : ALPHA_RA_REGNUM;
+ 
+   if (frame->signal_handler_caller)
+@@ -596,10 +598,10 @@
+ 
+ static alpha_extra_func_info_t
+ heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc,
+-		     struct frame_info *next_frame)
++		     struct frame_info *next_frame, int read_sp_p)
+ {
+-  CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM);
+-  CORE_ADDR vfp = sp;
++  CORE_ADDR sp;
++  CORE_ADDR vfp;
+   CORE_ADDR cur_pc;
+   int frame_size;
+   int has_frame_reg = 0;
+@@ -607,6 +609,11 @@
+   int pcreg = -1;
+   int regno;
+ 
++  if (read_sp_p)
++    vfp = sp = read_next_frame_reg (next_frame, SP_REGNUM);
++  else
++    vfp = sp = 0;
++
+   if (start_pc == 0)
+     return NULL;
+   memset (&temp_proc_desc, '\0', sizeof (temp_proc_desc));
+@@ -761,7 +768,7 @@
+   CORE_ADDR func_addr, func_end;
+ 
+   if (!proc_desc)
+-    proc_desc = find_proc_desc (pc, NULL);
++    proc_desc = find_proc_desc (pc, NULL, 0);
+ 
+   if (proc_desc)
+     {
+@@ -807,7 +814,7 @@
+ }
+ 
+ static alpha_extra_func_info_t
+-find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame)
++find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame, int read_sp_p)
+ {
+   alpha_extra_func_info_t proc_desc;
+   struct block *b;
+@@ -879,7 +886,7 @@
+ 	    {
+ 	      alpha_extra_func_info_t found_heuristic =
+ 	      heuristic_proc_desc (PROC_LOW_ADDR (proc_desc),
+-				   pc, next_frame);
++				   pc, next_frame, read_sp_p);
+ 	      if (found_heuristic)
+ 		{
+ 		  PROC_LOCALOFF (found_heuristic) =
+@@ -921,7 +928,7 @@
+ 	startaddr = heuristic_proc_start (pc);
+ 
+       proc_desc =
+-	heuristic_proc_desc (startaddr, pc, next_frame);
++	heuristic_proc_desc (startaddr, pc, next_frame, read_sp_p);
+     }
+   return proc_desc;
+ }
+@@ -937,7 +944,7 @@
+   if (saved_pc == 0 || inside_entry_file (saved_pc))
+     return 0;
+ 
+-  proc_desc = find_proc_desc (saved_pc, frame);
++  proc_desc = find_proc_desc (saved_pc, frame, 1);
+   if (!proc_desc)
+     return 0;
+ 
+@@ -979,7 +986,7 @@
+ {
+   /* Use proc_desc calculated in frame_chain */
+   alpha_extra_func_info_t proc_desc =
+-  frame->next ? cached_proc_desc : find_proc_desc (frame->pc, frame->next);
++  frame->next ? cached_proc_desc : find_proc_desc (frame->pc, frame->next, 1);
+ 
+   frame->extra_info = (struct frame_extra_info *)
+     frame_obstack_alloc (sizeof (struct frame_extra_info));
+@@ -1291,7 +1298,7 @@
+   /* we need proc_desc to know how to restore the registers;
+      if it is NULL, construct (a temporary) one */
+   if (proc_desc == NULL)
+-    proc_desc = find_proc_desc (frame->pc, frame->next);
++    proc_desc = find_proc_desc (frame->pc, frame->next, 1);
+ 
+   /* Question: should we copy this proc_desc and save it in
+      frame->proc_desc?  If we do, who will free it?
+Not yet submitted upstream.  This requires some serious thinking about. 
+If the target stack worked in any logical way, this wouldn't be necessary...
+ending up with roughly:
+  thread_stratum: thread-db (silent reference to lin-lwp)
+  core_stratum: corelow
+  exec_stratum: exec
+  dummy_stratum: dummy
+just makes no sense.
+
+This patch fixes debugging threaded applications which are statically linked
+without breaking debugging threaded core files.  It also fixes the PIDs in
+generate-core-file'd corefiles.  Mostly.
+
+diff -x '*~' -ur o/gdb-5.2.debian90.cvs20021120/gdb/corelow.c gdb-5.2.debian90.cvs20021120/gdb/corelow.c
+--- o/gdb-5.2.debian90.cvs20021120/gdb/corelow.c	2002-09-18 13:23:15.000000000 -0400
++++ gdb-5.2.debian90.cvs20021120/gdb/corelow.c	2002-12-03 14:03:32.000000000 -0500
+@@ -350,7 +350,7 @@
+   bfd_map_over_sections (core_bfd, add_to_thread_list,
+ 			 bfd_get_section_by_name (core_bfd, ".reg"));
+ 
+-  if (ontop)
++  if (ontop || 1)
+     {
+       /* Fetch all registers from core file.  */
+       target_fetch_registers (-1);
+diff -x '*~' -ur o/gdb-5.2.debian90.cvs20021120/gdb/linux-proc.c gdb-5.2.debian90.cvs20021120/gdb/linux-proc.c
+--- o/gdb-5.2.debian90.cvs20021120/gdb/linux-proc.c	2002-12-03 14:13:52.000000000 -0500
++++ gdb-5.2.debian90.cvs20021120/gdb/linux-proc.c	2002-12-03 13:56:34.000000000 -0500
+@@ -177,7 +177,7 @@
+ #ifdef FILL_FPXREGSET
+   gdb_fpxregset_t fpxregs;
+ #endif
+-  unsigned long merged_pid = ptid_get_tid (ptid) << 16 | ptid_get_pid (ptid);
++  unsigned long merged_pid = ptid_get_tid (ptid) << 16; /*  | ptid_get_pid (ptid); */
+ 
+   fill_gregset (&gregs, -1);
+   note_data = (char *) elfcore_write_prstatus (obfd, 
+diff -x '*~' -ur o/gdb-5.2.debian90.cvs20021120/gdb/target.c gdb-5.2.debian90.cvs20021120/gdb/target.c
+--- o/gdb-5.2.debian90.cvs20021120/gdb/target.c	2002-09-18 13:23:22.000000000 -0400
++++ gdb-5.2.debian90.cvs20021120/gdb/target.c	2002-12-03 14:06:07.000000000 -0500
+@@ -1589,6 +1589,7 @@
+   dummy_target.to_find_memory_regions = dummy_find_memory_regions;
+   dummy_target.to_make_corefile_notes = dummy_make_corefile_notes;
+   dummy_target.to_magic = OPS_MAGIC;
++  cleanup_target (&dummy_target);
+ }
+ 
+ 
+diff -x '*~' -ur o/gdb-5.2.debian90.cvs20021120/gdb/thread-db.c gdb-5.2.debian90.cvs20021120/gdb/thread-db.c
+--- o/gdb-5.2.debian90.cvs20021120/gdb/thread-db.c	2002-12-03 14:13:50.000000000 -0500
++++ gdb-5.2.debian90.cvs20021120/gdb/thread-db.c	2002-12-03 13:39:54.000000000 -0500
+@@ -57,6 +57,31 @@
+ /* Non-zero if we're using this module's target vector.  */
+ static int using_thread_db;
+ 
++/* Macros to pass an event to the next target if we should not be handling it
++   here in the thread_stratum.  */
++#define FIND_NEXT_TARGET(METHOD_NAME)			\
++  struct target_ops *next_target = &thread_db_ops;	\
++  while (1)						\
++    {							\
++      next_target = find_target_beneath (next_target);	\
++      if (next_target->METHOD_NAME != NULL)		\
++	break;						\
++    }
++
++#define MAYBE_HAND_DOWN(METHOD_NAME,ARGS)		\
++  if (proc_handle.pid == 0)				\
++    {							\
++      FIND_NEXT_TARGET (METHOD_NAME);			\
++      (*next_target->METHOD_NAME) ARGS;			\
++      return;						\
++    }
++#define MAYBE_HAND_DOWN_RETURN(METHOD_NAME,ARGS)	\
++  if (proc_handle.pid == 0)				\
++    {							\
++      FIND_NEXT_TARGET (METHOD_NAME);			\
++      return (*next_target->METHOD_NAME) ARGS;		\
++    }
++
+ /* Non-zero if we have to keep this module's target vector active
+    across re-runs.  */
+ static int keep_thread_db;
+@@ -489,9 +514,7 @@
+ {
+   td_err_e err;
+ 
+-  /* Don't attempt to use thread_db on targets which can not run
+-     (core files).  */
+-  if (objfile == NULL || !target_has_execution)
++  if (objfile == NULL)
+     {
+       /* All symbols have been discarded.  If the thread_db target is
+          active, deactivate it now.  */
+@@ -515,7 +538,10 @@
+   /* Initialize the structure that identifies the child process.  Note
+      that at this point there is no guarantee that we actually have a
+      child process.  */
+-  proc_handle.pid = GET_PID (inferior_ptid);
++  if (target_has_execution)
++    proc_handle.pid = GET_PID (inferior_ptid);
++  else
++    proc_handle.pid = 0;
+ 
+   /* Now attempt to open a connection to the thread library.  */
+   err = td_ta_new_p (&proc_handle, &thread_agent);
+@@ -758,6 +784,9 @@
+   struct cleanup *old_chain = save_inferior_ptid ();
+   int xfer;
+ 
++  MAYBE_HAND_DOWN_RETURN (to_xfer_memory, (memaddr, myaddr, len, write,
++					   attrib, target));
++
+   if (is_thread (inferior_ptid))
+     {
+       /* FIXME: This seems to be necessary to make sure breakpoints
+@@ -782,6 +811,8 @@
+   gdb_prfpregset_t fpregset;
+   td_err_e err;
+ 
++  MAYBE_HAND_DOWN (to_fetch_registers, (regno));
++
+   if (!is_thread (inferior_ptid))
+     {
+       /* Pass the request to the target beneath us.  */
+@@ -819,6 +850,8 @@
+   gdb_prfpregset_t fpregset;
+   td_err_e err;
+ 
++  MAYBE_HAND_DOWN (to_store_registers, (regno));
++
+   if (!is_thread (inferior_ptid))
+     {
+       /* Pass the request to the target beneath us.  */
+@@ -908,6 +941,8 @@
+   td_thrinfo_t ti;
+   td_err_e err;
+ 
++  MAYBE_HAND_DOWN_RETURN (to_thread_alive, (ptid));
++
+   if (is_thread (ptid))
+     {
+       err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th);
+@@ -961,6 +996,8 @@
+ {
+   td_err_e err;
+ 
++  MAYBE_HAND_DOWN (to_find_new_threads, ());
++
+   /* Iterate over all user-space threads to discover new threads.  */
+   err = td_ta_thr_iter_p (thread_agent, find_new_threads_callback, NULL,
+ 			  TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
+@@ -972,6 +1009,8 @@
+ static char *
+ thread_db_pid_to_str (ptid_t ptid)
+ {
++  MAYBE_HAND_DOWN_RETURN (to_pid_to_str, (ptid));
++
+   if (is_thread (ptid))
+     {
+       static char buf[64];
+Trivial.  Need to submit this.
+
+--- gdb-5.2.debian90.cvs20021120/gdb/tracepoint.c.orig	2002-12-03 14:35:44.000000000 -0500
++++ gdb-5.2.debian90.cvs20021120/gdb/tracepoint.c	2002-12-03 14:43:02.000000000 -0500
+@@ -861,6 +861,8 @@
+       else
+ 	line = gdb_readline (0);
+ 
++      if (line == NULL || *line == EOF)
++	break;
+       linetype = validate_actionline (&line, t);
+       if (linetype == BADLINE)
+ 	continue;		/* already warned -- collect another line */
+Fix build on Sparc.
+
+--- gdb-5.3/gdb/sparc-nat.c.orig	2003-01-04 00:11:28.000000000 -0500
++++ gdb-5.3/gdb/sparc-nat.c	2003-01-04 00:12:42.000000000 -0500
+@@ -33,6 +33,13 @@
+ #include <sys/ptrace.h>
+ #include <sys/wait.h>
+ #ifdef __linux__
++/* Sadly, <sys/ucontext.h> conflicts with <asm/reg.h> on Linux.  And
++   -D_GNU_SOURCE brings in <sys/ucontext.h> implicitly with <signal.h>.
++   Hack around this.  */
++#undef FPU_REGS_TYPE
++#define fpu asm_reg_fpu
++#define fq asm_reg_fq
++#define fpq asm_reg_fpq
+ #include <asm/reg.h>
+ #else
+ #include <machine/reg.h>