public inbox for gnu-gabi@sourceware.org
 help / color / mirror / Atom feed
* Re: [PATCH] Make _Unwind_GetIPInfo part of the ABI
  2016-01-01  0:00       ` Michael Matz
@ 2016-01-01  0:00         ` Carlos O'Donell
  0 siblings, 0 replies; 9+ messages in thread
From: Carlos O'Donell @ 2016-01-01  0:00 UTC (permalink / raw)
  To: Michael Matz, Florian Weimer; +Cc: H.J. Lu, gnu-gabi

On 10/21/2016 09:48 AM, Michael Matz wrote:
> Hi,
> 
> On Fri, 21 Oct 2016, Michael Matz wrote:
> 
>>> On 10/21/2016 02:58 PM, Michael Matz wrote:
>>>> +This function returns the same value as \code{\_Unwind\_GetIP}.  In
>>>> +addition, the argument \code{ip\_before\_insn} must not be not null, and
>>>> +\code{*ip\_before\_insn} is updated with a flag which indicates whether
>>>> +the returned pointer is at or after the first not yet fully executed
>>>> +instruction.
>>>
>>> I think this is rather misleading.  On x86_64, the location of the IP 
>>> value is the same for calls and asynchronous signals: it always points 
>>> to the next instruction to be executed.
>>
>> No, that's simply wrong.
> 
> Or rather, it isn't wrong, it's indeed pointing to the instruction to be 
> executed next after return from handler, as always.  But that's not the 
> important thing for unwinding: what you're interested in is the 
> instruction that _caused_ the interruption, and for that what I said 
> applies.

When you say "after the first not yet fully executed instruction" do you mean
"immediately after" or "some time after?"

On 32-bit hppa there is a delayed branch slot which means that after a call you are
two instructions past the call.

On 32-bit ARM you also have IP being two instructions beyond the call at any point
in time due to pipelining.

This would also mean the current code in gcc/libgcc/unwind-c.c needs to have a
target hook for it to be right?

-- 
Cheers,
Carlos.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Make _Unwind_GetIPInfo part of the ABI
  2016-01-01  0:00 ` Michael Matz
@ 2016-01-01  0:00   ` Florian Weimer
  2016-01-01  0:00     ` Michael Matz
  0 siblings, 1 reply; 9+ messages in thread
From: Florian Weimer @ 2016-01-01  0:00 UTC (permalink / raw)
  To: Michael Matz; +Cc: H.J. Lu, gnu-gabi

On 10/21/2016 02:58 PM, Michael Matz wrote:
> +This function returns the same value as \code{\_Unwind\_GetIP}.  In
> +addition, the argument \code{ip\_before\_insn} must not be not null, and
> +\code{*ip\_before\_insn} is updated with a flag which indicates whether
> +the returned pointer is at or after the first not yet fully executed
> +instruction.

I think this is rather misleading.  On x86_64, the location of the IP 
value is the same for calls and asynchronous signals: it always points 
to the next instruction to be executed.  There are no partially executed 
instructions.

The difference that if we unwind through a call which has not yet 
returned, the caller is assumed to be still within the exception 
handling region in which the call instruction is located.  This is the 
consequence of the desired exception handling semantics of a 
non-returned function call.  It is not directly related to the 
instruction pointer value returned by _Unwind_GetIPInfo.

This is different for the signal case.  There, the instruction pointer 
directly determines the active exception handling region.

Florian

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Make _Unwind_GetIPInfo part of the ABI
  2016-01-01  0:00   ` Florian Weimer
