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:
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user