Skip to content

Commit

Permalink
Fix #22972 - deadlock in :: fixed by handling ^C ##crash
Browse files Browse the repository at this point in the history
  • Loading branch information
radare authored and trufae committed May 28, 2024
1 parent 3dd4a78 commit b9cbd35
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 13 deletions.
25 changes: 23 additions & 2 deletions libr/core/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -4407,6 +4407,22 @@ R_API PJ *r_core_pj_new(RCore *core) {
return pj_new_with_encoding (string_encoding, number_encoding);
}

static void channel_stop(void *u) {
// RCore *core = (RCore *)u;
RThreadChannelPromise *promise = (RThreadChannelPromise*)u;
promise->tc->responses = NULL;
r_th_lock_leave (promise->tc->lock);
#if 0
r_th_lock_free (promise->tc->lock);
#endif
promise->tc->lock = NULL;
// r_th_channel_promise_free (promise);
#if 0
r_th_channel_free (core->chan);
core->chan = NULL;
#endif
}

// reentrant version of RCore.cmd()
R_API char *r_core_cmd_str_r(RCore *core, const char *cmd) {
if (r_str_startswith (cmd, "::")) {
Expand All @@ -4417,13 +4433,18 @@ R_API char *r_core_cmd_str_r(RCore *core, const char *cmd) {
}
RThreadChannelMessage *message = r_th_channel_message_new (core->chan, (const ut8*)cmd, strlen (cmd) + 1);
RThreadChannelPromise *promise = r_th_channel_query (core->chan, message);
r_cons_break_push (channel_stop, promise);
RThreadChannelMessage *response = r_th_channel_promise_wait (promise);
char *res = response->msg? strdup ((const char *)response->msg): NULL;
char *res = NULL;
if (response) {
res = response->msg? strdup ((const char *)response->msg): NULL;
}
// r_cons_printf ("%s", response->msg);
r_th_channel_message_free (message);
r_th_channel_promise_free (promise);
if (message != response) {
if (response && message != response) {
r_th_channel_message_free (response);
}
r_cons_break_pop ();
return res;
}
16 changes: 10 additions & 6 deletions libr/util/thread_chan.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,16 @@ R_API RThreadChannelMessage *r_th_channel_promise_wait(RThreadChannelPromise *pr
while (true) {
RListIter *iter;
RThreadChannelMessage *res;
r_th_lock_enter (promise->tc->lock);
r_list_foreach (promise->tc->responses, iter, res) {
if (res->id == promise->id) {
r_list_split_iter (promise->tc->responses, iter);
r_th_lock_leave (promise->tc->lock);
return res;
if (!r_th_lock_enter (promise->tc->lock)) {
break;
}
if (promise->tc->responses) {
r_list_foreach (promise->tc->responses, iter, res) {
if (res->id == promise->id) {
r_list_split_iter (promise->tc->responses, iter);
r_th_lock_leave (promise->tc->lock);
return res;
}
}
}
r_th_lock_leave (promise->tc->lock);
Expand Down
17 changes: 12 additions & 5 deletions libr/util/thread_lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,10 @@ R_API bool r_th_lock_wait(RThreadLock *thl) {

#if WANT_THREADS
R_API bool r_th_lock_enter(RThreadLock *thl) {
r_return_val_if_fail (thl, false);
if (!thl) {
return false;
}
// r_return_val_if_fail (thl, false);
R_LOG_DEBUG ("r_th_lock_enter");

// initialize static locks on acquisition
Expand All @@ -107,12 +110,12 @@ R_API bool r_th_lock_enter(RThreadLock *thl) {
r_atomic_store (&thl->activating, false);
}
#if HAVE_PTHREAD
return pthread_mutex_lock (&thl->lock);
return pthread_mutex_lock (&thl->lock) == 0;
#elif R2__WINDOWS__
EnterCriticalSection (&thl->lock);
return 0;
return true;
#else
return 0;
return true;
#endif
}
R_API bool r_th_lock_tryenter(RThreadLock *thl) {
Expand All @@ -126,8 +129,12 @@ R_API bool r_th_lock_tryenter(RThreadLock *thl) {
return false;
#endif
}

R_API bool r_th_lock_leave(RThreadLock *thl) {
r_return_val_if_fail (thl, false);
if (!thl) {
return false;
}
//r_return_val_if_fail (thl, false);
R_LOG_DEBUG ("r_th_lock_leave");
#if HAVE_PTHREAD
return pthread_mutex_unlock (&thl->lock) == 0;
Expand Down

0 comments on commit b9cbd35

Please sign in to comment.