]> Savannah Git Hosting - gnulib.git/commitdiff
c-stack: output diagnostic in single 'write'
authorPaul Eggert <eggert@cs.ucla.edu>
Sun, 20 Sep 2020 19:52:15 +0000 (12:52 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sun, 20 Sep 2020 22:48:44 +0000 (15:48 -0700)
* lib/c-stack.c (die): In the typical case, use just one 'write'
syscall to output the diagnostic, as this lessens interleaving.
(die, c_stack_action): Assume C99.
* modules/c-stack (Depends-on): Add c99, mempcpy.

ChangeLog
lib/c-stack.c
modules/c-stack

index 087b9232fdd8da162e97c7ae357f333e36dd5604..a43c32eb8d9ed4a4704b0fda734bae20180b22c7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2020-09-20  Paul Eggert  <eggert@cs.ucla.edu>
 
+       c-stack: output diagnostic in single 'write'
+       * lib/c-stack.c (die): In the typical case, use just one 'write'
+       syscall to output the diagnostic, as this lessens interleaving.
+       (die, c_stack_action): Assume C99.
+       * modules/c-stack (Depends-on): Add c99, mempcpy.
+
        c-stack: improve checking if !libsigsegv
        If SIGINFO_WORKS, do not treat a null pointer dereference as if it
        were a stack overflow.  Use uintptr_t and INT_ADD_WRAPV to avoid
index 3649c1bfe020946ade0a97ab9dc4805d3bc01b26..742eb023e82e164e54c72754ed89774e83f16a3a 100644 (file)
@@ -118,7 +118,6 @@ static char const * volatile progname;
 static _GL_ASYNC_SAFE _Noreturn void
 die (int signo)
 {
-  char const *message;
 # if !SIGINFO_WORKS && !USE_LIBSIGSEGV
   /* We can't easily determine whether it is a stack overflow; so
      assume that the rest of our program is perfect (!) and that
@@ -126,11 +125,34 @@ die (int signo)
   signo = 0;
 # endif
   segv_action (signo);
-  message = signo ? program_error_message : stack_overflow_message;
-  ignore_value (write (STDERR_FILENO, progname, strlen (progname)));
-  ignore_value (write (STDERR_FILENO, ": ", 2));
-  ignore_value (write (STDERR_FILENO, message, strlen (message)));
-  ignore_value (write (STDERR_FILENO, "\n", 1));
+  char const *message = signo ? program_error_message : stack_overflow_message;
+
+  /* If the message is short, write it all at once to avoid
+     interleaving with other messages.  Avoid writev as it is not
+     documented to be async-signal-safe.  */
+  size_t prognamelen = strlen (progname);
+  size_t messagelen = strlen (message);
+  static char const separator[] = {':', ' '};
+  char buf[SIGSTKSZ / 16 + sizeof separator];
+  ptrdiff_t buflen;
+  if (prognamelen + messagelen < sizeof buf - sizeof separator)
+    {
+      char *p = mempcpy (buf, progname, prognamelen);
+      p = mempcpy (p, separator, sizeof separator);
+      p = mempcpy (p, message, messagelen);
+      *p++ = '\n';
+      buflen = p - buf;
+    }
+  else
+    {
+      ignore_value (write (STDERR_FILENO, progname, prognamelen));
+      ignore_value (write (STDERR_FILENO, separator, sizeof separator));
+      ignore_value (write (STDERR_FILENO, message, messagelen));
+      buf[0] = '\n';
+      buflen = 1;
+    }
+  ignore_value (write (STDERR_FILENO, buf, buflen));
+
   if (! signo)
     _exit (exit_failure);
   raise (signo);
@@ -299,9 +321,7 @@ segv_handler (int signo, siginfo_t *info, void *context _GL_UNUSED)
 int
 c_stack_action (_GL_ASYNC_SAFE void (*action) (int))
 {
-  int r;
   stack_t st;
-  struct sigaction act;
   st.ss_flags = 0;
 # if SIGALTSTACK_SS_REVERSED
   /* Irix mistakenly treats ss_sp as the upper bound, rather than
@@ -312,7 +332,7 @@ c_stack_action (_GL_ASYNC_SAFE void (*action) (int))
   st.ss_sp = alternate_signal_stack.buffer;
   st.ss_size = sizeof alternate_signal_stack.buffer;
 # endif
-  r = sigaltstack (&st, NULL);
+  int r = sigaltstack (&st, NULL);
   if (r != 0)
     return r;
 
@@ -325,6 +345,7 @@ c_stack_action (_GL_ASYNC_SAFE void (*action) (int))
   page_size = sysconf (_SC_PAGESIZE);
 # endif
 
+  struct sigaction act;
   sigemptyset (&act.sa_mask);
 
 # if SIGINFO_WORKS
index 8c898eb9e92e54d5504aac59aab1b807d3e3f7f2..5ddf6e6f5a8a79198eb12640327b16c43787a38c 100644 (file)
@@ -7,6 +7,7 @@ lib/c-stack.c
 m4/c-stack.m4
 
 Depends-on:
+c99
 errno
 exitfail
 getprogname
@@ -15,6 +16,7 @@ ignore-value
 intprops
 inttypes
 libsigsegv
+mempcpy
 raise
 sigaction
 stdbool