This can be hard to debug, and could indeed prevent debugging, since it can take out the ability to run /bin/sh, depending on how you've set up your environment.
Before: $ HISTSIZE=1000000000 /bin/sh /bin/sh: internal error: unable to allocate memory <crashes> <--- no ksh With this pa $ HISTSIZE=1000000000 ./ksh ./ksh: internal error: unable to allocate 16+8000000008 bytes of memory Unable to set the history size to 1000000000 hostname$ ^D <--- ksh running diff --git a/bin/ksh/alloc.c b/bin/ksh/alloc.c index 204e835890c..6e29e2eb3fe 100644 --- a/bin/ksh/alloc.c +++ b/bin/ksh/alloc.c @@ -97,7 +97,7 @@ aresize(void *ptr, size_t size, Area *ap) l2 = realloc(l, sizeof(struct link) + size); if (l2 == NULL) - internal_errorf("unable to allocate memory"); + internal_errorf("unable to allocate %lu+%lu bytes of memory", sizeof(struct link), size); if (lprev) lprev->next = l2; else diff --git a/bin/ksh/history.c b/bin/ksh/history.c index a3a8b60cc76..3bd6444d7a9 100644 --- a/bin/ksh/history.c +++ b/bin/ksh/history.c @@ -549,10 +549,17 @@ sethistcontrol(const char *str) /* * set history * this means reallocating the dataspace + * if memory allocation fails then history size will remain unchanged */ void sethistsize(int n) { + newenv(E_FUNC); + if (sigsetjmp(genv->jbuf, 0)) { + fprintf(stderr, "Unable to set the history size to %d\n", n); + quitenv(NULL); + return; + } if (n > 0 && (uint32_t)n != histsize) { int offset = histptr - history; @@ -566,8 +573,8 @@ sethistsize(int n) memmove(history, histptr - offset, n * sizeof(char *)); } - histsize = n; histbase = areallocarray(histbase, n + 1, sizeof(char *), APERM); + histsize = n; history = histbase + 1; histptr = history + offset; }