Re: unsafe functions from signal handler



Kasper Dupont wrote:
bill pursell wrote:

Is the deadlock condition still possible if the sigaction resets
the signal dispostion to abort? (so the first signal enters the
handler which calls printf, but the second signal causes an abort)

The first handler may interrupt a printf call in the program.

Right, thanks. I am clearly somewhat confused still, and I'm hoping
you can clarify for me. I wrote the following code in an attempt
to understand better what is happening with signal handling, and
as always more questions were raised than answered.

I'm trying to determine if a pointer is writable. My function sets the
signal disposition for SIGSEGV, attempts to write to the address,
resets the signal disposition, and returns a value based on whether
or not a SIGSEGV was generated when writing to the address. However,
it doesn't work. When you write to an unwritable adress the attempt
to write
is made again after the handler returns, generating a segfault and
looping in
and out of the handler. The obvious solution was to modify the address
being written to in the signal handler so that the second attempt
will not generate a seg fault. However, subsequent writes do generate
the segfault, and I am baffled as to why. I suspect it is because
the address being written to is no longer being read from the variable,
but is already in a register. How do I achieve the desired result?


Also, on a totally unrelated note, when I run this with gdb -tui, it
bombs
out. The debugger goes to sleep. Any thoughts on why?

#include <signal.h>
#include <stdbool.h>
#include <stdio.h>

volatile char *test_ptr;
volatile bool can_write;
char good_buf;

static void
handle(int signum, siginfo_t *info, void *context)
{ /* Handler for SIGSEGV. */
test_ptr = &good_buf;
can_write = false;
}

bool
is_writable(void *ptr)
{ /** Return true if the ptr is writable */
struct sigaction oldact, act;
char value;

/* set signal disposition.*/
sigemptyset(&act.sa_mask);
act.sa_sigaction = handle;
sigaction(SIGSEGV, &act, &oldact);

/* Test the pointer. */
test_ptr = (char *)ptr;
can_write = true;
value = *test_ptr;
*test_ptr = value;

/* Restore the signal disposition. */
sigaction(SIGSEGV, &oldact, NULL);
return can_write;

}

int
main()
{
char *a = "test";
char b[] = "test";

printf(" can%s write to b\n", (is_writable(b)) ? "":"'t");
printf(" can%s write to a\n", (is_writable(a)) ? "":"'t");
}

.



Relevant Pages

  • Re: fwrite() does not write data to file
    ... ^C typically sends a SIGINT, which you could catch or even ... # handler calls any function in the standard library other than... ... rest of the program to write its file and then abort) should cause ... distinction made is that between an explicit call by abortor raise, ...
    (comp.lang.c)
  • Re: Button click event handler not called.
    ... The Click event is called in the MouseUp event. ... Some messages require a response, ... > the specified messages, and an "Abort" button, to allow the user to abort ... > socket, the click handler gets called, as normal. ...
    (microsoft.public.dotnet.framework.windowsforms.controls)
  • Re: Is setjmp/longjmp ok?
    ... > # than the abort function or the signal function with the ... > # the signal that caused the invocation of the handler. ... > Once you call longjmpfrom a signal handler, ... setjmp is generally called in an upper stack frame vs. longjmp being called ...
    (comp.lang.c)
  • Button click event handler not called.
    ... Some messages require a response, ... the specified messages, and an "Abort" button, to allow the user to abort the ... socket, the click handler gets called, as normal. ... I added MouseUp and MouseDown handlers for that button and saw that both ...
    (microsoft.public.dotnet.framework.windowsforms.controls)