diff usr/src/uts/intel/ia32/os/archdep.c @ 12979:ab9ae749152f

PSARC/2009/617 Software Events Notification Parameters CLI PSARC/2009/618 snmp-notify: SNMP Notification Daemon for Software Events PSARC/2009/619 smtp-notify: Email Notification Daemon for Software Events PSARC/2010/225 fmd for non-global Solaris zones PSARC/2010/226 Solaris Instance UUID PSARC/2010/227 nvlist_nvflag(3NVPAIR) PSARC/2010/228 libfmevent additions PSARC/2010/257 sysevent_evc_setpropnvl and sysevent_evc_getpropnvl PSARC/2010/265 FMRI and FMA Event Stabilty, 'ireport' category 1 event class, and the 'sw' FMRI scheme PSARC/2010/278 FMA/SMF integration: instance state transitions PSARC/2010/279 Modelling panics within FMA PSARC/2010/290 logadm.conf upgrade 6392476 fmdump needs to pretty-print 6393375 userland ereport/ireport event generation interfaces 6445732 Add email notification agent for FMA and software events 6804168 RFE: Allow an efficient means to monitor SMF services status changes 6866661 scf_values_destroy(3SCF) will segfault if is passed NULL 6884709 Add snmp notification agent for FMA and software events 6884712 Add private interface to tap into libfmd_msg macro expansion capabilities 6897919 fmd to run in a non-global zone 6897937 fmd use of non-private doors is not safe 6900081 add a UUID to Solaris kernel image for use in crashdump identification 6914884 model panic events as a defect diagnosis in FMA 6944862 fmd_case_open_uuid, fmd_case_uuisresolved, fmd_nvl_create_defect 6944866 log legacy sysevents in fmd 6944867 enumerate svc scheme in topo 6944868 software-diagnosis and software-response fmd modules 6944870 model SMF maintenance state as a defect diagnosis in FMA 6944876 savecore runs in foreground for systems with zfs root and dedicated dump 6965796 Implement notification parameters for SMF state transitions and FMA events 6968287 SUN-FM-MIB.mib needs to be updated to reflect Oracle information 6972331 logadm.conf upgrade PSARC/2010/290
author Gavin Maltby <gavin.maltby@oracle.com>
date Fri, 30 Jul 2010 17:04:17 +1000
parents 4c5722bc28dc
children 8315ff49e22e
line wrap: on
line diff
--- a/usr/src/uts/intel/ia32/os/archdep.c	Thu Jul 29 22:45:58 2010 -0700
+++ b/usr/src/uts/intel/ia32/os/archdep.c	Fri Jul 30 17:04:17 2010 +1000
@@ -1129,10 +1129,17 @@
 
 /*
  * Print a stack backtrace using the specified frame pointer.  We delay two
- * seconds before continuing, unless this is the panic traceback.  Note
- * that the frame for the starting stack pointer value is omitted because
+ * seconds before continuing, unless this is the panic traceback.
+ * If we are in the process of panicking, we also attempt to write the
+ * stack backtrace to a staticly assigned buffer, to allow the panic
+ * code to find it and write it in to uncompressed pages within the
+ * system crash dump.
+ * Note that the frame for the starting stack pointer value is omitted because
  * the corresponding %eip is not known.
  */
+
+extern char *dump_stack_scratch;
+
 #if defined(__amd64)
 
 void
@@ -1143,10 +1150,17 @@
 	uintptr_t	pc, nextpc;
 	ulong_t		off;
 	char		args[TR_ARG_MAX * 2 + 16], *sym;
+	uint_t	  offset = 0;
+	uint_t	  next_offset = 0;
+	char	    stack_buffer[1024];
 
 	if (!panicstr)
 		printf("traceback: %%fp = %p\n", (void *)fp);
 
+	if (panicstr && !dump_stack_scratch) {
+		printf("Warning - stack not written to the dump buffer\n");
+	}
+
 	fp = (struct frame *)plat_traceback(fpreg);
 	if ((uintptr_t)fp < KERNELBASE)
 		goto out;
