From c82fba943e4669e51ce6ac129eec39659d378ca5 Mon Sep 17 00:00:00 2001 From: Gust Date: Sat, 24 Feb 2024 22:31:32 +0800 Subject: [PATCH] fix jdwp thread dead lock --- minijvm/c/jvm/garbage.c | 2 +- minijvm/c/jvm/jdwp.c | 32 ++++++++++++++------------------ minijvm/c/jvm/jni_std.c | 1 + minijvm/c/jvm/jvm.c | 3 +++ minijvm/c/jvm/jvm.h | 8 ++++++++ minijvm/c/jvm/jvm_util.c | 6 +++++- 6 files changed, 32 insertions(+), 20 deletions(-) diff --git a/minijvm/c/jvm/garbage.c b/minijvm/c/jvm/garbage.c index b8974bb7..dbfa6ad1 100644 --- a/minijvm/c/jvm/garbage.c +++ b/minijvm/c/jvm/garbage.c @@ -67,7 +67,7 @@ s32 gc_create(MiniJVM *jvm) { collector->runtime_refer_copy = arraylist_create(256); collector->runtime = runtime_create(jvm); - + collector->runtime->thrd_info->type = THREAD_TYPE_GC; collector->_garbage_thread_status = GARBAGE_THREAD_PAUSE; thread_lock_init(&jvm->threadlock); diff --git a/minijvm/c/jvm/jdwp.c b/minijvm/c/jvm/jdwp.c index 7877e1a8..243155e4 100644 --- a/minijvm/c/jvm/jdwp.c +++ b/minijvm/c/jvm/jdwp.c @@ -19,7 +19,7 @@ struct _JdwpServer { ArrayList *event_packets; Pairlist *event_sets; mtx_t event_sets_lock; - Runtime *runtime_for_hold_obj_only; + Runtime *runtime_jdwp; s32 jdwp_eventset_requestid; @@ -125,7 +125,8 @@ s32 jdwp_start_server(MiniJVM *jvm) { jdwpserver->clients = arraylist_create(0); jdwpserver->event_packets = arraylist_create(0); jdwpserver->event_sets = pairlist_create(32); - jdwpserver->runtime_for_hold_obj_only = runtime_create(jvm); + jdwpserver->runtime_jdwp = runtime_create(jvm); + jdwpserver->runtime_jdwp->thrd_info->type = THREAD_TYPE_JDWP; mtx_init(&jdwpserver->event_sets_lock, mtx_recursive); jvm->jdwpserver = jdwpserver; @@ -172,7 +173,7 @@ s32 jdwp_stop_server(MiniJVM *jvm) { pairlist_destory(jdwpserver->event_sets); // - runtime_destory(jdwpserver->runtime_for_hold_obj_only); + runtime_destory(jdwpserver->runtime_jdwp); // thrd_detach(jdwpserver->pt_listener); thrd_detach(jdwpserver->pt_dispacher); @@ -213,7 +214,7 @@ void jdwp_client_destory(JdwpServer *jdwpserver, JdwpClient *client) { jvm_free(client); } -void jdwp_client_hold_obj(JdwpClient *client, Runtime *runtime, __refer obj) { +void jdwp_client_hold_obj(JdwpClient *client, __refer obj) { hashset_put(client->temp_obj_holder, obj); gc_obj_hold(client->jvm->collector, obj); } @@ -837,7 +838,7 @@ void jdwp_check_debug_step(Runtime *runtime) { } Runtime *jdwp_get_runtime(JdwpServer *srv) { - return srv->runtime_for_hold_obj_only; + return srv->runtime_jdwp; } s32 jdwp_is_ignore_sync(JdwpServer *srv) { @@ -1444,7 +1445,7 @@ void invoke_method(s32 call_mode, JdwpPacket *req, JdwpPacket *res, JdwpClient * JdwpServer *jdwpserver = client->jdwpserver; GcCollector *collector = client->jvm->collector; gc_pause(collector); - Runtime *runtime = runtime_create(jdwpserver->jvm); + Runtime *runtime = jdwp_get_runtime(jdwpserver); JClass *clazz; Instance *thread; Instance *object; @@ -1504,7 +1505,7 @@ void invoke_method(s32 call_mode, JdwpPacket *req, JdwpPacket *res, JdwpClient * __refer r = pop_ref(runtime->stack); vt.type = getInstanceOfClassTag(r);//recorrect type, may be Arraylist vt.value = (s64) (intptr_t) r; - jdwp_client_hold_obj(client, runtime, r); + jdwp_client_hold_obj(client, r); // if (vt.type == 's') { // s32 debug = 1; @@ -1526,7 +1527,6 @@ void invoke_method(s32 call_mode, JdwpPacket *req, JdwpPacket *res, JdwpClient * jdwp_packet_put(jdwpserver, res); gc_move_objs_thread_2_gc(runtime); - runtime_destory(runtime); gc_resume(collector);// } @@ -1711,11 +1711,10 @@ s32 jdwp_client_process(JdwpServer *jdwpserver, JdwpClient *client) { case JDWP_CMD_VirtualMachine_CreateString: {//1.11 Utf8String *str = jdwppacket_read_utf(req); gc_pause(jdwpserver->jvm->collector); - Runtime *runtime = runtime_create(jdwpserver->jvm); + Runtime *runtime = jdwp_get_runtime(jdwpserver); Instance *jstr = jstring_create(str, runtime); - jdwp_client_hold_obj(client, runtime, jstr);//防止回收此处需要hold + jdwp_client_hold_obj(client, jstr);//防止回收此处需要hold gc_move_objs_thread_2_gc(runtime); - runtime_destory(runtime); gc_resume(jdwpserver->jvm->collector); utf8_destory(str); jdwppacket_set_err(res, JDWP_ERROR_NONE); @@ -1936,7 +1935,7 @@ s32 jdwp_client_process(JdwpServer *jdwpserver, JdwpClient *client) { JClass *ref = jdwppacket_read_refer(req); if (is_class_exists(jdwpserver->jvm, ref)) { gc_pause(jdwpserver->jvm->collector); - Runtime *runtime = runtime_create(jdwpserver->jvm); + Runtime *runtime = jdwp_get_runtime(jdwpserver); s32 fields = jdwppacket_read_int(req); jdwppacket_set_err(res, JDWP_ERROR_NONE); jdwppacket_write_int(res, fields); @@ -1951,7 +1950,6 @@ s32 jdwp_client_process(JdwpServer *jdwpserver, JdwpClient *client) { } gc_move_objs_thread_2_gc(runtime); - runtime_destory(runtime); gc_resume(jdwpserver->jvm->collector); } else { jdwppacket_set_err(res, JDWP_ERROR_INVALID_CLASS); @@ -2209,7 +2207,7 @@ s32 jdwp_client_process(JdwpServer *jdwpserver, JdwpClient *client) { } case JDWP_CMD_ObjectReference_GetValues: {//9.2 gc_pause(jdwpserver->jvm->collector); - Runtime *runtime = runtime_create(jdwpserver->jvm); + Runtime *runtime = jdwp_get_runtime(jdwpserver); Instance *obj = (Instance *) jdwppacket_read_refer(req); JClass *ref = obj->mb.clazz; s32 fields = jdwppacket_read_int(req); @@ -2227,7 +2225,6 @@ s32 jdwp_client_process(JdwpServer *jdwpserver, JdwpClient *client) { jdwp_packet_put(jdwpserver, res); gc_move_objs_thread_2_gc(runtime); - runtime_destory(runtime); gc_resume(jdwpserver->jvm->collector); break; } @@ -2251,7 +2248,7 @@ s32 jdwp_client_process(JdwpServer *jdwpserver, JdwpClient *client) { case JDWP_CMD_ObjectReference_DisableCollection: {//9.7 gc_pause(jdwpserver->jvm->collector); Instance *obj = (Instance *) jdwppacket_read_refer(req); - jdwp_client_hold_obj(client, jdwpserver->runtime_for_hold_obj_only, obj); + jdwp_client_hold_obj(client, obj); jdwppacket_set_err(res, JDWP_ERROR_NONE); jdwp_packet_put(jdwpserver, res); @@ -2283,10 +2280,9 @@ s32 jdwp_client_process(JdwpServer *jdwpserver, JdwpClient *client) { case JDWP_CMD_StringReference_Value: {//10.1 Instance *jstr = jdwppacket_read_refer(req); Utf8String *ustr = utf8_create(); - Runtime *runtime = runtime_create(jdwpserver->jvm); + Runtime *runtime = jdwp_get_runtime(jdwpserver); jstring_2_utf8(jstr, ustr, runtime); gc_move_objs_thread_2_gc(runtime); - runtime_destory(runtime); jdwppacket_set_err(res, JDWP_ERROR_NONE); jdwppacket_write_utf(res, ustr); jdwp_packet_put(jdwpserver, res); diff --git a/minijvm/c/jvm/jni_std.c b/minijvm/c/jvm/jni_std.c index 76019f42..5971d6d6 100644 --- a/minijvm/c/jvm/jni_std.c +++ b/minijvm/c/jvm/jni_std.c @@ -1104,6 +1104,7 @@ s32 java_lang_Thread_createStackFrame(Runtime *runtime, JClass *clazz) { Instance *ins = (Instance *) localvar_getRefer(runtime->localvar, 0); Runtime *r = runtime_create(runtime->jvm); + r->thrd_info->type = THREAD_TYPE_NORMAL; jthread_set_stackframe_value(runtime->jvm, ins, r); push_long(stack, (s64) (intptr_t) r); #if _JVM_DEBUG_LOG_LEVEL > 5 diff --git a/minijvm/c/jvm/jvm.c b/minijvm/c/jvm/jvm.c index eaa5615a..36080658 100644 --- a/minijvm/c/jvm/jvm.c +++ b/minijvm/c/jvm/jvm.c @@ -309,6 +309,7 @@ s32 jvm_init(MiniJVM *jvm, c8 *p_bootclasspath, c8 *p_classpath) { //init load thread, string etc Runtime *runtime = runtime_create(jvm); + runtime->thrd_info->type = THREAD_TYPE_NORMAL; Utf8String *clsName = utf8_create_c(STR_CLASS_JAVA_LANG_INTEGER); JClass *c = classes_load_get(NULL, clsName, runtime); if (!c) { @@ -388,6 +389,7 @@ s32 call_main(MiniJVM *jvm, c8 *p_mainclass, ArrayList *java_para) { return 1; } Runtime *runtime = runtime_create(jvm); + runtime->thrd_info->type = THREAD_TYPE_NORMAL; thread_boundle(runtime); //准备参数 @@ -430,6 +432,7 @@ s32 call_method(MiniJVM *jvm, c8 *p_classname, c8 *p_methodname, c8 *p_methoddes Runtime *runtime = p_runtime; if (!p_runtime) { runtime = runtime_create(jvm); + runtime->thrd_info->type = THREAD_TYPE_NORMAL; thread_boundle(runtime); } diff --git a/minijvm/c/jvm/jvm.h b/minijvm/c/jvm/jvm.h index 71bf91a6..e5451484 100644 --- a/minijvm/c/jvm/jvm.h +++ b/minijvm/c/jvm/jvm.h @@ -458,6 +458,13 @@ enum { JVM_EXCEPTION_INSTANTIATION, }; +enum { + THREAD_TYPE_NONE, + THREAD_TYPE_NORMAL, + THREAD_TYPE_GC, + THREAD_TYPE_JDWP, +}; + extern char *STRS_CLASS_EXCEPTION[]; extern c8 const *STR_CLASS_JAVA_LANG_STRING; @@ -1251,6 +1258,7 @@ struct _JavaThreadInfo { u8 volatile is_unparked; u8 volatile is_blocking;// some of native method will enter blocking state u8 is_interrupt; + u8 type;// gc /jdwp /normal thrd_t pthread; //调试器相关字段 diff --git a/minijvm/c/jvm/jvm_util.c b/minijvm/c/jvm/jvm_util.c index f1fd49ac..a05e3a6d 100644 --- a/minijvm/c/jvm/jvm_util.c +++ b/minijvm/c/jvm/jvm_util.c @@ -999,7 +999,11 @@ s32 jthread_lock(MemoryBlock *mb, Runtime *runtime) { //可能会重入,同一 //can pause when lock while (mtx_trylock(&jtl->mutex_lock) != thrd_success) { check_suspend_and_pause(runtime); - jthread_yield(runtime); + if (runtime->thrd_info->type == THREAD_TYPE_JDWP) { + break; + } + //jthread_yield(runtime); + jthread_waitTime(mb, runtime, 20); } #if _JVM_DEBUG_LOG_LEVEL > 5