Skip to content

Commit

Permalink
fix: modify format
Browse files Browse the repository at this point in the history
  • Loading branch information
onroadmuwl committed Dec 18, 2023
1 parent 51d2b86 commit 1956e11
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 56 deletions.
49 changes: 3 additions & 46 deletions core/synch.c
Original file line number Diff line number Diff line change
Expand Up @@ -2301,55 +2301,41 @@ detach_externally_on_linux()
thread_id_t my_id;
DEBUG_DECLARE(bool ok;)
DEBUG_DECLARE(int exit_res;)

/* synch-all flags: */
uint flags = 0;

/* For Unix, such privilege problems are rarer but we would still prefer to
* continue if we hit a problem.
*/
flags |= THREAD_SYNCH_SUSPEND_FAILURE_IGNORE;

/* i#297: we only synch client threads after process exit event. */
flags |= THREAD_SYNCH_SKIP_CLIENT_THREAD;

ENTERING_DR();

/* dynamo_detaching_flag is not really a lock, and since no one ever waits
* on it we can't deadlock on it either.
*/
if (!atomic_compare_exchange(&dynamo_detaching_flag, LOCK_FREE_STATE, LOCK_SET_STATE))
return;

instrument_pre_detach_event();

/* Unprotect .data for exit cleanup.
* XXX: more secure to not do this until we've synched, but then need
* alternative prot for started_detach and init_apc_go_native*
*/
SELF_UNPROTECT_DATASEC(DATASEC_RARELY_PROT);

ASSERT(!started_detach);
started_detach = true;

ASSERT(dynamo_initialized);
ASSERT(!dynamo_exited);

my_id = d_r_get_thread_id();
my_dcontext = get_thread_private_dcontext();
ASSERT(my_dcontext != NULL);

LOG(GLOBAL, LOG_ALL, 1, "Detach: thread %d starting detach process\n", my_id);
SYSLOG(SYSLOG_INFORMATION, INFO_DETACHING, 2, get_application_name(),
get_application_pid());

/* synch with flush */
if (my_dcontext != NULL)
enter_threadexit(my_dcontext);

/* i#2270: we ignore alarm signals during detach to reduce races. */
signal_remove_alarm_handlers(my_dcontext);

