Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 8 Jan 2021 20:14:49 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r560808 - in head/devel/gdb: . files/kgdb
Message-ID:  <202101082014.108KEn2B081605@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb (src,doc committer)
Date: Fri Jan  8 20:14:49 2021
New Revision: 560808
URL: https://svnweb.freebsd.org/changeset/ports/560808

Log:
  Fix a couple of issues in kgdb.
  
  - Properly unwind across in-kernel exceptions on arm.
  
  - Enumerate processes via the pid hash table for kernels without the
    zombproc list.
  
  PR:		251463 (1)
  Reviewed by:	pizzamig (maintainer)
  Differential Revision:	https://reviews.freebsd.org/D27849

Modified:
  head/devel/gdb/Makefile
  head/devel/gdb/files/kgdb/arm-fbsd-kern.c
  head/devel/gdb/files/kgdb/fbsd-kthr.c

Modified: head/devel/gdb/Makefile
==============================================================================
--- head/devel/gdb/Makefile	Fri Jan  8 19:42:42 2021	(r560807)
+++ head/devel/gdb/Makefile	Fri Jan  8 20:14:49 2021	(r560808)
@@ -3,7 +3,7 @@
 
 PORTNAME=	gdb
 PORTVERSION=	10.1
-PORTREVISION=	0
+PORTREVISION=	1
 CATEGORIES=	devel
 MASTER_SITES=	GNU
 

Modified: head/devel/gdb/files/kgdb/arm-fbsd-kern.c
==============================================================================
--- head/devel/gdb/files/kgdb/arm-fbsd-kern.c	Fri Jan  8 19:42:42 2021	(r560807)
+++ head/devel/gdb/files/kgdb/arm-fbsd-kern.c	Fri Jan  8 20:14:49 2021	(r560808)
@@ -73,12 +73,16 @@ arm_fbsd_supply_pcb(struct regcache *regcache, CORE_AD
   regcache->raw_supply_unsigned(ARM_PS_REGNUM, 0);
 }
 
+#define PSR_MODE        0x0000001f      /* mode mask */
+#define PSR_USR32_MODE  0x00000010
+
 static struct trad_frame_cache *
 arm_fbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct trad_frame_cache *cache;
+  uint32_t psr;
   CORE_ADDR func, pc, sp;
   const char *name;
   int i;
@@ -94,10 +98,21 @@ arm_fbsd_trapframe_cache (struct frame_info *this_fram
 
   find_pc_partial_function (func, &name, NULL, NULL);
 
+  /* Read $PSR to determine where SP and LR are. */
+  psr = read_memory_unsigned_integer (sp, 4, byte_order);
+
   for (i = 0; i <= 12; i++)
     trad_frame_set_reg_addr (cache, ARM_A1_REGNUM + i, sp + 4 + i * 4);
-  trad_frame_set_reg_addr (cache, ARM_SP_REGNUM, sp + 14 * 4);
-  trad_frame_set_reg_addr (cache, ARM_LR_REGNUM, sp + 15 * 4);
+  if ((psr & PSR_MODE) == PSR_USR32_MODE)
+    {
+      trad_frame_set_reg_addr (cache, ARM_SP_REGNUM, sp + 14 * 4);
+      trad_frame_set_reg_addr (cache, ARM_LR_REGNUM, sp + 15 * 4);
+    }
+  else
+    {
+      trad_frame_set_reg_addr (cache, ARM_SP_REGNUM, sp + 16 * 4);
+      trad_frame_set_reg_addr (cache, ARM_LR_REGNUM, sp + 17 * 4);
+    }
   trad_frame_set_reg_addr (cache, ARM_PC_REGNUM, sp + 18 * 4);
   trad_frame_set_reg_addr (cache, ARM_PS_REGNUM, sp);
 

Modified: head/devel/gdb/files/kgdb/fbsd-kthr.c
==============================================================================
--- head/devel/gdb/files/kgdb/fbsd-kthr.c	Fri Jan  8 19:42:42 2021	(r560807)
+++ head/devel/gdb/files/kgdb/fbsd-kthr.c	Fri Jan  8 20:14:49 2021	(r560808)
@@ -22,16 +22,15 @@
  * 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$
  */
 
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
 #include <sys/param.h>
 #include <sys/proc.h>
 #include <stdbool.h>
 
-#include <defs.h>
+#include "defs.h"
 #include "gdbcore.h"
 #include "objfiles.h"
 #include "value.h"
@@ -47,7 +46,8 @@ static LONGEST mp_maxid;
 static struct kthr *first, *last;
 struct kthr *curkthr;
 
-static int proc_off_p_pid, proc_off_p_comm, proc_off_p_list, proc_off_p_threads;
+static int proc_off_p_pid, proc_off_p_comm, proc_off_p_hash, proc_off_p_list;
+static int proc_off_p_threads;
 static int thread_off_td_tid, thread_off_td_oncpu, thread_off_td_pcb;
 static int thread_off_td_name, thread_off_td_plist;
 static int thread_oncpu_size;
@@ -95,61 +95,105 @@ kgdb_thr_first(void)
 }
 
 static void
