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
fix: thread exit improvement for 10.14 and later #76
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
I had two ideas, either similar to this (trying to get the right arguments for bsdthread_terminate, plus other platforms make the calls in inline asm). Or alternatively see what happens if we just restart the thread by calling VG_(scheduler)(tid) I'll try to explain. At the point that we're trying to kill the thread we're in this line of code
(line 888 here https://github.com/apple-oss-distributions/libpthread/blob/libpthread-514/src/pthread.c) The client thread function is pointed to by If we can continue running the scheduler then it should execute _pthread_exit and clean up and kill the thread. It may be necessary to store the result of the guest thread function in RAX. I also suspect that the changes made to the stack in |
This would require reading the internal pthread struct right? (https://github.com/apple-oss-distributions/libpthread/blob/libpthread-514/src/pthread.c#L733) I couldn't find any place where Valgrind currently does that, it might also be a bit inconsistent between macOS (and thus libpthread) versions? Is there any point in doing the call in assembly?
Interesting, I will have a look. |
I really don't know what the right thing to do is. Not setting these values could cause a per-thread leak. But then we're creating the thread stack in pthread_hijack so maybe they should be 0 after all. The call in pthread,c is
We can get the first 3 args from 'self' and 'kport' passed to pthread_hijack.
I don't see why it was done, but there must have been some reason, possibly a long time ago and only on Linux copied by all the other ports.
The above looks one-way. A call instead of push/jmp might be needed. |
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
I dug into pthread a bit to understand the exact flow with the hijack (been a long time since I looked at it). Turns out, we already execute all the
So, all that we have left is to actually call
Ok, I looked at other ports, no harm to do it in assembly if it helps avoiding messing with the stack.
As explained above, that code is already running. In conclusion, this PR should be enough to solve the issue. Do you have any way to test on x86? It's been a long time since I last wrote assembly and I don't have any way to test outside amd64/arm64 macOS 13. |
@paulfloyd Tested with your dummy program and no crashes anymore. Is that the kind of things you had in mind?