Index: defs.h
===================================================================
RCS file: /nfs/projects/cvs/crash/defs.h,v
retrieving revision 1.347
diff -u -r1.347 defs.h
--- defs.h	23 Apr 2008 19:54:00 -0000	1.347
+++ defs.h	14 May 2008 15:40:40 -0000
@@ -46,6 +46,7 @@
 #include <sys/param.h>
 #include <sys/wait.h>
 #include <sys/time.h>
+#include <execinfo.h> /* backtrace() */
 
 #define BASELEVEL_REVISION  "4.0"
 
@@ -1797,18 +1798,18 @@
 	char argbuf[1];
 };
 
-static inline void
-save_return_address(ulong *retaddr)
-{
-	retaddr[0] = (ulong) __builtin_return_address(0);
-#if defined(X86) || defined(PPC) || defined(X86_64) || defined(PPC64)
-	if (__builtin_frame_address(1))
-		retaddr[1] = (ulong) __builtin_return_address(1);
-	if (__builtin_frame_address(2))
-                retaddr[2] = (ulong) __builtin_return_address(2);
-	if (__builtin_frame_address(3))
-                retaddr[3] = (ulong) __builtin_return_address(3);
-#endif
+#define NUMBER_STACKFRAMES 4
+
+#define SAVE_RETURN_ADDRESS(retaddr) \
+{ 									\
+	int i; 								\
+	int saved_stacks; 						\
+									\
+	saved_stacks = backtrace((void **)retaddr, NUMBER_STACKFRAMES); \
+									\
+	/* explicitely zero out the invalid addresses */		\
+	for (i = saved_stacks; i < NUMBER_STACKFRAMES; i++)		\
+		retaddr[i] = 0;						\
 }
 
 #endif /* !GDB_COMMON */
Index: symbols.c
===================================================================
RCS file: /nfs/projects/cvs/crash/symbols.c,v
retrieving revision 1.162
diff -u -r1.162 symbols.c
--- symbols.c	14 Apr 2008 17:54:56 -0000	1.162
+++ symbols.c	14 May 2008 15:55:01 -0000
@@ -8913,8 +8913,8 @@
 		return offset2;
 
 	if (pc->flags & DATADEBUG) {
-        	ulong retaddr[4] = { 0 };
-		save_return_address(retaddr);
+        	ulong retaddr[NUMBER_STACKFRAMES] = { 0 };
+		SAVE_RETURN_ADDRESS(retaddr);
 		sprintf(errmsg, 	
 		    "invalid (optional) structure member offsets: %s or %s",
 			item1, item2);
@@ -8936,8 +8936,8 @@
                 return size2;
 
         if (pc->flags & DATADEBUG) {
-        	ulong retaddr[4] = { 0 };
-		save_return_address(retaddr);
+        	ulong retaddr[NUMBER_STACKFRAMES] = { 0 };
+		SAVE_RETURN_ADDRESS(retaddr);
 		sprintf(errmsg, "invalid (optional) structure sizes: %s or %s",
 			item1, item2);
                 datatype_error(retaddr, errmsg, func, file, line);
@@ -8964,8 +8964,8 @@
 		return offset;
 
 	if (offset < 0) {
-        	ulong retaddr[4] = { 0 };
-		save_return_address(retaddr);
+        	ulong retaddr[NUMBER_STACKFRAMES] = { 0 };
+		SAVE_RETURN_ADDRESS(retaddr);
 		sprintf(errmsg, "invalid structure member offset: %s",
 			item);
 		datatype_error(retaddr, errmsg, func, file, line);
@@ -8982,8 +8982,8 @@
                 return size;
 
         if (size < 0) {
-        	ulong retaddr[4] = { 0 };
-		save_return_address(retaddr);
+        	ulong retaddr[NUMBER_STACKFRAMES] = { 0 };
+		SAVE_RETURN_ADDRESS(retaddr);
 		sprintf(errmsg, "invalid structure size: %s", item);
                 datatype_error(retaddr, errmsg, func, file, line);
         }
@@ -9051,7 +9051,7 @@
 	thisfile = get_thisfile();
 
 	fprintf(stderr, "[%s] error trace: ", thisfile);
-        for (i = 3; i >= 0; i--) {
+        for (i = (NUMBER_STACKFRAMES-1); i >= 0; i--) {
                 if (retaddr[i])
                         fprintf(stderr, "%s%lx%s",
                                 i == 3 ? "" : "=> ",
@@ -9065,7 +9065,7 @@
 		return;
 	}
 
-        for (i = 0; i < 4; i++) {
+        for (i = 0; i < NUMBER_STACKFRAMES; i++) {
 		if (!(lookfor = retaddr[i]))
 			continue;
 
Index: tools.c
===================================================================
RCS file: /nfs/projects/cvs/crash/tools.c,v
retrieving revision 1.60
diff -u -r1.60 tools.c
--- tools.c	2 Jan 2008 14:15:13 -0000	1.60
+++ tools.c	14 May 2008 15:58:23 -0000
@@ -41,11 +41,11 @@
 {
 	int end_of_line, new_line;
         char buf[BUFSIZE];
-        ulong retaddr[4] = { 0 };
+        ulong retaddr[NUMBER_STACKFRAMES] = { 0 };
 	va_list ap;
 
 	if (CRASHDEBUG(1) || (pc->flags & DROP_CORE)) {
-		save_return_address(retaddr);
+		SAVE_RETURN_ADDRESS(retaddr);
 		console("error() trace: %lx => %lx => %lx => %lx\n",
 			retaddr[3], retaddr[2], retaddr[1], retaddr[0]);
 	}