@ 2016-01-01  0:00     ` Michael Matz
  2016-01-01  0:00       ` Florian Weimer
  2016-01-01  0:00       ` Michael Matz
  0 siblings, 2 replies; 9+ messages in thread
From: Michael Matz @ 2016-01-01  0:00 UTC (permalink / raw)
  To: Florian Weimer; +Cc: H.J. Lu, gnu-gabi

Hi,

On Fri, 21 Oct 2016, Florian Weimer wrote:

> On 10/21/2016 02:58 PM, Michael Matz wrote:
> > +This function returns the same value as \code{\_Unwind\_GetIP}.  In
> > +addition, the argument \code{ip\_before\_insn} must not be not null, and
> > +\code{*ip\_before\_insn} is updated with a flag which indicates whether
> > +the returned pointer is at or after the first not yet fully executed
> > +instruction.
> 
> I think this is rather misleading.  On x86_64, the location of the IP 
> value is the same for calls and asynchronous signals: it always points 
> to the next instruction to be executed.

No, that's simply wrong.  The saved instruction pointer points _at_ the 
instruction causing the fault for faults, and _after_ the instruction for 
traps.  Traps are things like single-stepping, breakpoints or INTO.  Most 
other interrupts are faults or aborts (the latter being imprecise and 
hence can't be restarted anyway).

For calls the saved instruction pointer always points to after the call 
and hence can be handled like a trap for unwinding purposes.

> There are no partially executed instructions.

That's not 100% correct either (e.g. certain load-state instructions can 
be interrupted in the middle, though that usually just causes a double 
fault).  But in the interest of being clearer, I guess I should have 
written "not yet completed" instruction, instead of that "fully executed" 
part.

> The difference that if we unwind through a call which has not yet 
> returned, the caller is assumed to be still within the exception 
> handling region in which the call instruction is located.  This is the 
> consequence of the desired exception handling semantics of a 
> non-returned function call.

Unwinding through one call or one trap is the same.  The interesting 
instruction is the one ending right before the reported IP.

> It is not directly related to the instruction pointer value returned by 
> _Unwind_GetIPInfo.

Yes it is.  GetIPInfo always returns the instruction pointer as encoded in 
the given unwind context (like GetIP itself).  That's exactly the one 
that's also stored on the stack (well, on x86-64 at least, for other 
architectures it might be stored in a register and might be in encoded 
form), and is the one to be used to look up exception regions _except_ 
that you normally need to subtract one from it, because the IP stored in 
the context and stack points to after the insn you're interested in.  
Except for those situations where it doesn't, for which this function was 
introduced to start with, in order to be able to differ between those 
(basically the kernel needs to mark the signal frame as being the result 
of a fault or a trap, and GetIPInfo uses this to set the flag).


Ciao,
Michael.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH] Make _Unwind_GetIPInfo part of the ABI
@ 2016-01-01  0:00 Florian Weimer
  2016-01-01  0:00 ` Michael Matz
  0 siblings, 1 reply; 9+ messages in thread
From: Florian Weimer @ 2016-01-01  0:00 UTC (permalink / raw)
  To: H.J. Lu; +Cc: gnu-gabi

