linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Gábor Melis" <mega@retes.hu>
To: Oleg Nesterov <oleg@redhat.com>
Cc: Davide Libenzi <davidel@xmailserver.org>,
	Ingo Molnar <mingo@elte.hu>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Roland McGrath <roland@redhat.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Chris Friesen <cfriesen@nortel.com>,
	linux-kernel@vger.kernel.org
Subject: Re: Q: SEGSEGV && uc_mcontext->ip (Was: Signal delivery order)
Date: Tue, 17 Mar 2009 09:23:56 +0100	[thread overview]
Message-ID: <200903170923.56430.mega@retes.hu> (raw)
In-Reply-To: <20090317041337.GA29740@redhat.com>

On Martes 17 Marzo 2009, Oleg Nesterov wrote:
> (see http://marc.info/?t=123704955800002)
>
> First of all, perhaps I missed somethings and this is solvable
> without kernel changes, but I can't see how.
>
> To simplify, suppose that the application wants to log the faulting
> instruction before exit, so it installs the handler for SIGSEGV
>
> 	void sigsegv_handler(int sig, siginfo_t *info, struct ucontext
> *context) {
> 		fprintf(stderr, "bug at %p\n", context->uc_mcontext->ip);
> 		exit(1);
> 	}
>
> But this doesn't work. It is possible that, before the task dequeues
> SIGSEGV, another private signal, say, SIGHUP (note that SIGHUP <
> SIGSEGV) is sent to this app.
>
> In this case the task dequeues both signals, SIGHUP and then SIGSEGV
> before return to user-space. This is correct, but now uc_mcontext->ip
> points to sighup_handler, not to the faulted instruction.
>
>
> Can/should we change force_sig_info_fault() to help?
>
> We can add siginfo_t->_sigfault.ip to solve this problem. This
> shouldn't enlarge the size of siginfo_t. With this change
> sigsegv_handler() always knows the address of the instruction which
> caused the fault.
>
>
> But this doesn't allow to change uc_mcontext->ip to, say, skip the
> offending instruction or call another function which does a fixup.
> Actually, ->si_ip helps, we can do
>
> 	void sigsegv_handler(int sig, siginfo_t *info, struct ucontext
> *context) {
> 		if (info->si_ip != context->uc_mcontext->ip)
> 			/*
> 			 * The offending instruction will be repeated, and
> 			 * we will have the "same" SIGSEGV again.
> 			 */
> 			return;
>
> 		context->uc_mcontext->ip = fixup;
> 		...
> 	}
>
> But this doesn't look very nice. So, perhaps we can do another
> change?
>
> 	--- arch/x86/mm/fault.c
> 	+++ arch/x86/mm/fault.c
> 	@@ -177,6 +177,13 @@ static void force_sig_info_fault(int si_
> 	 {
> 		siginfo_t info;
>
> 	+	current->saved_sigmask = current->blocked;
> 	+	spin_lock_irq(&current->sighand->siglock);
> 	+	siginitsetinv(&current->blocked, sigmask(si_signo) |
> 	+			sigmask(SIGKILL) | sigmask(SIGSTOP));
> 	+	spin_unlock_irq(&current->sighand->siglock);
> 	+	set_restore_sigmask();
> 	+
> 		info.si_signo = si_signo;
> 		info.si_errno = 0;
> 		info.si_code = si_code;
>
> But this is a user-visible change, all signals will be blocked until
> sigsegv_handler() returns. But with this change sigsegv_handler()
> always has the "correct" rt_sigframe.
>
>
> Comments?
>
> And once again, I have a nasty feeling I missed something and we
> don't need to change the kernel.
>
> Oleg.

As an application developer what I'd like to have is this: synchronously 
generated signals are delivered before asynchronously generated ones. 
That is, if a number of signals are generated but not yet delivered 
then the synchronously generated ones are delivered first. I guess, in 
the kernel this would mean that the private/non-private distinction is 
not enough.

I think Chris is right in that standard allows the current behaviour. I 
would have quoted it already if I had thought otherwise ... He's also 
right about quality of implementation. The standard doesn't say much 
about synchronously and asynchronously generated signals and it even 
goes further:

"The order in which multiple, simultaneously pending signals outside the 
range SIGRTMIN to SIGRTMAX are delivered to or accepted by a process is 
unspecified."

Bleh. It also says that the context argument represents the context at 
the time of delivery. For a handler for sigsegv, sigtrap (to name just 
the most likely suspects) the context -  in order for it to be useful 
at all - must be from the time of generation. There is an obvious 
contradiction here and the only way I see to resolve this is to deliver 
syncrhronously generated signals while the two contexts are the same 
which is exactly what allowing other signals to 'overtake' violates. Of 
course, if sigsegv is blocked then this is impossible to do, but that's 
fine.

For the application I'm working on this whole issue is kind of moot 
since kernels with the current behaviour will be around for ages to 
come and I have the workaround of not pthread_kill()ing with a signal 
whose signum is lower than the signum of any of the syncrhonously 
generated signals. In practice, it only means that I'll use SIGUSR2 
instead of SIGUSR1 because that's greater than SIGSEGV and pay 
attention not to pthread_kill() with SIGINT. The only thing that 
worries me is this remark from Oleg 
(http://marc.info/?l=linux-kernel&m=123711058421913&w=2):

"But please note that it is still possible to hit is_signal_blocked()
even with test_with_kill(), but the probability is very low."

I still can't see how that's possible, but if it is, then it defeats the 
workaround and I have even bigger problems than I thought. Not only me, 
I guess, most applications with a sigtrap, sigsegv handler that use the 
context will be broken by a C-c.

Gabor

  parent reply	other threads:[~2009-03-17  8:24 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-14 16:50 Signal delivery order Gábor Melis
2009-03-15  9:44 ` Oleg Nesterov
2009-03-15 14:40   ` Gábor Melis
2009-03-15 17:29     ` Oleg Nesterov
2009-03-15 22:06       ` Gábor Melis
2009-03-16  0:28         ` Oleg Nesterov
2009-03-16  8:34           ` Gábor Melis
2009-03-16 21:13             ` Oleg Nesterov
2009-03-16 22:56               ` Chris Friesen
2009-03-17  4:13                 ` Q: SEGSEGV && uc_mcontext->ip (Was: Signal delivery order) Oleg Nesterov
2009-03-17  4:25                   ` Oleg Nesterov
2009-03-17  8:23                   ` Gábor Melis [this message]
2009-03-17  9:25                     ` Oleg Nesterov
2009-03-17 10:20                       ` Gábor Melis
2009-03-17 10:43                         ` Oleg Nesterov
2009-03-17 15:56                     ` Linus Torvalds
2009-03-17 19:20                       ` Q: SEGSEGV && uc_mcontext->ip David Miller
2009-03-18  9:58                       ` Q: SEGSEGV && uc_mcontext->ip (Was: Signal delivery order) Gábor Melis
2009-03-18  7:59                   ` Roland McGrath
2009-03-18  9:02                     ` RT signal queue overflow (Was: Q: SEGSEGV && uc_mcontext->ip (Was: Signal delivery order)) Gábor Melis
2009-03-18 14:52                       ` Linus Torvalds
2009-03-18 15:23                         ` Gábor Melis

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200903170923.56430.mega@retes.hu \
    --to=mega@retes.hu \
    --cc=akpm@linux-foundation.org \
    --cc=cfriesen@nortel.com \
    --cc=davidel@xmailserver.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=oleg@redhat.com \
    --cc=roland@redhat.com \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).