1
0
mirror of https://git.savannah.gnu.org/git/gnulib.git synced 2025-08-08 17:22:05 +03:00

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.
This commit is contained in:
Paul Eggert
2020-09-20 12:52:15 -07:00
parent 8ba9126d00
commit 649a39bbd0
3 changed files with 38 additions and 9 deletions

View File

@@ -1,5 +1,11 @@
2020-09-20 Paul Eggert <eggert@cs.ucla.edu> 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 c-stack: improve checking if !libsigsegv
If SIGINFO_WORKS, do not treat a null pointer dereference as if it 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 were a stack overflow. Use uintptr_t and INT_ADD_WRAPV to avoid

View File

@@ -118,7 +118,6 @@ static char const * volatile progname;
static _GL_ASYNC_SAFE _Noreturn void static _GL_ASYNC_SAFE _Noreturn void
die (int signo) die (int signo)
{ {
char const *message;
# if !SIGINFO_WORKS && !USE_LIBSIGSEGV # if !SIGINFO_WORKS && !USE_LIBSIGSEGV
/* We can't easily determine whether it is a stack overflow; so /* We can't easily determine whether it is a stack overflow; so
assume that the rest of our program is perfect (!) and that assume that the rest of our program is perfect (!) and that
@@ -126,11 +125,34 @@ die (int signo)
signo = 0; signo = 0;
# endif # endif
segv_action (signo); segv_action (signo);
message = signo ? program_error_message : stack_overflow_message; char const *message = signo ? program_error_message : stack_overflow_message;
ignore_value (write (STDERR_FILENO, progname, strlen (progname)));
ignore_value (write (STDERR_FILENO, ": ", 2)); /* If the message is short, write it all at once to avoid
ignore_value (write (STDERR_FILENO, message, strlen (message))); interleaving with other messages. Avoid writev as it is not
ignore_value (write (STDERR_FILENO, "\n", 1)); 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) if (! signo)
_exit (exit_failure); _exit (exit_failure);
raise (signo); raise (signo);
@@ -299,9 +321,7 @@ segv_handler (int signo, siginfo_t *info, void *context _GL_UNUSED)
int int
c_stack_action (_GL_ASYNC_SAFE void (*action) (int)) c_stack_action (_GL_ASYNC_SAFE void (*action) (int))
{ {
int r;
stack_t st; stack_t st;
struct sigaction act;
st.ss_flags = 0; st.ss_flags = 0;
# if SIGALTSTACK_SS_REVERSED # if SIGALTSTACK_SS_REVERSED
/* Irix mistakenly treats ss_sp as the upper bound, rather than /* 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_sp = alternate_signal_stack.buffer;
st.ss_size = sizeof alternate_signal_stack.buffer; st.ss_size = sizeof alternate_signal_stack.buffer;
# endif # endif
r = sigaltstack (&st, NULL); int r = sigaltstack (&st, NULL);
if (r != 0) if (r != 0)
return r; return r;
@@ -325,6 +345,7 @@ c_stack_action (_GL_ASYNC_SAFE void (*action) (int))
page_size = sysconf (_SC_PAGESIZE); page_size = sysconf (_SC_PAGESIZE);
# endif # endif
struct sigaction act;
sigemptyset (&act.sa_mask); sigemptyset (&act.sa_mask);
# if SIGINFO_WORKS # if SIGINFO_WORKS

View File

@@ -7,6 +7,7 @@ lib/c-stack.c
m4/c-stack.m4 m4/c-stack.m4
Depends-on: Depends-on:
c99
errno errno
exitfail exitfail
getprogname getprogname
@@ -15,6 +16,7 @@ ignore-value
intprops intprops
inttypes inttypes
libsigsegv libsigsegv
mempcpy
raise raise
sigaction sigaction
stdbool stdbool