[-- Attachment #1: Type: text/plain, Size: 491 bytes --]

Without _Unwind_GetIPInfo, it is not possible to unwind correctly 
through signal handlers.  glibc needs this, otherwise cancellation does 
not work.

The attached patch documents this function and makes it part of the ABI. 
  I tried to explain as best as I could why this function is needed, 
without talking about exception handler regions.

The 32-bit ABI will need a similar change.

The second patch is for the Makefile, so that it doesn't ask for input 
on an error.

Thanks,
Florian

[-- Attachment #2: getipinfo.patch --]
[-- Type: text/x-patch, Size: 2246 bytes --]

diff --git a/libraries.tex b/libraries.tex
index 7c5d214..a539e6d 100644
--- a/libraries.tex
+++ b/libraries.tex
@@ -42,6 +42,7 @@ The unwind library interface consists of at least the following routines:\\
 \codeindex{\_Unwind\_GetGR},\\
 \codeindex{\_Unwind\_SetGR},\\
 \codeindex{\_Unwind\_GetIP},\\
+\codeindex{\_Unwind\_GetIPInfo},\\
 \codeindex{\_Unwind\_SetIP},\\
 \codeindex{\_Unwind\_GetRegionStart},\\
 \codeindex{\_Unwind\_GetLanguageSpecificData},\\
@@ -524,6 +525,41 @@ identified by the unwind context. This value may be outside of the
 procedure fragment for a function call that is known to not return
 (such as \code{\_Unwind\_Resume}).
 
+Applications which unwind through asynchronous signals and other
+non-call locations should use \code{\_Unwind\_GetIPInfo} below, and
+the additional flag that function provides.
+
+\subsubsection{\code{\_Unwind\_GetIPInfo}}
+
+\code{
+\begin{tabular}{l}
+    uint64 \_Unwind\_GetIPInfo\\
+    \ \ (struct \_Unwind\_Context *context, int *not\_nested);\\
+\end{tabular}
+}
+
+This function returns the same value as \code{\_Unwind\_GetIP}.  In
+addition, the argument \code{not\_nested} must not be not null, and
+\code{*not\_nested} is updated with a flag which indicates whether
+this unwind context refers to a call site which was reached through
+stack unwinding.
+
+If \code{*not\_nested} is false, the application calling
+\code{\_Unwind\_GetIPInfo} should assume that the instruction pointer
+provided points after a call instruction which has not yet returned.
+In general, this means that the application should use the preceding
+call instruction as the instruction pointer location of the unwind
+context.  Typically, this can be approximated by subtracting one from
+the returned instruction pointer.
+
+If \code{*not\_nested} is true, then the instruction pointer does not
+refer to an active call site.  Usually, this means that the
+instruction pointer refers to the point at which an asynchronous
+signal arrived.  In this case, the application should use the
+instruction pointer returned from \code{\_Unwind\_GetIPInfo} as the
+instruction pointer location of the unwind context, without
+adjustment.
+
 \subsubsection{\code{\_Unwind\_SetIP}}
 \code{
 \begin{tabular}{l}

[-- Attachment #3: makefile.patch --]
[-- Type: text/x-patch, Size: 666 bytes --]

diff --git a/Makefile b/Makefile
index 89dfd18..3fc1d65 100644
--- a/Makefile
+++ b/Makefile
@@ -5,6 +5,8 @@ INCLUDES  := execution.tex low-level-sys-info.tex development.tex      \
 
 ALL_FILES := abi.tex $(INCLUDES)
 
+TEXFLAGS = -interaction=nonstopmode -file-line-error
+
 .PHONY: all abi clean ps pdf update
 
 # default
@@ -14,14 +16,14 @@ all: abi.ps abi.pdf
 
 
 abi.dvi: $(ALL_FILES)
-	latex abi
+	latex $(TEXFLAGS) abi
 	makeindex abi
-	latex abi
-	latex abi
+	latex $(TEXFLAGS) abi
+	latex $(TEXFLAGS) abi
 
 # Depend on abi.dvi to get index.
 pdf abi.pdf: abi.dvi
-	pdflatex abi
+	pdflatex $(TEXFLAGS) abi
 
 ps abi.ps: abi.dvi
 	dvips abi.dvi -o abi.ps

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Make _Unwind_GetIPInfo part of the ABI
  2016-01-01  0:00     ` Michael Matz
@ 2016-01-01  0:00       ` Florian Weimer
  2016-01-01  0:00         ` H.J. Lu
  2016-01-01  0:00       ` Michael Matz
  1 sibling, 1 reply; 9+ messages in thread
From: Florian Weimer @ 2016-01-01  0:00 UTC (permalink / raw)
  To: Michael Matz; +Cc: H.J. Lu, gnu-gabi

On 10/21/2016 03:45 PM, Michael Matz wrote:
> Hi,
>
> On Fri, 21 Oct 2016, Florian Weimer wrote:
>
>> On 10/21/2016 02:58 PM, Michael Matz wrote:
>>> +This function returns the same value as \code{\_Unwind\_GetIP}.  In
>>> +addition, the argument \code{ip\_before\_insn} must not be not null, and
>>> +\code{*ip\_before\_insn} is updated with a flag which indicates whether
>>> +the returned pointer is at or after the first not yet fully executed
>>> +instruction.
>>
>> I think this is rather misleading.  On x86_64, the location of the IP
>> value is the same for calls and asynchronous signals: it always points
>> to the next instruction to be executed.
>
> No, that's simply wrong.  The saved instruction pointer points _at_ the
> instruction causing the fault for faults, and _after_ the instruction for
> traps.  Traps are things like single-stepping, breakpoints or INTO.  Most
> other interrupts are faults or aborts (the latter being imprecise and
> hence can't be restarted anyway).
>
> For calls the saved instruction pointer always points to after the call
> and hence can be handled like a trap for unwinding purposes.

Oh, then we are dealing with four different things: Calls, asynchronous 
signals (like the internal SIGCANCEL signal, which is how came to this 
topic), faults, and traps.

Using your terminology, traps are like calls (IP adjustment needed).  An 
SIGCANCEL signal is like a fault because no IP adjustment is allowed. 
The GCC unwinders currently treat all the signals the same, which causes 
it to use the wrong handler region for traps.

>> The difference that if we unwind through a call which has not yet
>> returned, the caller is assumed to be still within the exception
>> handling region in which the call instruction is located.  This is the
>> consequence of the desired exception handling semantics of a
>> non-returned function call.
>
> Unwinding through one call or one trap is the same.  The interesting
> instruction is the one ending right before the reported IP.

Agreed.

> Except for those situations where it doesn't, for which this function was
> introduced to start with, in order to be able to differ between those
> (basically the kernel needs to mark the signal frame as being the result
> of a fault or a trap, and GetIPInfo uses this to set the flag).

It's not really clear to me how the glibc unwinders tell traps from faults.

Florian

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Make _Unwind_GetIPInfo part of the ABI
  2016-01-01  0:00 [PATCH] Make _Unwind_GetIPInfo part of the ABI Florian Weimer
@ 2016-01-01  0:00 ` Michael Matz
  2016-01-01  0:00   ` Florian Weimer
  0 siblings, 1 reply; 9+ messages in thread
From: Michael Matz @ 2016-01-01  0:00 UTC (permalink / raw)
  To: Florian Weimer; +Cc: H.J. Lu, gnu-gabi

Hi,

On Fri, 21 Oct 2016, Florian Weimer wrote:

> Without _Unwind_GetIPInfo, it is not possible to unwind correctly 
> through signal handlers.  glibc needs this, otherwise cancellation does 
> not work.
> 
> The attached patch documents this function and makes it part of the ABI.  
> I tried to explain as best as I could why this function is needed, 
> without talking about exception handler regions.
> 
> The 32-bit ABI will need a similar change.
> 
> The second patch is for the Makefile, so that it doesn't ask for input 
> on an error.

Thanks, integrated in my copy, though I changed the text slightly to the 
below.  The parameter is customary called "ip_before_insn" (though that is 
wrong as well, and should be named "ip_at_insn" or the like).


Ciao,
Michael.

Index: libraries.tex
===================================================================
--- libraries.tex	(revision 251)
+++ libraries.tex	(working copy)
@@ -42,6 +42,7 @@ The unwind library interface consists of
 \codeindex{\_Unwind\_GetGR},\\
 \codeindex{\_Unwind\_SetGR},\\
 \codeindex{\_Unwind\_GetIP},\\
+\codeindex{\_Unwind\_GetIPInfo},\\
 \codeindex{\_Unwind\_SetIP},\\
 \codeindex{\_Unwind\_GetRegionStart},\\
 \codeindex{\_Unwind\_GetLanguageSpecificData},\\
@@ -524,6 +525,41 @@ identified by the unwind context. This v
 procedure fragment for a function call that is known to not return
 (such as \code{\_Unwind\_Resume}).
 
+Applications which unwind through asynchronous signals and other
+non-call locations should use \code{\_Unwind\_GetIPInfo} below, and
+the additional flag that function provides.
+
+\subsubsection{\code{\_Unwind\_GetIPInfo}}
+
+\code{
+\begin{tabular}{l}
+    uint64 \_Unwind\_GetIPInfo\\
+    \ \ (struct \_Unwind\_Context *context, int *ip\_before\_insn);\\
+\end{tabular}
+}
+
+This function returns the same value as \code{\_Unwind\_GetIP}.  In
+addition, the argument \code{ip\_before\_insn} must not be not null, and
+\code{*ip\_before\_insn} is updated with a flag which indicates whether
+the returned pointer is at or after the first not yet fully executed
+instruction.
+
+If \code{*ip\_before\_insn} is false, the application calling
+\code{\_Unwind\_GetIPInfo} should assume that the instruction pointer
+provided points after a call instruction which has not yet returned.
+In general, this means that the application should use the preceding
+call instruction as the instruction pointer location of the unwind
+context.  Typically, this can be approximated by subtracting one from
+the returned instruction pointer.
+
+If \code{*ip\_before\_insn} is true, then the instruction pointer does not
+refer to an active call site.  Usually, this means that the
+instruction pointer refers to the point at which an asynchronous
+signal arrived.  In this case, the application should use the
+instruction pointer returned from \code{\_Unwind\_GetIPInfo} as the
+instruction pointer location of the unwind context, without
+adjustment.
+
 \subsubsection{\code{\_Unwind\_SetIP}}
 \code{
 \begin{tabular}{l}

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Make _Unwind_GetIPInfo part of the ABI
  2016-01-01  0:00       ` Florian Weimer
@ 2016-01-01  0:00         ` H.J. Lu
  2016-01-01  0:00           ` Florian Weimer
  0 siblings, 1 reply; 9+ messages in thread
From: H.J. Lu @ 2016-01-01  0:00 UTC (permalink / raw)
  To: Florian Weimer; +Cc: Michael Matz, gnu-gabi

On Fri, Oct 21, 2016 at 11:11 AM, Florian Weimer <fweimer@redhat.com> wrote:
> On 10/21/2016 03:45 PM, Michael Matz wrote:
>>
>> Hi,
>>
>> On Fri, 21 Oct 2016, Florian Weimer wrote:
>>
>>> On 10/21/2016 02:58 PM, Michael Matz wrote:
>>>>
>>>> +This function returns the same value as \code{\_Unwind\_GetIP}.  In
>>>> +addition, the argument \code{ip\_before\_insn} must not be not null,
>>>> and
>>>> +\code{*ip\_before\_insn} is updated with a flag which indicates whether
>>>> +the returned pointer is at or after the first not yet fully executed
>>>> +instruction.
>>>
>>>
>>> I think this is rather misleading.  On x86_64, the location of the IP
>>> value is the same for calls and asynchronous signals: it always points
>>> to the next instruction to be executed.
>>
>>
>> No, that's simply wrong.  The saved instruction pointer points _at_ the
>> instruction causing the fault for faults, and _after_ the instruction for
>> traps.  Traps are things like single-stepping, breakpoints or INTO.  Most
>> other interrupts are faults or aborts (the latter being imprecise and
>> hence can't be restarted anyway).
>>
>> For calls the saved instruction pointer always points to after the call
>> and hence can be handled like a trap for unwinding purposes.
>
>
> Oh, then we are dealing with four different things: Calls, asynchronous
> signals (like the internal SIGCANCEL signal, which is how came to this
> topic), faults, and traps.
>
> Using your terminology, traps are like calls (IP adjustment needed).  An
> SIGCANCEL signal is like a fault because no IP adjustment is allowed. The
> GCC unwinders currently treat all the signals the same, which causes it to
> use the wrong handler region for traps.
>
>>> The difference that if we unwind through a call which has not yet
>>> returned, the caller is assumed to be still within the exception
>>> handling region in which the call instruction is located.  This is the
>>> consequence of the desired exception handling semantics of a
>>> non-returned function call.
>>
>>
>> Unwinding through one call or one trap is the same.  The interesting
>> instruction is the one ending right before the reported IP.
>
>
> Agreed.
>
>> Except for those situations where it doesn't, for which this function was
>> introduced to start with, in order to be able to differ between those
>> (basically the kernel needs to mark the signal frame as being the result
>> of a fault or a trap, and GetIPInfo uses this to set the flag).
>
>
> It's not really clear to me how the glibc unwinders tell traps from faults.
>
> Florian

We can set signal_frame to 0 for SIGCANCEL?

-- 
H.J.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Make _Unwind_GetIPInfo part of the ABI
  2016-01-01  0:00     ` Michael Matz
  2016-01-01  0:00       ` Florian Weimer
@ 2016-01-01  0:00       ` Michael Matz
  2016-01-01  0:00         ` Carlos O'Donell
  1 sibling, 1 reply; 9+ messages in thread
From: Michael Matz @ 2016-01-01  0:00 UTC (permalink / raw)
  To: Florian Weimer; +Cc: H.J. Lu, gnu-gabi

Hi,

On Fri, 21 Oct 2016, Michael Matz wrote:

> > On 10/21/2016 02:58 PM, Michael Matz wrote:
> > > +This function returns the same value as \code{\_Unwind\_GetIP}.  In
> > > +addition, the argument \code{ip\_before\_insn} must not be not null, and
> > > +\code{*ip\_before\_insn} is updated with a flag which indicates whether
> > > +the returned pointer is at or after the first not yet fully executed
> > > +instruction.
> > 
> > I think this is rather misleading.  On x86_64, the location of the IP 
> > value is the same for calls and asynchronous signals: it always points 
> > to the next instruction to be executed.
> 
> No, that's simply wrong.

Or rather, it isn't wrong, it's indeed pointing to the instruction to be 
executed next after return from handler, as always.  But that's not the 
important thing for unwinding: what you're interested in is the 
instruction that _caused_ the interruption, and for that what I said 
applies.


Ciao,
Michael.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Make _Unwind_GetIPInfo part of the ABI
  2016-01-01  0:00         ` H.J. Lu
@ 2016-01-01  0:00           ` Florian Weimer
  0 siblings, 0 replies; 9+ messages in thread
From: Florian Weimer @ 2016-01-01  0:00 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Michael Matz, gnu-gabi

On 10/21/2016 08:37 PM, H.J. Lu wrote:

>> It's not really clear to me how the glibc unwinders tell traps from faults.

(I meant to write “gcc unwinders”.)

> We can set signal_frame to 0 for SIGCANCEL?

No, SIGCANCEL is a signal frame for all intents in purposes.  (The bug 
was that __gcc_personality_v0 (the C unwinder) completely ignored signal 
frame hints on all architectures.)

The question if INTO should result in a signal frame.  Per Michael's 
comments, it should not because it is a trap and gets reported at the 
immediately following address (which can be in a completely different 
exception handling region).

Thanks,
Florian

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2016-10-21 18:52 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-01  0:00 [PATCH] Make _Unwind_GetIPInfo part of the ABI Florian Weimer
2016-01-01  0:00 ` Michael Matz
2016-01-01  0:00   ` Florian Weimer
2016-01-01  0:00     ` Michael Matz
2016-01-01  0:00       ` Florian Weimer
2016-01-01  0:00         ` H.J. Lu
2016-01-01  0:00           ` Florian Weimer
2016-01-01  0:00       ` Michael Matz
2016-01-01  0:00         ` Carlos O'Donell

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 read-only IMAP folder(s) and NNTP newsgroup(s).