-kgdb_thr_add_procs(CORE_ADDR paddr, CORE_ADDR (*cpu_pcb_addr) (u_int))
+kgdb_thr_add_proc(CORE_ADDR paddr, CORE_ADDR (*cpu_pcb_addr) (u_int))
 {
 	struct gdbarch *gdbarch = target_gdbarch ();
 	struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
 	enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 	struct kthr *kt;
-	CORE_ADDR pcb, pnext, tdaddr, tdnext;
+	CORE_ADDR pcb, tdaddr, tdnext;
 	ULONGEST oncpu;
 	LONGEST pid, tid;
 
-	while (paddr != 0) {
+	try {
+		tdaddr = read_memory_typed_address (paddr + proc_off_p_threads,
+		    ptr_type);
+		pid = read_memory_integer (paddr + proc_off_p_pid, 4, byte_order);
+	} catch (const gdb_exception_error &e) {
+		return;
+	}
+
+	while (tdaddr != 0) {
 		try {
-			tdaddr = read_memory_typed_address (paddr +
-			    proc_off_p_threads, ptr_type);
-			pid = read_memory_integer (paddr + proc_off_p_pid, 4,
-			    byte_order);
-			pnext = read_memory_typed_address (paddr +
-			    proc_off_p_list, ptr_type);
+			tid = read_memory_integer (tdaddr + thread_off_td_tid,
+			    4, byte_order);
+			oncpu = read_memory_unsigned_integer (tdaddr +
+			    thread_off_td_oncpu, thread_oncpu_size, byte_order);
+			pcb = read_memory_typed_address (tdaddr +
+			    thread_off_td_pcb, ptr_type);
+			tdnext = read_memory_typed_address (tdaddr +
+			    thread_off_td_plist, ptr_type);
 		} catch (const gdb_exception_error &e) {
-			break;
+			return;
 		}
-		while (tdaddr != 0) {
+		kt = XNEW (struct kthr);
+		if (last == NULL)
+			first = last = kt;
+		else
+			last->next = kt;
+		kt->next = NULL;
+		kt->kaddr = tdaddr;
+		if (tid == dumptid)
+			kt->pcb = dumppcb;
+		else if (cpu_stopped(oncpu))
+			kt->pcb = cpu_pcb_addr(oncpu);
+		else
+			kt->pcb = pcb;
+		kt->tid = tid;
+		kt->pid = pid;
+		kt->paddr = paddr;
+		kt->cpu = oncpu;
+		last = kt;
+		tdaddr = tdnext;
+	}
+}
+
+static void
+kgdb_thr_add_procs_hash(CORE_ADDR pidhashtbl, CORE_ADDR (*cpu_pcb_addr) (u_int))
+{
+	struct gdbarch *gdbarch = target_gdbarch ();
+	struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
+	enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+	CORE_ADDR paddr, pnext;
+	ULONGEST i, pidhash;
+
+	pidhash = parse_and_eval_long("pidhash");
+	for (i = 0; i < pidhash; i++) {
+		try {
+			paddr = read_memory_typed_address (pidhashtbl +
+			    i * TYPE_LENGTH(ptr_type), ptr_type);
+		} catch (const gdb_exception_error &e) {
+			continue;
+		}
+		while (paddr != 0) {
 			try {
-				tid = read_memory_integer (tdaddr +
-				    thread_off_td_tid, 4, byte_order);
-				oncpu = read_memory_unsigned_integer (tdaddr +
-				    thread_off_td_oncpu, thread_oncpu_size,
-				    byte_order);
-				pcb = read_memory_typed_address (tdaddr +
-				    thread_off_td_pcb, ptr_type);
-				tdnext = read_memory_typed_address (tdaddr +
-				    thread_off_td_plist, ptr_type);
+				pnext = read_memory_typed_address (paddr +
+				    proc_off_p_hash, ptr_type);
 			} catch (const gdb_exception_error &e) {
 				break;
 			}
-			kt = XNEW (struct kthr);
-			if (last == NULL)
-				first = last = kt;
-			else
-				last->next = kt;
-			kt->next = NULL;
-			kt->kaddr = tdaddr;
-			if (tid == dumptid)
-				kt->pcb = dumppcb;
-			else if (cpu_stopped(oncpu))
-				kt->pcb = cpu_pcb_addr(oncpu);
-			else
-				kt->pcb = pcb;
-			kt->tid = tid;
-			kt->pid = pid;
-			kt->paddr = paddr;
-			kt->cpu = oncpu;
-			last = kt;
-			tdaddr = tdnext;
+			kgdb_thr_add_proc(paddr, cpu_pcb_addr);
+			paddr = pnext;
 		}
+	}
+}
+
+static void
+kgdb_thr_add_procs_list(CORE_ADDR paddr, CORE_ADDR (*cpu_pcb_addr) (u_int))
+{
+	struct gdbarch *gdbarch = target_gdbarch ();
+	struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
+	enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+	CORE_ADDR pnext;
+
+	while (paddr != 0) {
+		try {
+			pnext = read_memory_typed_address (paddr +
+			    proc_off_p_list, ptr_type);
+		} catch (const gdb_exception_error &e) {
+			break;
+		}
+		kgdb_thr_add_proc(paddr, cpu_pcb_addr);
 		paddr = pnext;
 	}
 }
@@ -169,15 +213,6 @@ kgdb_thr_init(CORE_ADDR (*cpu_pcb_addr) (u_int))
 	}
 	last = NULL;
 
-	addr = kgdb_lookup("allproc");
-	if (addr == 0)
-		return (NULL);
-	try {
-		paddr = read_memory_typed_address (addr, ptr_type);
-	} catch (const gdb_exception_error &e) {
-		return (NULL);
-	}
-
 	dumppcb = kgdb_lookup("dumppcb");
 	if (dumppcb == 0)
 		return (NULL);
@@ -272,13 +307,49 @@ kgdb_thr_init(CORE_ADDR (*cpu_pcb_addr) (u_int))
 		}
 	}
 
