Index: /trunk/src/kash/bltin/printf.c
===================================================================
--- /trunk/src/kash/bltin/printf.c	(revision 2647)
+++ /trunk/src/kash/bltin/printf.c	(revision 2648)
@@ -55,4 +55,5 @@
 #include <string.h>
 #include <unistd.h>
+#include "shinstance.h"
 
 #ifdef __GNUC__
@@ -647,5 +648,5 @@
 		rval = 1;
 	} else if (errno == ERANGE) {
-		warnx("%s: %s", s, strerror(ERANGE));
+		warnx("%s: %s", s, sh_strerror(psh, ERANGE));
 		rval = 1;
 	}
Index: /trunk/src/kash/cd.c
===================================================================
--- /trunk/src/kash/cd.c	(revision 2647)
+++ /trunk/src/kash/cd.c	(revision 2648)
@@ -392,5 +392,5 @@
 			continue;
 		if (!noerror)
-			error(psh, "getcwd() failed: %s", strerror(errno));
+			error(psh, "getcwd() failed: %s", sh_strerror(psh, errno));
 		return;
 	}
Index: /trunk/src/kash/error.c
===================================================================
--- /trunk/src/kash/error.c	(revision 2647)
+++ /trunk/src/kash/error.c	(revision 2648)
@@ -138,5 +138,5 @@
 	}
 	if (sv_errno >= 0)
-		outfmt(&psh->errout, "%s", strerror(sv_errno));
+		outfmt(&psh->errout, "%s", sh_strerror(psh, sv_errno));
 	out2c(psh, '\n');
 	flushout(&psh->errout);
@@ -156,6 +156,9 @@
 #ifdef DEBUG
 	if (msg) {
+		va_list va2;
 		TRACE((psh, "exverror(%d, \"", cond));
-		TRACEV((psh, msg, ap));
+		va_copy(va2, ap);
+		TRACEV((psh, msg, va2));
+		va_end(va2);
 		TRACE((psh, "\") pid=%d\n", sh_getpid(psh)));
 	} else
Index: /trunk/src/kash/exec.c
===================================================================
--- /trunk/src/kash/exec.c	(revision 2647)
+++ /trunk/src/kash/exec.c	(revision 2648)
@@ -1138,5 +1138,5 @@
 					if (!v_flag)
 						out1fmt(psh, ": %s\n",
-						    strerror(errno));
+						    sh_strerror(psh, errno));
 					else
 						err = 126;
Index: /trunk/src/kash/jobs.c
===================================================================
--- /trunk/src/kash/jobs.c	(revision 2647)
+++ /trunk/src/kash/jobs.c	(revision 2648)
@@ -150,15 +150,15 @@
 		if (sh_getpgid(psh, 0) != psh->rootpid && sh_setpgid(psh, 0, psh->rootpid) == -1)
 			error(psh, "Cannot set process group (%s) at %d",
-			    strerror(errno), __LINE__);
+			    sh_strerror(psh, errno), __LINE__);
 		if (sh_tcsetpgrp(psh, psh->ttyfd, psh->rootpid) == -1)
 			error(psh, "Cannot set tty process group (%s) at %d",
-			    strerror(errno), __LINE__);
+			    sh_strerror(psh, errno), __LINE__);
 	} else { /* turning job control off */
 		if (sh_getpgid(psh, 0) != psh->initialpgrp && sh_setpgid(psh, 0, psh->initialpgrp) == -1)
 			error(psh, "Cannot set process group (%s) at %d",
-			    strerror(errno), __LINE__);
+			    sh_strerror(psh, errno), __LINE__);
 		if (sh_tcsetpgrp(psh, psh->ttyfd, psh->initialpgrp) == -1)
 			error(psh, "Cannot set tty process group (%s) at %d",
-			    strerror(errno), __LINE__);
+			    sh_strerror(psh, errno), __LINE__);
 		shfile_close(&psh->fdtab, psh->ttyfd);
 		psh->ttyfd = -1;
@@ -209,5 +209,5 @@
 	if (i >= jp->nprocs) {
 		error(psh, "Cannot set tty process group (%s) at %d",
-		    strerror(errno), __LINE__);
+		    sh_strerror(psh, errno), __LINE__);
 	}
 	restartjob(psh, jp);
@@ -301,5 +301,5 @@
 			break;
 	if (i >= jp->nprocs)
