Re: How to use __forced_unwind?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2023-05-31 22:28, Jonathan Wakely wrote:
> On Wed, 31 May 2023 at 21:27, J.W. Jagersma <jwjagersma@xxxxxxxxx> wrote:
>>
>> On 2023-05-31 22:24, Jonathan Wakely wrote:
>>> On Wed, 31 May 2023 at 21:23, J.W. Jagersma <jwjagersma@xxxxxxxxx> wrote:
>>>>
>>>> On 2023-05-31 22:18, Jonathan Wakely wrote:
>>>>> On Wed, 31 May 2023 at 21:15, J.W. Jagersma via Gcc-help
>>>>> <gcc-help@xxxxxxxxxxx> wrote:
>>>>>>
>>>>>> Hi all,
>>>>>>
>>>>>> In my cooperative scheduler I currently use a regular exception type for thread
>>>>>> cancellation.  But these tend to get eaten, for example by std::iosteam
>>>>>> functions.
>>>>>>
>>>>>> Now I see those functions do catch and rethrow a __cxxabiv1::__forced_unwind
>>>>>> type, and I presume such an object can be thrown via _Unwind_ForcedUnwind().
>>>>>>
>>>>>> But how do you actually use it?
>>>>>
>>>>> You don't. It exists for pthread_kill, not for users.
>>>>>
>>>>>> Specifically, how is the exception supposed to
>>>>>> be allocated, who is in charge of freeing it,
>>>>>
>>>>> The runtime does that as needed.
>>>>>
>>>>>> and how do you make sure it stops
>>>>>> where you want it to?
>>>>>
>>>>> You can't, it can never be stopped. If it is caught and not rethrown
>>>>> then the entire process is aborted. It must propagate to the initial
>>>>> function that was executed in the thread, and then when it leaves that
>>>>> function the thread is terminated.
>>>>
>>>> Okay, that's a bit unfortunate.  But why is it exposed in a public header then
>>>> if it's never supposed to be used by anyone?
>>>>
>>>> I understand doing something like this from user code is extremely messy,
>>>> but... that's how these things are.
>>>
>>> Why not just use pthread_kill(0) if you want a __forced_unwind exception?
>>
>> Single-threaded target, I don't have pthreads.  That's why I rolled my own.
> 
> Then you couldn't use __forced_unwind anyway, it would always
> terminate the program.

>From reading the Itanium ABI docs and glibc code I think I figured it out.  It
seems fairly straightforward even:

The stop function is supposed to just jump out when it hits end of stack.  So,
I can just call yield(), do a context switch, and delete the thread from there.
Same as I otherwise would when exiting a thread.  From the stop function I can
even print a neat backtrace when debugging.

The exception object also doesn't need to be allocated in any special way.  It
can simply be part of the thread struct itself.

The program only terminates if the cleanup function does so.  It is in fact
possible to catch and ignore the forced unwind, if cleanup does nothing.

All in all, it's not quite as messy as I had expected, and should be more
reliable than using regular exceptions.  I did notice though that the forced
unwind is not seen from std::uncaught_exceptions(), so that may require some
special handling.




[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux