Skip to content

Commit

Permalink
fix jdwp thread dead lock
Browse files Browse the repository at this point in the history
  • Loading branch information
digitalgust committed Feb 24, 2024
1 parent db3547d commit c82fba9
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 20 deletions.
2 changes: 1 addition & 1 deletion minijvm/c/jvm/garbage.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
32 changes: 14 additions & 18 deletions minijvm/c/jvm/jdwp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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<String>
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;
Expand All @@ -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);//

}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions minijvm/c/jvm/jni_std.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions minijvm/c/jvm/jvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);

//准备参数
Expand Down Expand Up @@ -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);
}

Expand Down
8 changes: 8 additions & 0 deletions minijvm/c/jvm/jvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
//调试器相关字段
Expand Down
6 changes: 5 additions & 1 deletion minijvm/c/jvm/jvm_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit c82fba9

Please sign in to comment.