-
Notifications
You must be signed in to change notification settings - Fork 574
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
i#5383: macOS a64 client threads and private TLS #7300
base: master
Are you sure you want to change the base?
Conversation
cat_spin: | ||
CALLC2(GLOBAL_REF(atomic_swap), x26, #1) | ||
CALLC2(GLOBAL_REF(atomic_swap), x0, #1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had to change since x26 is used on line 365
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, works out I think b/c it's in the 1st arg slot already, but it can be fragile to use the calling conv params in the args of CALL* b/c they can be clobbered by other args in arg setup.
@@ -1246,7 +1246,7 @@ signal_thread_inherit(dcontext_t *dcontext, void *clone_record) | |||
* FIXME: are current pending or blocked inherited? | |||
*/ | |||
#ifdef MACOS | |||
if (record->app_thread_xsp != 0) { | |||
if (record->app_thread_xsp == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really understand this code but you'll get heap oob/uaf asserts if this condition is !=
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is freeing the clone record.
See the comment in clone_record_t:
#ifdef MACOS
/* XXX i#1403: once we have lower-level, earlier thread interception we can
* likely switch to something closer to what we do on Linux.
* This is used for bsdthread_create, where app_thread_xsp is NULL;
* for vfork, app_thread_xsp is non-NULL and this is unused.
*/
This change != to == looks suspect. Please double check vs this pasted comment: if bsdthread_create ends up different on aarch64 please update that comment; does it need separate handling a64 vs x86.
Some messy stuff I'm not sure if there's a better way to do:
You'll get a backtrace like this if we do not maintain a valid thread register during entry and exit.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for contributing. I have mostly style comments but also some points need clarifying.
cat_spin: | ||
CALLC2(GLOBAL_REF(atomic_swap), x26, #1) | ||
CALLC2(GLOBAL_REF(atomic_swap), x0, #1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, works out I think b/c it's in the 1st arg slot already, but it can be fragile to use the calling conv params in the args of CALL* b/c they can be clobbered by other args in arg setup.
@@ -325,48 +325,6 @@ new_thread_setup(priv_mcontext_t *mc) | |||
ASSERT_NOT_REACHED(); | |||
} | |||
|
|||
# if defined(MACOS) && defined(X86) | |||
/* Called from new_bsdthread_intercept for targeting a bsd thread user function. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Despite the legacy name, this file "x86_code.c" is used with asm code on all arches and not just x86. I don't think this should be moved if the only reason was the file name. If you want to rename it to asm_aux.c or something like that, that seems reasonable.
@@ -85,6 +85,11 @@ | |||
# include "vmkuw.h" | |||
#endif | |||
|
|||
#if defined(MACOS) && defined(AARCH64) | |||
# include "unix/tls.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally we avoid including private headers: os_public.h and os_exports.h are what are supposed to be public.
@@ -2246,6 +2257,19 @@ dynamo_thread_init(byte *dstack_in, priv_mcontext_t *mc, void *os_data, | |||
return SUCCESS; | |||
} | |||
|
|||
/* macOS aarch64 will sometimes crash when acquiring locks if TLS is NULL */ | |||
#if defined(MACOS) && defined(AARCH64) | |||
void *tmp_tls = NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move this inside a unix/ file and export a function to call here.
@@ -2300,6 +2324,13 @@ dynamo_thread_init(byte *dstack_in, priv_mcontext_t *mc, void *os_data, | |||
} | |||
|
|||
os_tls_init(); | |||
#if defined(MACOS) && defined(AARCH64) | |||
if (tmp_tls) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here: let's isolate TLS details like this inside unix/
return new_thread; | ||
# else | ||
/* NYI */ | ||
return -1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add ASSERT_NOT_IMPLEMENTED and up put a XXX comment with an issue number.
# ifdef X64 | ||
/* Also update the pthread->fun and pthread->arg fields, since _pthread_start uses | ||
* them instead of the syscall arg0 on some macOS versions */ | ||
ASSERT(sys_param(dcontext, 3) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: explicit bools
/* Also update the pthread->fun and pthread->arg fields, since _pthread_start uses | ||
* them instead of the syscall arg0 on some macOS versions */ | ||
ASSERT(sys_param(dcontext, 3) && | ||
"bsdthread_create pthread argument should not be NULL"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use ASSERT_MESSAGE
# ifdef X64 | ||
/* Also update the pthread->fun and pthread->arg fields, since _pthread_start uses | ||
* them instead of the syscall arg0 on some macOS versions */ | ||
ASSERT(sys_param(dcontext, 3) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should ever assert on an app-supplied value: we want to be able to run any app. If the parameter is null, just skip this code gracefully. Use ASSERT_CURIOSITY if you want a non-fatal notification, or SYSLOG_INTERNAL_WARNING for a less visible one.
@@ -1246,7 +1246,7 @@ signal_thread_inherit(dcontext_t *dcontext, void *clone_record) | |||
* FIXME: are current pending or blocked inherited? | |||
*/ | |||
#ifdef MACOS | |||
if (record->app_thread_xsp != 0) { | |||
if (record->app_thread_xsp == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is freeing the clone record.
See the comment in clone_record_t:
#ifdef MACOS
/* XXX i#1403: once we have lower-level, earlier thread interception we can
* likely switch to something closer to what we do on Linux.
* This is used for bsdthread_create, where app_thread_xsp is NULL;
* for vfork, app_thread_xsp is non-NULL and this is unused.
*/
This change != to == looks suspect. Please double check vs this pasted comment: if bsdthread_create ends up different on aarch64 please update that comment; does it need separate handling a64 vs x86.
Adds macOS ARM64 support for client threads and private TLS (under
-private_loader
-- though we don't implement a full private loader yet).The end result is that client threads can start and terminate properly, and multithreaded applications can also terminate without crashing. I did not test attach/detach, but I'm guessing it's still broken (there is no injector implementation anyway iiuc)