/* suspend all DR-controlled threads at safe locations */
if (!synch_with_all_threads(THREAD_SYNCH_SUSPENDED_VALID_MCONTEXT, &threads,
&num_threads,
Expand All @@ -2362,47 +2348,40 @@ detach_externally_on_linux()
REPORT_FATAL_ERROR_AND_EXIT(FAILED_TO_SYNCHRONIZE_THREADS, 2,
get_application_name(), get_application_pid());
}

/* Now we own the thread_initexit_lock. We'll release the locks grabbed in
* synch_with_all_threads below after cleaning up all the threads in case we
* need to grab it during process exit cleanup.
*/
ASSERT(mutex_testlock(&all_threads_synch_lock) &&
mutex_testlock(&thread_initexit_lock));

ASSERT(!doing_detach);
doing_detach = true;
detacher_tid = d_r_get_thread_id();

#ifdef HOT_PATCHING_INTERFACE
/* In hotp_only mode, we must remove patches when detaching; we don't want
* to leave in all our hooks and detach; that will definitely crash the app.
*/
if (DYNAMO_OPTION(hotp_only))
hotp_only_detach_helper();
#endif

if (!DYNAMO_OPTION(thin_client))
revert_memory_regions();
unhook_vsyscall();
LOG(GLOBAL, LOG_ALL, 1,
"Detach : unpatched ntdll.dll and fixed memory permissions\n");

/* perform exit tasks that require full thread data structs */
dynamo_process_exit_with_thread_info();

LOG(GLOBAL, LOG_ALL, 1, "Detach: starting to translate contexts\n");
for (i = 0; i < num_threads; i++) {
priv_mcontext_t mc;
if (threads[i]->dcontext == my_dcontext) {
my_idx = i;
my_tr = threads[i];

DEBUG_DECLARE(ok =)
thread_get_nudged_mcontext(threads[i], &my_mcontext);

DEBUG_DECLARE(ok =)
translate_mcontext(threads[i], &my_mcontext, true /*restore mem*/, NULL /*f*/);
translate_mcontext(threads[i], &my_mcontext, true /*restore mem*/,
NULL /*f*/);
ASSERT(!is_dynamo_address(my_mcontext.pc) && !in_fcache(my_mcontext.pc));
ASSERT(!in_fcache(my_mcontext.pc));
ASSERT(!is_dynamo_address(my_mcontext.pc));
Expand All @@ -2417,18 +2396,15 @@ detach_externally_on_linux()
threads[i]->id);
} else {
LOG(GLOBAL, LOG_ALL, 2, "Detach: translating " TIDFMT "\n", threads[i]->id);

DEBUG_DECLARE(ok =)
thread_get_mcontext(threads[i], &mc);
ASSERT(ok);

/* For a thread at a syscall, we use SA_RESTART for our suspend signal,
* so the kernel will adjust the restart point back to the syscall for us
* where expected. This is an artifical signal we're introducing, so an
* app that assumes no signals and assumes its non-auto-restart syscalls
* don't need loops could be broken.
*/

LOG(GLOBAL, LOG_ALL, 3,
/* Having the code bytes can help diagnose post-detach where the code
* cache is gone.
Expand All @@ -2437,14 +2413,12 @@ detach_externally_on_linux()
"for thread " TIDFMT "\n",
mc.pc, *mc.pc, *(mc.pc + 1), *(mc.pc + 2), *(mc.pc + 3), *(mc.pc + 4),
mc.xsp, threads[i]->id);

DEBUG_DECLARE(ok =)
translate_mcontext(threads[i], &mc, true /*restore mem*/, NULL /*f*/);
ASSERT(ok);

if (!threads[i]->under_dynamo_control) {
dr_printf("Detach : thread " TIDFMT " already running natively\n",
threads[i]->id);
threads[i]->id);
LOG(GLOBAL, LOG_ALL, 1,
"Detach : thread " TIDFMT " already running natively\n",
threads[i]->id);
Expand All @@ -2454,7 +2428,6 @@ detach_externally_on_linux()
put_back_native_retaddrs(threads[i]->dcontext);
}
}

LOG(GLOBAL, LOG_ALL, 1, "Detach: pc=" PFX " for thread " TIDFMT "\n", mc.pc,
threads[i]->id);
ASSERT(!is_dynamo_address(mc.pc) && !in_fcache(mc.pc));
Expand All @@ -2463,31 +2436,25 @@ detach_externally_on_linux()
* structures for the handler, it could result in a codemod exception
* that wouldn't happen natively!
*/

DEBUG_DECLARE(ok =)
thread_set_mcontext(threads[i], &mc);
ASSERT(ok);

}
/* Resumes the thread, which will do kernel-visible cleanup of
* signal state. Resume happens within the synch_all region where
* the thread_initexit_lock is held so that we can clean up thread
* data later.
*/
os_signal_thread_detach(threads[i]->dcontext);

LOG(GLOBAL, LOG_ALL, 1, "Detach: thread " TIDFMT " is being resumed as native\n",
threads[i]->id);

os_thread_resume(threads[i]);
}

LOG(GLOBAL, LOG_ALL, 1, "Detach: waiting for threads to fully detach\n");
for (i = 0; i < num_threads; i++) {
if (i != my_idx && !IS_CLIENT_THREAD(threads[i]->dcontext))
os_wait_thread_detached(threads[i]->dcontext);
}

/* Clean up each thread now that everyone has gone native. Needs to be
* done with the thread_initexit_lock held, which is true within a synched
* region.
Expand All @@ -2499,36 +2466,26 @@ detach_externally_on_linux()
dynamo_other_thread_exit(threads[i] _IF_WINDOWS(!cleanup_tpc[i]));
}
}

if (my_idx != -1) {
/* pre-client thread cleanup (PR 536058) */
dynamo_thread_exit_pre_client(my_dcontext, my_tr->id);
}

LOG(GLOBAL, LOG_ALL, 1, "Detach: Letting secondary threads go native\n");
end_synch_with_all_threads(threads, num_threads, false /*don't resume */);
threads = NULL;

LOG(GLOBAL, LOG_ALL, 1, "Detach: Entering final cleanup and unload\n");
SYSLOG_INTERNAL_INFO("Detaching from process, entering final cleanup");

