summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2005-03-31 02:53:49 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2005-03-31 02:53:49 +0000
commit173ca87ff276e5c2b7f182890fa4a0dc80ece156 (patch)
tree5230102dbd1cb87cb81020b19e4c1dc9988640de /sys
parent1fb6ba8d217a278d995a3169f6b8413ee5bb0b8a (diff)
go back to the old trace code, but add -fno-omit-frame-pointer so it works.
makes trace output more reasonable. ok andreas
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/amd64/amd64/db_interface.c56
-rw-r--r--sys/arch/amd64/amd64/db_trace.c526
-rw-r--r--sys/arch/amd64/conf/Makefile.amd644
3 files changed, 383 insertions, 203 deletions
diff --git a/sys/arch/amd64/amd64/db_interface.c b/sys/arch/amd64/amd64/db_interface.c
index 2d591a51d78..8178503a51f 100644
--- a/sys/arch/amd64/amd64/db_interface.c
+++ b/sys/arch/amd64/amd64/db_interface.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: db_interface.c,v 1.4 2004/08/02 20:45:42 andreas Exp $ */
+/* $OpenBSD: db_interface.c,v 1.5 2005/03/31 02:53:48 tedu Exp $ */
/* $NetBSD: db_interface.c,v 1.1 2003/04/26 18:39:27 fvdl Exp $ */
/*
@@ -53,7 +53,6 @@
#include <ddb/db_command.h>
#include <ddb/db_extern.h>
#include <ddb/db_access.h>
-#include <ddb/db_variables.h>
#include <ddb/db_output.h>
#include <ddb/db_var.h>
@@ -74,59 +73,6 @@ long db_switch_to_cpu;
int db_active;
db_regs_t ddb_regs;
-#define dbreg(xx) (long *)offsetof(db_regs_t, tf_ ## xx)
-
-static int db_x86_64_regop(struct db_variable *, db_expr_t *, int);
-
-struct db_variable db_regs[] = {
- { "ds", dbreg(ds), db_x86_64_regop },
- { "es", dbreg(es), db_x86_64_regop },
- { "fs", dbreg(fs), db_x86_64_regop },
- { "gs", dbreg(gs), db_x86_64_regop },
- { "rdi", dbreg(rdi), db_x86_64_regop },
- { "rsi", dbreg(rsi), db_x86_64_regop },
- { "rbp", dbreg(rbp), db_x86_64_regop },
- { "rbx", dbreg(rbx), db_x86_64_regop },
- { "rdx", dbreg(rdx), db_x86_64_regop },
- { "rcx", dbreg(rcx), db_x86_64_regop },
- { "rax", dbreg(rax), db_x86_64_regop },
- { "r8", dbreg(r8), db_x86_64_regop },
- { "r9", dbreg(r9), db_x86_64_regop },
- { "r10", dbreg(r10), db_x86_64_regop },
- { "r11", dbreg(r11), db_x86_64_regop },
- { "r12", dbreg(r12), db_x86_64_regop },
- { "r13", dbreg(r13), db_x86_64_regop },
- { "r14", dbreg(r14), db_x86_64_regop },
- { "r15", dbreg(r15), db_x86_64_regop },
- { "rip", dbreg(rip), db_x86_64_regop },
- { "cs", dbreg(cs), db_x86_64_regop },
- { "rflags", dbreg(rflags), db_x86_64_regop },
- { "rsp", dbreg(rsp), db_x86_64_regop },
- { "ss", dbreg(ss), db_x86_64_regop },
-};
-
-struct db_variable * db_eregs =
- db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
-
-static int
-db_x86_64_regop(struct db_variable *vp, db_expr_t *val, int opcode)
-{
- db_expr_t *regaddr =
- (db_expr_t *)(((uint8_t *)DDB_REGS) + ((size_t)vp->valuep));
-
- switch (opcode) {
- case DB_VAR_GET:
- *val = *regaddr;
- break;
- case DB_VAR_SET:
- *regaddr = *val;
- break;
- default:
- panic("db_x86_64_regop: unknown op %d", opcode);
- }
- return 0;
-}
-
void kdbprinttrap(int, int);
#ifdef MULTIPROCESSOR
void db_cpuinfo_cmd(db_expr_t, int, db_expr_t, char *);
diff --git a/sys/arch/amd64/amd64/db_trace.c b/sys/arch/amd64/amd64/db_trace.c
index e9f71d3e30f..e577d767bd8 100644
--- a/sys/arch/amd64/amd64/db_trace.c
+++ b/sys/arch/amd64/amd64/db_trace.c
@@ -1,178 +1,412 @@
-/* $OpenBSD: db_trace.c,v 1.2 2004/08/02 20:45:42 andreas Exp $ */
+/* $OpenBSD: db_trace.c,v 1.3 2005/03/31 02:53:48 tedu Exp $ */
+/* $NetBSD: db_trace.c,v 1.1 2003/04/26 18:39:27 fvdl Exp $ */
-/*
- * Copyright (c) 2004 Andreas Gunnarsson <andreas@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
*/
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+
#include <machine/db_machdep.h>
+#include <machine/frame.h>
+#include <machine/trap.h>
+
#include <ddb/db_sym.h>
#include <ddb/db_access.h>
+#include <ddb/db_variables.h>
+#include <ddb/db_output.h>
#include <ddb/db_interface.h>
-extern char end[];
-extern unsigned int db_maxoff;
+#if 1
+#define dbreg(xx) (long *)offsetof(db_regs_t, tf_ ## xx)
+#else
+#define dbreg(xx) (long *)&ddb_regs.tf_ ## xx
+#endif
+
+static int db_x86_64_regop(struct db_variable *, db_expr_t *, int);
-db_addr_t db_findcaller(db_addr_t, db_addr_t, char **name, db_expr_t *);
-int db_endtrace(db_addr_t);
+/*
+ * Machine register set.
+ */
+struct db_variable db_regs[] = {
+ { "ds", dbreg(ds), db_x86_64_regop },
+ { "es", dbreg(es), db_x86_64_regop },
+ { "fs", dbreg(fs), db_x86_64_regop },
+ { "gs", dbreg(gs), db_x86_64_regop },
+ { "rdi", dbreg(rdi), db_x86_64_regop },
+ { "rsi", dbreg(rsi), db_x86_64_regop },
+ { "rbp", dbreg(rbp), db_x86_64_regop },
+ { "rbx", dbreg(rbx), db_x86_64_regop },
+ { "rdx", dbreg(rdx), db_x86_64_regop },
+ { "rcx", dbreg(rcx), db_x86_64_regop },
+ { "rax", dbreg(rax), db_x86_64_regop },
+ { "r8", dbreg(r8), db_x86_64_regop },
+ { "r9", dbreg(r9), db_x86_64_regop },
+ { "r10", dbreg(r10), db_x86_64_regop },
+ { "r11", dbreg(r11), db_x86_64_regop },
+ { "r12", dbreg(r12), db_x86_64_regop },
+ { "r13", dbreg(r13), db_x86_64_regop },
+ { "r14", dbreg(r14), db_x86_64_regop },
+ { "r15", dbreg(r15), db_x86_64_regop },
+ { "rip", dbreg(rip), db_x86_64_regop },
+ { "cs", dbreg(cs), db_x86_64_regop },
+ { "rflags", dbreg(rflags), db_x86_64_regop },
+ { "rsp", dbreg(rsp), db_x86_64_regop },
+ { "ss", dbreg(ss), db_x86_64_regop },
+};
+struct db_variable * db_eregs =
+ db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
-db_addr_t
-db_findcaller(db_addr_t sp, db_addr_t ip, char **name, db_expr_t *offset)
+static int
+db_x86_64_regop(struct db_variable *vp, db_expr_t *val, int opcode)
{
- db_addr_t previp;
- db_addr_t called_addr = 0;
- db_expr_t value;
- db_sym_t sym;
- unsigned char callinstr;
- int calloffs;
- short scalloffs;
-
- if (*(char **)sp < (char *)VM_MIN_KERNEL_ADDRESS || *(char **)sp >= end)
- return 0;
-
- sym = db_search_symbol((db_addr_t)*(char **)sp, DB_STGY_PROC, offset);
- db_symbol_values(sym, name, &value);
- if (!*name || *offset > db_maxoff || !value)
- return 0;
-
- /* Check for call with 32 bit relative displacement */
- /* e8 xx xx xx xx */
- previp = (db_addr_t)*(char **)sp - 5;
- callinstr = db_get_value(previp, 1, 0);
- if (callinstr == 0xe8) {
- calloffs = db_get_value(previp + 1, 4, 1);
- called_addr = previp + 5 + calloffs;
- goto found;
- }
+ db_expr_t *regaddr =
+ (db_expr_t *)(((uint8_t *)DDB_REGS) + ((size_t)vp->valuep));
+
+ switch (opcode) {
+ case DB_VAR_GET:
+ *val = *regaddr;
+ break;
+ case DB_VAR_SET:
+ *regaddr = *val;
+ break;
+ default:
+ panic("db_x86_64_regop: unknown op %d", opcode);
+ }
+ return 0;
+}
- /* Check for call with 16 bit relative displacement */
- /* 66 e8 xx xx */
- previp = (db_addr_t)*(char **)sp - 4;
- callinstr = db_get_value(previp, 1, 0);
- if (callinstr == 0x66) {
- callinstr = db_get_value(previp + 1, 1, 0);
- if (callinstr == 0xe8) {
- scalloffs = db_get_value(previp + 2, 2, 1);
- called_addr = previp + 4 + scalloffs;
- goto found;
- }
- }
+/*
+ * Stack trace.
+ */
+#define INKERNEL(va) (((vaddr_t)(va)) >= VM_MIN_KERNEL_ADDRESS)
- /* Check for call with reg/mem */
- previp = (db_addr_t)*(char **)sp - 2;
- callinstr = db_get_value(previp, 1, 0);
- if (callinstr == 0xff) {
- callinstr = db_get_value(previp + 1, 1, 0);
- if (((callinstr & 0xf8) == 0x10 || (callinstr & 0xf8) == 0xd0) &&
- callinstr != 0x15) {
- goto found;
- }
- }
+struct x86_64_frame {
+ struct x86_64_frame *f_frame;
+ long f_retaddr;
+ long f_arg0;
+};
- previp = (db_addr_t)*(char **)sp - 3;
- callinstr = db_get_value(previp, 1, 0);
- if (callinstr == 0xff) {
- callinstr = db_get_value(previp + 1, 1, 0);
- if ((callinstr & 0xf8) == 0x50) {
- goto found;
- }
- }
+#define NONE 0
+#define TRAP 1
+#define SYSCALL 2
+#define INTERRUPT 3
- previp = (db_addr_t)*(char **)sp - 6;
- callinstr = db_get_value(previp, 1, 0);
- if (callinstr == 0xff) {
- callinstr = db_get_value(previp + 1, 1, 0);
- if (callinstr == 0x15 || (callinstr & 0xf8) == 0x90) {
- goto found;
- }
- }
+db_addr_t db_trap_symbol_value = 0;
+db_addr_t db_syscall_symbol_value = 0;
+db_addr_t db_kdintr_symbol_value = 0;
+boolean_t db_trace_symbols_found = FALSE;
- /* Value on stack doesn't seem to be a return address */
- return 0;
+void db_find_trace_symbols(void);
+int db_numargs(struct x86_64_frame *);
+void db_nextframe(struct x86_64_frame **, db_addr_t *, long *, int,
+ int (*) (const char *, ...));
-found:
- if (called_addr) {
- sym = db_search_symbol(called_addr, DB_STGY_PROC, offset);
- } else {
- sym = db_search_symbol(ip, DB_STGY_PROC, offset);
- *offset = 0;
- }
- db_symbol_values(sym, name, &value);
- if (!*name || *offset > db_maxoff || !value)
- return 0;
- return previp;
+void
+db_find_trace_symbols()
+{
+ db_expr_t value;
+
+ if (db_value_of_name("_trap", &value))
+ db_trap_symbol_value = (db_addr_t) value;
+ if (db_value_of_name("_kdintr", &value))
+ db_kdintr_symbol_value = (db_addr_t) value;
+ if (db_value_of_name("_syscall", &value))
+ db_syscall_symbol_value = (db_addr_t) value;
+ db_trace_symbols_found = TRUE;
}
+/*
+ * Figure out how many arguments were passed into the frame at "fp".
+ * We can probably figure out how many arguments where passed above
+ * the first 6 (which are in registers), but since we can't
+ * reliably determine the values currently, just return 0.
+ */
int
-db_endtrace(db_addr_t ip)
+db_numargs(fp)
+ struct x86_64_frame *fp;
{
- db_expr_t offset, value;
- db_sym_t sym;
- char *name;
-
- sym = db_search_symbol(ip, DB_STGY_PROC, &offset);
- db_symbol_values(sym, &name, &value);
- if (!name || offset > db_maxoff || !value)
- return 1;
- if (!strcmp(name, "trap") ||
- !strcmp(name, "syscall") ||
- !strncmp(name, "Xintr", 5) ||
- !strncmp(name, "Xresume", 7) ||
- !strncmp(name, "Xstray", 6) ||
- !strncmp(name, "Xhold", 5) ||
- !strncmp(name, "Xrecurse", 8) ||
- !strcmp(name, "Xdoreti") ||
- !strncmp(name, "Xsoft", 5)) {
- return 1;
- }
return 0;
}
+/*
+ * Figure out the next frame up in the call stack.
+ * For trap(), we print the address of the faulting instruction and
+ * proceed with the calling frame. We return the ip that faulted.
+ * If the trap was caused by jumping through a bogus pointer, then
+ * the next line in the backtrace will list some random function as
+ * being called. It should get the argument list correct, though.
+ * It might be possible to dig out from the next frame up the name
+ * of the function that faulted, but that could get hairy.
+ */
void
-db_stack_trace_print(db_expr_t addr, boolean_t have_addr, db_expr_t count,
- char *modif, int (*pr)(const char *, ...))
+db_nextframe(fp, ip, argp, is_trap, pr)
+ struct x86_64_frame **fp; /* in/out */
+ db_addr_t *ip; /* out */
+ long *argp; /* in */
+ int is_trap; /* in */
+ int (*pr)(const char *, ...); /* in */
{
- db_addr_t ip, previp, sp;
- db_expr_t offset, value;
- db_sym_t sym;
- char *name;
- ip = ddb_regs.tf_rip;
+ switch (is_trap) {
+ case NONE:
+ *ip = (db_addr_t)
+ db_get_value((db_addr_t)&(*fp)->f_retaddr, 8, FALSE);
+ *fp = (struct x86_64_frame *)
+ db_get_value((db_addr_t)&(*fp)->f_frame, 8, FALSE);
+ break;
- for (sp = ddb_regs.tf_rsp; !db_endtrace(ip); sp += 4) {
- if (*(char **)sp >= end)
- continue;
- previp = db_findcaller(sp, ip, &name, &offset);
- if (!previp || !name)
- continue;
- if (offset) {
- pr("[%s+%p", name, offset);
- pr(" called from ");
- db_printsym(previp, DB_STGY_PROC, pr);
- pr("]");
+ default: {
+ struct trapframe *tf;
+
+ /* The only argument to trap() or syscall() is the trapframe. */
+ tf = (struct trapframe *)argp;
+ switch (is_trap) {
+ case TRAP:
+ (*pr)("--- trap (number %d) ---\n", tf->tf_trapno);
+ break;
+ case SYSCALL:
+ (*pr)("--- syscall (number %ld) ---\n", tf->tf_rax);
+ break;
+ case INTERRUPT:
+ (*pr)("--- interrupt ---\n");
+ break;
+ }
+ *fp = (struct x86_64_frame *)tf->tf_rbp;
+ *ip = (db_addr_t)tf->tf_rip;
+ break;
+ }
+ }
+}
+
+void
+db_stack_trace_print(addr, have_addr, count, modif, pr)
+ db_expr_t addr;
+ boolean_t have_addr;
+ db_expr_t count;
+ char *modif;
+ int (*pr)(const char *, ...);
+{
+ struct x86_64_frame *frame, *lastframe;
+ long *argp;
+ db_addr_t callpc;
+ int is_trap = 0;
+ boolean_t kernel_only = TRUE;
+ boolean_t trace_thread = FALSE;
+
+#if 0
+ if (!db_trace_symbols_found)
+ db_find_trace_symbols();
+#endif
+
+ {
+ register char *cp = modif;
+ register char c;
+
+ while ((c = *cp++) != 0) {
+ if (c == 't')
+ trace_thread = TRUE;
+ if (c == 'u')
+ kernel_only = FALSE;
+ }
+ }
+
+ if (!have_addr) {
+ frame = (struct x86_64_frame *)ddb_regs.tf_rbp;
+ callpc = (db_addr_t)ddb_regs.tf_rip;
+ } else {
+#if 0
+ if (trace_thread) {
+ struct proc *p;
+ struct user *u;
+ struct lwp *l;
+ (*pr)("trace: pid %d ", (int)addr);
+ p = pfind(addr);
+ if (p == NULL) {
+ (*pr)("not found\n");
+ return;
+ }
+ l = proc_representative_lwp(p);
+ if (!(l->l_flag&L_INMEM)) {
+ (*pr)("swapped out\n");
+ return;
+ }
+ u = l->l_addr;
+ frame = (struct x86_64_frame *) u->u_pcb.pcb_rbp;
+ (*pr)("at %p\n", frame);
+ } else
+#endif
+ frame = (struct x86_64_frame *)addr;
+ callpc = (db_addr_t)
+ db_get_value((db_addr_t)&frame->f_retaddr, 8, FALSE);
+ frame = (struct x86_64_frame *)frame->f_frame;
+ }
+
+ lastframe = 0;
+ while (count && frame != 0) {
+ int narg;
+ char * name;
+ db_expr_t offset;
+ db_sym_t sym;
+#define MAXNARG 16
+ char *argnames[MAXNARG], **argnp = NULL;
+
+ sym = db_search_symbol(callpc, DB_STGY_ANY, &offset);
+ db_symbol_values(sym, &name, NULL);
+
+ if (lastframe == 0 && sym == NULL) {
+ /* Symbol not found, peek at code */
+ long instr = db_get_value(callpc, 8, FALSE);
+
+ offset = 1;
+ if ((instr & 0x00ffffff) == 0x00e58955 ||
+ /* enter: pushl %ebp, movl %esp, %ebp */
+ (instr & 0x0000ffff) == 0x0000e589
+ /* enter+1: movl %esp, %ebp */) {
+ offset = 0;
+ }
+ }
+ if (INKERNEL(frame) && name) {
+#ifdef __ELF__
+ if (!strcmp(name, "trap")) {
+ is_trap = TRAP;
+ } else if (!strcmp(name, "syscall")) {
+ is_trap = SYSCALL;
+ } else if (name[0] == 'X') {
+ if (!strncmp(name, "Xintr", 5) ||
+ !strncmp(name, "Xresume", 7) ||
+ !strncmp(name, "Xstray", 6) ||
+ !strncmp(name, "Xhold", 5) ||
+ !strncmp(name, "Xrecurse", 8) ||
+ !strcmp(name, "Xdoreti") ||
+ !strncmp(name, "Xsoft", 5)) {
+ is_trap = INTERRUPT;
+ } else
+ goto normal;
+ } else
+ goto normal;
+ narg = 0;
+#else
+ if (!strcmp(name, "_trap")) {
+ is_trap = TRAP;
+ } else if (!strcmp(name, "_syscall")) {
+ is_trap = SYSCALL;
+ } else if (name[0] == '_' && name[1] == 'X') {
+ if (!strncmp(name, "_Xintr", 6) ||
+ !strncmp(name, "_Xresume", 8) ||
+ !strncmp(name, "_Xstray", 7) ||
+ !strncmp(name, "_Xhold", 6) ||
+ !strncmp(name, "_Xrecurse", 9) ||
+ !strcmp(name, "_Xdoreti") ||
+ !strncmp(name, "_Xsoft", 6)) {
+ is_trap = INTERRUPT;
+ } else
+ goto normal;
+ } else
+ goto normal;
+ narg = 0;
+#endif /* __ELF__ */
+ } else {
+ normal:
+ is_trap = NONE;
+ narg = MAXNARG;
+ if (db_sym_numargs(sym, &narg, argnames))
+ argnp = argnames;
+ else
+ narg = db_numargs(frame);
+ }
+
+ (*pr)("%s(", name);
+
+ if (lastframe == 0 && offset == 0 && !have_addr) {
+ /*
+ * We have a breakpoint before the frame is set up
+ * Use %esp instead
+ */
+ argp = &((struct x86_64_frame *)(ddb_regs.tf_rsp-8))->f_arg0;
+ } else {
+ argp = &frame->f_arg0;
+ }
+
+ while (narg) {
+ if (argnp)
+ (*pr)("%s=", *argnp++);
+ (*pr)("%lx", db_get_value((db_addr_t)argp, 8, FALSE));
+ argp++;
+ if (--narg != 0)
+ (*pr)(",");
+ }
+ (*pr)(") at ");
+ db_printsym(callpc, DB_STGY_PROC, pr);
+ (*pr)("\n");
+
+ if (lastframe == 0 && offset == 0 && !have_addr) {
+ /* Frame really belongs to next callpc */
+ lastframe = (struct x86_64_frame *)(ddb_regs.tf_rsp-8);
+ callpc = (db_addr_t)
+ db_get_value((db_addr_t)&lastframe->f_retaddr,
+ 8, FALSE);
continue;
}
- pr("%s() at ", name);
- /* pr("%s(%%rsp=%p) at ", name, sp); */
- db_printsym(ip, DB_STGY_PROC, pr);
- pr("\n");
- ip = previp;
+
+ lastframe = frame;
+ db_nextframe(&frame, &callpc, &frame->f_arg0, is_trap, pr);
+
+ if (frame == 0) {
+ /* end of chain */
+ break;
+ }
+ if (INKERNEL(frame)) {
+ /* staying in kernel */
+ if (frame <= lastframe) {
+ (*pr)("Bad frame pointer: %p\n", frame);
+ break;
+ }
+ } else if (INKERNEL(lastframe)) {
+ /* switch from user to kernel */
+ if (kernel_only) {
+ (*pr)("end of kernel\n");
+ break; /* kernel stack only */
+ }
+ } else {
+ /* in user */
+ if (frame <= lastframe) {
+ (*pr)("Bad user frame pointer: %p\n",
+ frame);
+ break;
+ }
+ }
+ --count;
+ }
+ (*pr)("end trace frame: 0x%lx, count: %d\n", frame, count);
+
+ if (count && is_trap != NONE) {
+ db_printsym(callpc, DB_STGY_XTRN, pr);
+ (*pr)(":\n");
}
- sym = db_search_symbol(ip, DB_STGY_PROC, &offset);
- db_symbol_values(sym, &name, &value);
- if (name)
- pr("%s() at ", name);
- db_printsym(ip, DB_STGY_PROC, pr);
- pr("\n");
}
diff --git a/sys/arch/amd64/conf/Makefile.amd64 b/sys/arch/amd64/conf/Makefile.amd64
index eb831850458..4aa6ecdb196 100644
--- a/sys/arch/amd64/conf/Makefile.amd64
+++ b/sys/arch/amd64/conf/Makefile.amd64
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.amd64,v 1.6 2004/11/19 06:41:13 miod Exp $
+# $OpenBSD: Makefile.amd64,v 1.7 2005/03/31 02:53:48 tedu Exp $
# Makefile for OpenBSD
#
@@ -40,7 +40,7 @@ CDIAGFLAGS= -Werror -Wall -Wstrict-prototypes -Wmissing-prototypes \
CMACHFLAGS+= -mcmodel=kernel -mno-red-zone -fno-strict-aliasing \
-mno-sse2 -mno-sse -mno-3dnow -mno-mmx -msoft-float \
- -fno-builtin-printf -fno-builtin-log
+ -fno-builtin-printf -fno-builtin-log -fno-omit-frame-pointer
.if ${IDENT:M-DNO_PROPOLICE}
CMACHFLAGS+= -fno-stack-protector
.endif