-		error(psh, "Cannot continue job (%s)", strerror(errno));
+		error(psh, "Cannot continue job (%s)", sh_strerror(psh, errno));
 	for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) {
 		if (WIFSTOPPED(ps->status)) {
@@ -485,5 +485,5 @@
 		if (sh_tcsetpgrp(psh, psh->ttyfd, sh_getpid(psh)) == -1)
 			error(psh, "Cannot set tty process group (%s) at %d",
-			    strerror(errno), __LINE__);
+			    sh_strerror(psh, errno), __LINE__);
 		TRACE((psh, "repaired tty process group\n"));
 		silent = 1;
@@ -854,5 +854,5 @@
 			if (sh_tcsetpgrp(psh, psh->ttyfd, pgrp) == -1)
 				error(psh, "Cannot set tty process group (%s) at %d",
-				    strerror(errno), __LINE__);
+				    sh_strerror(psh, errno), __LINE__);
 		}
 		setsignal(psh, SIGTSTP, vforked);
@@ -927,5 +927,5 @@
 		if (sh_tcsetpgrp(psh, psh->ttyfd, mypgrp) == -1)
 			error(psh, "Cannot set tty process group (%s) at %d",
-			    strerror(errno), __LINE__);
+			    sh_strerror(psh, errno), __LINE__);
 	}
 	if (jp->state == JOBSTOPPED && psh->curjob != jp - psh->jobtab)
Index: /trunk/src/kash/miscbltin.c
===================================================================
--- /trunk/src/kash/miscbltin.c	(revision 2647)
+++ /trunk/src/kash/miscbltin.c	(revision 2648)
@@ -424,5 +424,5 @@
 			limit.rlim_cur = val;
 		if (sh_setrlimit(psh, l->cmd, &limit) < 0)
-			error(psh, "error setting limit (%s)", strerror(errno));
+			error(psh, "error setting limit (%s)", sh_strerror(psh, errno));
 	} else {
 		if (how & SOFT)
Index: /trunk/src/kash/redir.c
===================================================================
--- /trunk/src/kash/redir.c	(revision 2647)
+++ /trunk/src/kash/redir.c	(revision 2648)
@@ -144,5 +144,5 @@
 				default:
 					INTON;
-					error(psh, "%d: %s", fd, strerror(errno));
+					error(psh, "%d: %s", fd, sh_strerror(psh, errno));
 					/* NOTREACHED */
 				}
@@ -377,5 +377,5 @@
 		if (errno == EMFILE)
 			return EMPTY;
-		error(psh, "%d: %s", from, strerror(errno));
+		error(psh, "%d: %s", from, sh_strerror(psh, errno));
 	}
 	return newfd;
@@ -398,5 +398,5 @@
 		if (errno == EMFILE)
 			return EMPTY;
-		error(psh, "%d: %s", from, strerror(errno));
+		error(psh, "%d: %s", from, sh_strerror(psh, errno));
 	}
 	return newfd;
@@ -419,5 +419,5 @@
 		if (errno == EMFILE)
 			return EMPTY;
-		error(psh, "%d: %s", from, strerror(errno));
+		error(psh, "%d: %s", from, sh_strerror(psh, errno));
 	}
 	return newfd;
Index: /trunk/src/kash/shinstance.c
===================================================================
--- /trunk/src/kash/shinstance.c	(revision 2647)
+++ /trunk/src/kash/shinstance.c	(revision 2648)
@@ -1417,2 +1417,14 @@
 }
 
+
+/* Wrapper for strerror that makes sure it doesn't return NULL and causes the
+   caller or fprintf routines to crash. */
+const char *sh_strerror(shinstance *psh, int error)
+{
+    char *err = strerror(error);
+    if (!err)
+        return "strerror return NULL!";
+    (void)psh;
+    return err;
+}
+
Index: /trunk/src/kash/shinstance.h
===================================================================
--- /trunk/src/kash/shinstance.h	(revision 2647)
+++ /trunk/src/kash/shinstance.h	(revision 2648)
@@ -494,4 +494,6 @@
 int sh_setrlimit(shinstance *, int, const shrlimit *);
 
+/* string.h */
+const char *sh_strerror(shinstance *, int);
 
 #ifdef DEBUG
@@ -499,7 +501,7 @@
 # define TRACE2V(param)	tracev param
 #else
-# define TRACE2(param)
-# define TRACE2V(param)
-#endif
-
-#endif
+# define TRACE2(param)  do { } while (0)
+# define TRACE2V(param) do { } while (0)
+#endif
+
+#endif
