summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2001-04-09 21:43:45 +0000
committerjhb <jhb@FreeBSD.org>2001-04-09 21:43:45 +0000
commitcd92f5e07a06ee13792a974210d5111b5cee25aa (patch)
tree85ea84b307d7ea9546eac0416d43b95f3fbdfac0
parent179a4916c8446b0872d547329066e18c2164af70 (diff)
downloadFreeBSD-src-cd92f5e07a06ee13792a974210d5111b5cee25aa.zip
FreeBSD-src-cd92f5e07a06ee13792a974210d5111b5cee25aa.tar.gz
- One can now specify the decimal pid of a process to trace as a parameter.
Since pid's are not in the kernel address space, this doesn't conflict with the funcionality of specifying an arbitrary frame pointer to the trace command. - If the first function of a backtrace maps to fork_trampoline, then this is a newly fork'd process that has not been executed yet, so just print out the first frame and then return for that case. - Lower the default count from 65535 to 1024. ddb doesn't trace into userland, and if the stack gets hosed and starts looping it's less annoying.
-rw-r--r--sys/amd64/amd64/db_trace.c98
-rw-r--r--sys/i386/i386/db_trace.c98
2 files changed, 146 insertions, 50 deletions
diff --git a/sys/amd64/amd64/db_trace.c b/sys/amd64/amd64/db_trace.c
index 682a644..af02d94 100644
--- a/sys/amd64/amd64/db_trace.c
+++ b/sys/amd64/amd64/db_trace.c
@@ -28,6 +28,9 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/linker_set.h>
+#include <sys/proc.h>
+#include <sys/user.h>
#include <machine/cpu.h>
@@ -240,15 +243,51 @@ db_stack_trace_cmd(addr, have_addr, count, modif)
int *argp;
db_addr_t callpc;
boolean_t first;
+ struct pcb *pcb;
+ struct proc *p;
+ pid_t pid;
if (count == -1)
- count = 65535;
+ count = 1024;
if (!have_addr) {
frame = (struct i386_frame *)ddb_regs.tf_ebp;
if (frame == NULL)
frame = (struct i386_frame *)(ddb_regs.tf_esp - 4);
callpc = (db_addr_t)ddb_regs.tf_eip;
+ } else if (!INKERNEL(addr)) {
+ pid = (addr % 16) + ((addr >> 4) % 16) * 10 +
+ ((addr >> 8) % 16) * 100 + ((addr >> 12) % 16) * 1000 +
+ ((addr >> 16) % 16) * 10000;
+ /*
+ * The pcb for curproc is not valid at this point,
+ * so fall back to the default case.
+ */
+ if (pid == curproc->p_pid) {
+ frame = (struct i386_frame *)ddb_regs.tf_ebp;
+ if (frame == NULL)
+ frame = (struct i386_frame *)
+ (ddb_regs.tf_esp - 4);
+ callpc = (db_addr_t)ddb_regs.tf_eip;
+ } else {
+
+ /* sx_slock(&allproc_lock); */
+ LIST_FOREACH(p, &allproc, p_list) {
+ if (p->p_pid == pid)
+ break;
+ }
+ /* sx_sunlock(&allproc_lock); */
+ if (p == NULL) {
+ db_printf("pid %d not found\n", pid);
+ return;
+ }
+ pcb = &p->p_addr->u_pcb;
+ frame = (struct i386_frame *)pcb->pcb_ebp;
+ if (frame == NULL)
+ frame = (struct i386_frame *)
+ (pcb->pcb_esp - 4);
+ callpc = (db_addr_t)pcb->pcb_eip;
+ }
} else {
frame = (struct i386_frame *)addr;
callpc = (db_addr_t)db_get_value((int)&frame->f_retaddr, 4, FALSE);
@@ -279,33 +318,42 @@ db_stack_trace_cmd(addr, have_addr, count, modif)
* db_nextframe() works because the `next' pc is special).
*/
actframe = frame;
- if (first && !have_addr) {
- int instr;
-
- instr = db_get_value(callpc, 4, FALSE);
- if ((instr & 0x00ffffff) == 0x00e58955) {
- /* pushl %ebp; movl %esp, %ebp */
- actframe = (struct i386_frame *)
- (ddb_regs.tf_esp - 4);
- } else if ((instr & 0x0000ffff) == 0x0000e589) {
- /* movl %esp, %ebp */
- actframe = (struct i386_frame *)
- ddb_regs.tf_esp;
- if (ddb_regs.tf_ebp == 0) {
- /* Fake the caller's frame better. */
- frame = actframe;
+ if (first) {
+ if (!have_addr) {
+ int instr;
+
+ instr = db_get_value(callpc, 4, FALSE);
+ if ((instr & 0x00ffffff) == 0x00e58955) {
+ /* pushl %ebp; movl %esp, %ebp */
+ actframe = (struct i386_frame *)
+ (ddb_regs.tf_esp - 4);
+ } else if ((instr & 0x0000ffff) == 0x0000e589) {
+ /* movl %esp, %ebp */
+ actframe = (struct i386_frame *)
+ ddb_regs.tf_esp;
+ if (ddb_regs.tf_ebp == 0) {
+ /* Fake caller's frame better. */
+ frame = actframe;
+ }
+ } else if ((instr & 0x000000ff) == 0x000000c3) {
+ /* ret */
+ actframe = (struct i386_frame *)
+ (ddb_regs.tf_esp - 4);
+ } else if (offset == 0) {
+ /* Probably a symbol in assembler code. */
+ actframe = (struct i386_frame *)
+ (ddb_regs.tf_esp - 4);
}
- } else if ((instr & 0x000000ff) == 0x000000c3) {
- /* ret */
- actframe = (struct i386_frame *)
- (ddb_regs.tf_esp - 4);
- } else if (offset == 0) {
- /* Probably a symbol in assembler code. */
- actframe = (struct i386_frame *)
- (ddb_regs.tf_esp - 4);
+ } else if (!strcmp(name, "fork_trampoline")) {
+ /*
+ * Don't try to walk back on a stack for a
+ * process that hasn't actually been run yet.
+ */
+ db_print_stack_entry(name, 0, 0, 0, callpc);
+ break;
}
+ first = FALSE;
}
- first = FALSE;
argp = &actframe->f_arg0;
narg = MAXNARG;
diff --git a/sys/i386/i386/db_trace.c b/sys/i386/i386/db_trace.c
index 682a644..af02d94 100644
--- a/sys/i386/i386/db_trace.c
+++ b/sys/i386/i386/db_trace.c
@@ -28,6 +28,9 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/linker_set.h>
+#include <sys/proc.h>
+#include <sys/user.h>
#include <machine/cpu.h>
@@ -240,15 +243,51 @@ db_stack_trace_cmd(addr, have_addr, count, modif)
int *argp;
db_addr_t callpc;
boolean_t first;
+ struct pcb *pcb;
+ struct proc *p;
+ pid_t pid;
if (count == -1)
- count = 65535;
+ count = 1024;
if (!have_addr) {
frame = (struct i386_frame *)ddb_regs.tf_ebp;
if (frame == NULL)
frame = (struct i386_frame *)(ddb_regs.tf_esp - 4);
callpc = (db_addr_t)ddb_regs.tf_eip;
+ } else if (!INKERNEL(addr)) {
+ pid = (addr % 16) + ((addr >> 4) % 16) * 10 +
+ ((addr >> 8) % 16) * 100 + ((addr >> 12) % 16) * 1000 +
+ ((addr >> 16) % 16) * 10000;
+ /*
+ * The pcb for curproc is not valid at this point,
+ * so fall back to the default case.
+ */
+ if (pid == curproc->p_pid) {
+ frame = (struct i386_frame *)ddb_regs.tf_ebp;
+ if (frame == NULL)
+ frame = (struct i386_frame *)
+ (ddb_regs.tf_esp - 4);
+ callpc = (db_addr_t)ddb_regs.tf_eip;
+ } else {
+
+ /* sx_slock(&allproc_lock); */
+ LIST_FOREACH(p, &allproc, p_list) {
+ if (p->p_pid == pid)
+ break;
+ }
+ /* sx_sunlock(&allproc_lock); */
+ if (p == NULL) {
+ db_printf("pid %d not found\n", pid);
+ return;
+ }
+ pcb = &p->p_addr->u_pcb;
+ frame = (struct i386_frame *)pcb->pcb_ebp;
+ if (frame == NULL)
+ frame = (struct i386_frame *)
+ (pcb->pcb_esp - 4);
+ callpc = (db_addr_t)pcb->pcb_eip;
+ }
} else {
frame = (struct i386_frame *)addr;
callpc = (db_addr_t)db_get_value((int)&frame->f_retaddr, 4, FALSE);
@@ -279,33 +318,42 @@ db_stack_trace_cmd(addr, have_addr, count, modif)
* db_nextframe() works because the `next' pc is special).
*/
actframe = frame;
- if (first && !have_addr) {
- int instr;
-
- instr = db_get_value(callpc, 4, FALSE);
- if ((instr & 0x00ffffff) == 0x00e58955) {
- /* pushl %ebp; movl %esp, %ebp */
- actframe = (struct i386_frame *)
- (ddb_regs.tf_esp - 4);
- } else if ((instr & 0x0000ffff) == 0x0000e589) {
- /* movl %esp, %ebp */
- actframe = (struct i386_frame *)
- ddb_regs.tf_esp;
- if (ddb_regs.tf_ebp == 0) {
- /* Fake the caller's frame better. */
- frame = actframe;
+ if (first) {
+ if (!have_addr) {
+ int instr;
+
+ instr = db_get_value(callpc, 4, FALSE);
+ if ((instr & 0x00ffffff) == 0x00e58955) {
+ /* pushl %ebp; movl %esp, %ebp */
+ actframe = (struct i386_frame *)
+ (ddb_regs.tf_esp - 4);
+ } else if ((instr & 0x0000ffff) == 0x0000e589) {
+ /* movl %esp, %ebp */
+ actframe = (struct i386_frame *)
+ ddb_regs.tf_esp;
+ if (ddb_regs.tf_ebp == 0) {
+ /* Fake caller's frame better. */
+ frame = actframe;
+ }
+ } else if ((instr & 0x000000ff) == 0x000000c3) {
+ /* ret */
+ actframe = (struct i386_frame *)
+ (ddb_regs.tf_esp - 4);
+ } else if (offset == 0) {
+ /* Probably a symbol in assembler code. */
+ actframe = (struct i386_frame *)
+ (ddb_regs.tf_esp - 4);
}
- } else if ((instr & 0x000000ff) == 0x000000c3) {
- /* ret */
- actframe = (struct i386_frame *)
- (ddb_regs.tf_esp - 4);
- } else if (offset == 0) {
- /* Probably a symbol in assembler code. */
- actframe = (struct i386_frame *)
- (ddb_regs.tf_esp - 4);
+ } else if (!strcmp(name, "fork_trampoline")) {
+ /*
+ * Don't try to walk back on a stack for a
+ * process that hasn't actually been run yet.
+ */
+ db_print_stack_entry(name, 0, 0, 0, callpc);
+ break;
}
+ first = FALSE;
}
- first = FALSE;
argp = &actframe->f_arg0;
narg = MAXNARG;
OpenPOWER on IntegriCloud