[ANNOUNCEMENT] TEST RELEASE: Cygwin 2.1.0-0.1
Ken Brown
kbrown@cornell.edu
Fri Jun 26 14:34:00 GMT 2015
Hi Corinna,
On 6/26/2015 10:14 AM, Corinna Vinschen wrote:
> Hi Ken,
>
> On Jun 26 08:02, Ken Brown wrote:
>> On 6/26/2015 7:12 AM, Corinna Vinschen wrote:
>>> On Jun 22 13:08, Corinna Vinschen wrote:
>>>> On Jun 21 14:47, Ken Brown wrote:
>>>>> On 6/20/2015 4:55 PM, Corinna Vinschen wrote:
>>>>>> - First cut of an implementation to allow signal handlers running on an
>>>>>> alternate signal stack.
>>>>>>
>>>>>> - New API sigaltstack, plus definitions for SA_ONSTACK, SS_ONSTACK, SS_DISABLE,
>>>>>> MINSIGSTKSZ, SIGSTKSZ.
>>>>> [...]
>>>> [...]
>>> did you have a chance to test this a bit, in the meantime?
>>
>> Yes, but I don't have anything definitive to report yet. I tried to test a
>> facility in emacs that uses the alternate stack to recover from stack
>> overflow (of the main stack) under some circumstances. The configure script
>> did detect the alternate stack.
>>
>> I then made the stack overflow by defining an elisp function that did an
>> infinite recursion. emacs still crashed, but the "segmentation fault"
>> message was printed twice instead of once. I haven't had a chance yet to
>> investigate further and try to see what's going on. What I hope is that the
>> alternate stack functioned correctly but the code was still not able to
>> recover for some reason. I've appended below the signal handler in case you
>> want to see if you think it ought to work on Cygwin.
>
> Thank you. I'll try to test this in the next couple of days. One hint
> and one question:
>
>> The signal handler:
>>
>> /* Attempt to recover from SIGSEGV caused by C stack overflow. */
>> static void
>> handle_sigsegv (int sig, siginfo_t *siginfo, void *arg)
>> {
>> /* Hard GC error may lead to stack overflow caused by
>> too nested calls to mark_object. No way to survive. */
>> if (!gc_in_progress)
>> {
>> struct rlimit rlim;
>>
>> if (!getrlimit (RLIMIT_STACK, &rlim))
>
> This getrlimit probably won't work as desired. I just had a quick look
> how this request is handled. It will return the size of the alternate
> stack while running the signal handler, rather than the size of the
> initial thread's stack as required by POSIX. This definitely needs
> fixing.
>
>> {
>> enum { STACK_DANGER_ZONE = 16 * 1024 };
>> char *beg, *end, *addr;
>>
>> beg = stack_bottom;
>> end = stack_bottom + stack_direction * rlim.rlim_cur;
>> if (beg > end)
>> addr = beg, beg = end, end = addr;
>> addr = (char *) siginfo->si_addr;
>> /* If we're somewhere on stack and too close to
>> one of its boundaries, most likely this is it. */
>> if (beg < addr && addr < end
>> && (addr - beg < STACK_DANGER_ZONE
>> || end - addr < STACK_DANGER_ZONE))
>> siglongjmp (return_to_command_loop, 1);
>> }
>> }
>>
>> /* Otherwise we can't do anything with this. */
>> deliver_fatal_thread_signal (sig);
>> }
>>
>> The code to set up the signal handler on the alternate stack:
>>
>> static bool
>> init_sigsegv (void)
>> {
>> struct sigaction sa;
>> stack_t ss;
>>
>> stack_direction = ((char *) &ss < stack_bottom) ? -1 : 1;
>>
>> ss.ss_sp = sigsegv_stack;
>> ss.ss_size = sizeof (sigsegv_stack);
> ^^^^^^^^^^^^^^^^^^^^^^^
>
> What's that size in bytes?
SIGSTKSZ
>> ss.ss_flags = 0;
>> if (sigaltstack (&ss, NULL) < 0)
>> return 0;
>>
>> sigfillset (&sa.sa_mask);
>> sa.sa_sigaction = handle_sigsegv;
>> sa.sa_flags = SA_SIGINFO | SA_ONSTACK | emacs_sigaction_flags ();
>> return sigaction (SIGSEGV, &sa, NULL) < 0 ? 0 : 1;
Ken
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
More information about the Cygwin
mailing list