-	kgdb_thr_add_procs(paddr, cpu_pcb_addr);
+	/*
+	 * Handle p_hash separately.
+	 */
+	try {
+		proc_off_p_hash = parse_and_eval_long("proc_off_p_hash");
+	} catch (const gdb_exception_error &e) {
+		try {
+			struct symbol *proc_sym =
+			    lookup_symbol_in_language ("struct proc", NULL,
+				STRUCT_DOMAIN, language_c, NULL).symbol;
+			if (proc_sym == NULL)
+				error (_("Unable to find struct proc symbol"));
+
+			proc_off_p_hash =
+			    lookup_struct_elt (SYMBOL_TYPE (proc_sym), "p_hash",
+				0).offset / 8;
+		} catch (const gdb_exception_error &e2) {
+			proc_off_p_hash = offsetof(struct proc, p_hash);
+		}
+	}
+
 	addr = kgdb_lookup("zombproc");
 	if (addr != 0) {
+		addr = kgdb_lookup("allproc");
 		try {
 			paddr = read_memory_typed_address (addr, ptr_type);
-			kgdb_thr_add_procs(paddr, cpu_pcb_addr);
+			kgdb_thr_add_procs_list(paddr, cpu_pcb_addr);
 		} catch (const gdb_exception_error &e) {
+			return (NULL);
+		}
+
+		try {
+			paddr = read_memory_typed_address (addr, ptr_type);
+			kgdb_thr_add_procs_list(paddr, cpu_pcb_addr);
+		} catch (const gdb_exception_error &e) {
+		}
+	} else {
+		addr = kgdb_lookup("pidhashtbl");
+		try {
+			addr = read_memory_typed_address (addr, ptr_type);
+			kgdb_thr_add_procs_hash(addr, cpu_pcb_addr);
+		} catch (const gdb_exception_error &e) {
+			return (NULL);
 		}
 	}
 	curkthr = kgdb_thr_lookup_tid(dumptid);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202101082014.108KEn2B081605>