DEBUG_DECLARE(exit_res =)
dynamo_shared_exit(my_tr _IF_WINDOWS(detach_stacked_callbacks));

ASSERT(exit_res == SUCCESS);
detach_finalize_cleanup();

stack_free(d_r_initstack, DYNAMORIO_STACK_SIZE);

dynamo_exit_post_detach();

doing_detach = false;
started_detach = false;

SELF_PROTECT_DATASEC(DATASEC_RARELY_PROT);
dynamo_detaching_flag = LOCK_FREE_STATE;
EXITING_DR();
options_detach();

thread_set_self_mcontext(&my_mcontext);
}
2 changes: 1 addition & 1 deletion core/unix/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -8483,7 +8483,7 @@ handle_suspend_signal(dcontext_t *dcontext, kernel_siginfo_t *siginfo,

if (is_sigqueue_supported() && SUSPEND_SIGNAL == NUDGESIG_SIGNUM) {
nudge_arg_t *arg = (nudge_arg_t *)siginfo;
if (!TEST(NUDGE_IS_SUSPEND, arg->flags)){
if (!TEST(NUDGE_IS_SUSPEND, arg->flags)) {
sig_full_initialize(&sc_full, ucxt);
ostd->nudged_sigcxt = &sc_full;
return handle_nudge_signal(dcontext, siginfo, ucxt);
Expand Down
2 changes: 1 addition & 1 deletion suite/tests/client-interface/detach_test.dll.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ dr_exit(void)
#ifdef WINDOWS
dr_fprintf(STDERR, "done\n");
#else
/* The app prints 'done' for us. */
/* The app prints 'done' for us. */
#endif
}

Expand Down
16 changes: 8 additions & 8 deletions tools/drdeploy.c
Original file line number Diff line number Diff line change
Expand Up @@ -1216,9 +1216,9 @@ _tmain(int argc, TCHAR *targv[])
bool exit0 = false;
#endif
#if defined(DRCONFIG)
#if defined(WINDOWS) || defined(LINUX)
# if defined(WINDOWS) || defined(LINUX)
process_id_t detach_pid = 0;
# endif
# endif
#endif
char *drlib_path = NULL;
#if defined(DRCONFIG) || defined(DRRUN)
Expand Down Expand Up @@ -1515,7 +1515,7 @@ _tmain(int argc, TCHAR *targv[])
nudge_arg = _strtoui64(argv[++i], NULL, 16);
}
# endif
#if defined(WINDOWS) || defined(LINUX)
# if defined(WINDOWS) || defined(LINUX)
else if (strcmp(argv[i], "-detach") == 0) {
if (i + 1 >= argc)
usage(false, "detach requires a process id");
Expand Down Expand Up @@ -1845,21 +1845,22 @@ _tmain(int argc, TCHAR *targv[])
die();
}
# ifndef WINDOWS
# ifdef LINUX
# ifdef LINUX
else if (detach_pid != 0) {
siginfo_t info;
uint action_mask = 0x04;
client_id_t client_id = 0;
uint64 client_arg = 0;
bool success = create_nudge_signal_payload(&info, action_mask, 0, client_id, client_arg);
bool success =
create_nudge_signal_payload(&info, action_mask, 0, client_id, client_arg);
assert(success); /* failure means kernel's sigqueueinfo has changed */

/* send the nudge */
i = syscall(SYS_rt_sigqueueinfo, detach_pid, NUDGESIG_SIGNUM, &info);
if (i < 0)
fprintf(stderr, "nudge FAILED with error %d\n", i);
}
# endif
# endif
else {
usage(false, "no action specified");
}
Expand Down Expand Up @@ -1899,8 +1900,7 @@ _tmain(int argc, TCHAR *targv[])
list_process(NULL, global, dr_platform, iter);
dr_registered_process_iterator_stop(iter);
}
}
else if (detach_pid != 0) {
} else if (detach_pid != 0) {
dr_config_status_t res = detach(detach_pid, TRUE, detach_timeout);
if (res != DR_SUCCESS)
error("unable to detach: check pid and system ptrace permissions");
Expand Down

0 comments on commit 1956e11

Please sign in to comment.