@@ -1177,9 +1191,33 @@
 		if ((sym = kobj_getsymname(pc, &off)) != NULL) {
 			printf("%016lx %s:%s+%lx (%s)\n", (uintptr_t)fp,
 			    mod_containing_pc((caddr_t)pc), sym, off, args);
+			(void) snprintf(stack_buffer, sizeof (stack_buffer),
+			    "%s:%s+%lx (%s) | ",
+			    mod_containing_pc((caddr_t)pc), sym, off, args);
 		} else {
 			printf("%016lx %lx (%s)\n",
 			    (uintptr_t)fp, pc, args);
+			(void) snprintf(stack_buffer, sizeof (stack_buffer),
+			    "%lx (%s) | ", pc, args);
+		}
+
+		if (panicstr && dump_stack_scratch) {
+			next_offset = offset + strlen(stack_buffer);
+			if (next_offset < STACK_BUF_SIZE) {
+				bcopy(stack_buffer, dump_stack_scratch + offset,
+				    strlen(stack_buffer));
+				offset = next_offset;
+			} else {
+				/*
+				 * In attempting to save the panic stack
+				 * to the dumpbuf we have overflowed that area.
+				 * Print a warning and continue to printf the
+				 * stack to the msgbuf
+				 */
+				printf("Warning: stack in the dump buffer"
+				    " may be incomplete\n");
+				offset = next_offset;
+			}
 		}
 
 		pc = nextpc;
@@ -1189,6 +1227,8 @@
 	if (!panicstr) {
 		printf("end of traceback\n");
 		DELAY(2 * MICROSEC);
+	} else if (dump_stack_scratch) {
+		dump_stack_scratch[offset] = '\0';
 	}
 }
 
@@ -1200,6 +1240,9 @@
 	struct frame *fp = (struct frame *)fpreg;
 	struct frame *nextfp, *minfp, *stacktop;
 	uintptr_t pc, nextpc;
+	uint_t	  offset = 0;
+	uint_t	  next_offset = 0;
+	char	    stack_buffer[1024];
 
 	cpu_t *cpu;
 
@@ -1215,6 +1258,10 @@
 	if (!panicstr)
 		printf("traceback: %%fp = %p\n", (void *)fp);
 
+	if (panicstr && !dump_stack_scratch) {
+		printf("Warning - stack not written to the dumpbuf\n");
+	}
+
 	/*
 	 * If we are panicking, all high-level interrupt information in
 	 * CPU was overwritten.  panic_cpu has the correct values.
@@ -1275,9 +1322,35 @@
 		if ((sym = kobj_getsymname(pc, &off)) != NULL) {
 			printf("%08lx %s:%s+%lx (%s)\n", (uintptr_t)fp,
 			    mod_containing_pc((caddr_t)pc), sym, off, args);
+			(void) snprintf(stack_buffer, sizeof (stack_buffer),
+			    "%s:%s+%lx (%s) | ",
+			    mod_containing_pc((caddr_t)pc), sym, off, args);
+
 		} else {
 			printf("%08lx %lx (%s)\n",
 			    (uintptr_t)fp, pc, args);
+			(void) snprintf(stack_buffer, sizeof (stack_buffer),
+			    "%lx (%s) | ", pc, args);
+
+		}
+
+		if (panicstr && dump_stack_scratch) {
+			next_offset = offset + strlen(stack_buffer);
+			if (next_offset < STACK_BUF_SIZE) {
+				bcopy(stack_buffer, dump_stack_scratch + offset,
+				    strlen(stack_buffer));
+				offset = next_offset;
+			} else {
+				/*
+				 * In attempting to save the panic stack
+				 * to the dumpbuf we have overflowed that area.
+				 * Print a warning and continue to printf the
+				 * stack to the msgbuf
+				 */
+				printf("Warning: stack in the dumpbuf"
+				    " may be incomplete\n");
+				offset = next_offset;
+			}
 		}
 
 		minfp = fp;
@@ -1288,7 +1361,10 @@
 	if (!panicstr) {
 		printf("end of traceback\n");
 		DELAY(2 * MICROSEC);
+	} else if (dump_stack_scratch) {
+		dump_stack_scratch[offset] = '\0';
 	}
+
 }
 
 #endif	/* __i386 */