* 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).