Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make exit_on_sigint work again #17727

Merged
merged 2 commits into from
Aug 10, 2016
Merged

Make exit_on_sigint work again #17727

merged 2 commits into from
Aug 10, 2016

Conversation

yuyichao
Copy link
Contributor

@yuyichao yuyichao commented Jul 31, 2016

  • Add more try-catch and sigatomic for top-level code/new tasks

    So that we don't need to run jl_exit in strange (signal handler) context
    due to missing exception handler.

  • Implement jl_call_in_ctx on unix.

    Use it to make sure that jl_rethrow and jl_exit are running on the right
    thread and right stack when an exception/exit is caused by a signal.

    Fix Unreliable SIGINT delivery #17706

Tested locally on Linux x86/x64/aarch64/arm and Mac (windows sigint handling seems to be really unreliable in general). According to musl source code, it should work there too. Implementation on platforms that I don't have access to (FreeBSD, PowerPC) is left as an exercise for people who do. =)

This uses assembly to set the register values instead of using sigreturn since it doesn't work reliably on Mac and may not work in the future due to mitigation of sigreturn oriented programming. (Just like all other low level features that we want to use that is blocked by security fixes....)

The final implementation is on the edge of what I'm happy to merge during feature freeze/backport after branching so I'll let others decide when this should be merge and whether it should be backported to 0.5 branch.

// (Only a few actually needs these but doesn't hurt to do on all of them).
rsp &= -16; // ensure 16-byte alignment
rsp -= 128; // 128bytes red zone
#if defined(_CPU_X86_64_)
Copy link
Member

@vtjnash vtjnash Jul 31, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tkelman's going to complain that MSVC doesn't support the asm keyword

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, this is in ...-unix.c, I'll be happy to learn how to write this in msvc compatible way when we support using MSVC to build for unix =)

@vtjnash
Copy link
Member

vtjnash commented Jul 31, 2016

looks like a good improvement to me

@@ -105,6 +105,7 @@ suppress_excp_printing(t::Task) = isa(t.storage, ObjectIdDict) ? get(get_task_tl

# runtime system hook called when a task finishes
function task_done_hook(t::Task)
# `finish_task` set `sigatomic` before entering this function
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sets?

@yuyichao yuyichao force-pushed the yyc/signals/safer-exit branch from 3c56850 to 9648228 Compare July 31, 2016 06:06
@yuyichao
Copy link
Contributor Author

yuyichao commented Jul 31, 2016

Go back to modifying the ucontext since the concern I had was mainly due to a misunderstanding of a LWN article....

I'll need to repeat the test on the 5 architectures again.

@yuyichao
Copy link
Contributor Author

Tests (make sure Ctrl-C with exit_on_sigint doesn't segfault most of the time) all passed.

I left jl_get_rsp_from_ctx as a separate function (it was not in an earlier implementation that modifies ucontext) since it is also useful for GC debugging code.

// Do not use the main stack if this is a stack overflow since that will
// not work....
if (e == jl_stackovf_exception)
jl_rethrow();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

on mach, we re-use the signal stack for the rethrow call. should we eventually do that here too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set sp to the top of the signal stack and jmp to the function?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it does jl_call_in_ctx with sp set to the top of the signal stack (ptls2->signal_stack + sig_stack_size), to preserve call to sigreturn (and in the mach case, to get back to the right tid)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, Just need quite a bit of signal stack space for this to be reliable.

@ViralBShah ViralBShah added this to the 0.5.x milestone Jul 31, 2016
@yuyichao yuyichao force-pushed the yyc/signals/safer-exit branch from 9648228 to 81ca3e6 Compare August 1, 2016 00:12
@yuyichao
Copy link
Contributor Author

yuyichao commented Aug 1, 2016

Increase the signal stack size and use that stack for every call from the signal handler now.
This version relies much less on low level access to ucontext (only for playing nicely with the kernel). Also added a signal stack overflow detection (and call _exit).

kern_return_t ret = thread_suspend(thread);
HANDLE_MACH_ERROR("thread_suspend", ret);

// This abort `sleep` and other syscall.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aborts sleep and other syscalls

@yuyichao yuyichao force-pushed the yyc/signals/safer-exit branch 2 times, most recently from bf8479e to 82f0b93 Compare August 2, 2016 06:21
@JeffBezanson
Copy link
Member

I would probably not put this in 0.5.0 but can go in 0.5.x once we're confident that it works well.

@yuyichao yuyichao modified the milestones: 0.6.0, 0.5.x Aug 2, 2016
@vtjnash
Copy link
Member

vtjnash commented Aug 9, 2016

what's left on this? it lgtm, and it's after branching now so that resolves the question of whether to do it before.

@yuyichao
Copy link
Contributor Author

Should be ready. I guess I need to rebase though.

So that we don't need to run `jl_exit` in strange (signal handler) context
due to missing exception handler.
Use it to make sure that `jl_rethrow` and `jl_exit` are running on the right
thread and right stack when an exception/exit is caused by a signal.

Fix #17706
@yuyichao yuyichao force-pushed the yyc/signals/safer-exit branch from 82f0b93 to 03c3c70 Compare August 10, 2016 06:43
@yuyichao
Copy link
Contributor Author

Rebased.

@yuyichao yuyichao merged commit a57b50d into master Aug 10, 2016
@yuyichao yuyichao deleted the yyc/signals/safer-exit branch August 10, 2016 11:27
tkelman pushed a commit that referenced this pull request Aug 20, 2016
(cherry picked from commit 6a62d30)
ref #18063

Conflicts:
	src/signals-unix.c

Not including changes to jl_call_in_ctx in this file because those
changes were part of #17727
which has not been backported to release-0.5 at this time.
maleadt added a commit that referenced this pull request Aug 20, 2016
This makes the SIGINT signal handler work in combination with ASAN.
@maleadt
Copy link
Member

maleadt commented Aug 20, 2016

I've extracted the signal stack size change for backporting: see 467e181. @yuyichao, does this look OK?

@yuyichao
Copy link
Contributor Author

Yeah, should be fine and it should fix most of the symptoms.

maleadt added a commit that referenced this pull request Aug 21, 2016
This makes the SIGINT signal handler work in combination with ASAN.

(partially cherry picked from commit 03c3c70, ref #17727)
maleadt added a commit that referenced this pull request Aug 21, 2016
This makes the SIGINT signal handler work in combination with ASAN.

(partially cherry picked from commit 03c3c70, ref #17727)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unreliable SIGINT delivery
6 participants