Skip to content

Commit 4f6f6c8

Browse files
authored
Merge pull request #1292 from Unity-Technologies/unity-master-fix-1241280
mono debugger remove some asserts and fixing an error for async debug of a generic (fixes case 1241280)
2 parents d982901 + 4fc45ee commit 4f6f6c8

File tree

5 files changed

+126
-26
lines changed

5 files changed

+126
-26
lines changed

mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ public static int Main (String[] args) {
366366
new Tests ().invoke_abort ();
367367
new Tests ().evaluate_method ();
368368

369+
test_async_debug_generics();
369370
test_invalid_argument_assembly_get_type ();
370371

371372
return 3;
@@ -558,6 +559,17 @@ public static void ss_nested () {
558559
ss_nested_3 ();
559560
}
560561

562+
[MethodImplAttribute (MethodImplOptions.NoInlining)]
563+
public static void test_async_debug_generics () {
564+
ExecuteAsync_Broken<object>().Wait ();
565+
}
566+
567+
async static Task<T> ExecuteAsync_Broken<T>()
568+
{
569+
await Task.Delay(2);
570+
return default;
571+
}
572+
561573
[MethodImplAttribute (MethodImplOptions.NoInlining)]
562574
public static void ss_nested_1 (int i) {
563575
}

mcs/class/Mono.Debugger.Soft/Test/dtest.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4444,5 +4444,14 @@ public void InvalidArgumentAssemblyGetType () {
44444444
}
44454445
}
44464446

4447+
[Test]
4448+
public void TestAsyncDebugGenerics () {
4449+
Event e = run_until ("test_async_debug_generics");
4450+
e = step_in_await ("test_async_debug_generics", e);
4451+
e = step_in_await ("MoveNext", e);
4452+
e = step_in_await ("MoveNext", e);
4453+
e = step_in_await ("MoveNext", e);
4454+
e = step_in_await ("MoveNext", e);
4455+
}
44474456
} // class DebuggerTests
44484457
} // namespace

mono/mini/debugger-agent.c

Lines changed: 96 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5442,12 +5442,47 @@ get_object_id_for_debugger_method (MonoClass* async_builder_class)
54425442
MonoError error;
54435443
GPtrArray *array = mono_class_get_methods_by_name (async_builder_class, "get_ObjectIdForDebugger", 0x24, FALSE, FALSE, &error);
54445444
mono_error_assert_ok (&error);
5445-
g_assert (array->len == 1);
5445+
if (array->len != 1) {
5446+
g_ptr_array_free (array, TRUE);
5447+
//if we don't find method get_ObjectIdForDebugger we try to find the property Task to continue async debug.
5448+
MonoProperty *prop = mono_class_get_property_from_name (async_builder_class, "Task");
5449+
if (!prop) {
5450+
DEBUG_PRINTF (1, "Impossible to debug async methods.\n");
5451+
return NULL;
5452+
}
5453+
return prop->get;
5454+
}
54465455
MonoMethod *method = (MonoMethod *)g_ptr_array_index (array, 0);
54475456
g_ptr_array_free (array, TRUE);
54485457
return method;
54495458
}
54505459

5460+
static MonoClass *
5461+
get_class_to_get_builder_field(StackFrame *frame)
5462+
{
5463+
MonoError error;
5464+
gpointer this_addr = get_this_addr (frame);
5465+
MonoClass *original_class = frame->method->klass;
5466+
MonoClass *ret;
5467+
if (!mono_class_is_valuetype(original_class) && mono_class_is_open_constructed_type (&original_class->byval_arg)) {
5468+
MonoObject *this_obj = *(MonoObject**)this_addr;
5469+
MonoGenericContext context;
5470+
MonoType *inflated_type;
5471+
5472+
if (!this_obj)
5473+
return NULL;
5474+
5475+
context = mono_get_generic_context_from_stack_frame (frame->ji, this_obj->vtable);
5476+
inflated_type = mono_class_inflate_generic_type_checked (&original_class->byval_arg, &context, &error);
5477+
mono_error_assert_ok (&error); /* FIXME don't swallow the error */
5478+
5479+
ret = mono_class_from_mono_type (inflated_type);
5480+
mono_metadata_free_type (inflated_type);
5481+
return ret;
5482+
}
5483+
return original_class;
5484+
}
5485+
54515486
/* Return the address of the AsyncMethodBuilder struct belonging to the state machine method pointed to by FRAME */
54525487
static gpointer
54535488
get_async_method_builder (StackFrame *frame)
@@ -5456,15 +5491,18 @@ get_async_method_builder (StackFrame *frame)
54565491
MonoClassField *builder_field;
54575492
gpointer builder;
54585493
guint8 *this_addr;
5494+
MonoClass* klass = frame->method->klass;
54595495

5460-
builder_field = mono_class_get_field_from_name (frame->method->klass, "<>t__builder");
5461-
g_assert (builder_field);
5496+
klass = get_class_to_get_builder_field(frame);
5497+
builder_field = mono_class_get_field_from_name_full (klass, "<>t__builder", NULL);
5498+
if (!builder_field)
5499+
return NULL;
54625500

54635501
this_addr = get_this_addr (frame);
54645502
if (!this_addr)
54655503
return NULL;
54665504

5467-
if (mono_class_is_valuetype (frame->method->klass)) {
5505+
if (mono_class_is_valuetype (klass)) {
54685506
guint8 *vtaddr = *(guint8**)this_addr;
54695507
builder = (char*)vtaddr + mono_field_get_offset (builder_field) - sizeof (MonoObject);
54705508
} else {
@@ -5497,8 +5535,9 @@ get_this_async_id (StackFrame *frame)
54975535
if (!builder)
54985536
return 0;
54995537

5500-
builder_field = mono_class_get_field_from_name (frame->method->klass, "<>t__builder");
5501-
g_assert (builder_field);
5538+
builder_field = mono_class_get_field_from_name (get_class_to_get_builder_field(frame), "<>t__builder");
5539+
if (!builder_field)
5540+
return 0;
55025541

55035542
tls = (DebuggerTlsData *)mono_native_tls_get_value (debugger_tls_id);
55045543
if (tls) {
@@ -5507,6 +5546,11 @@ get_this_async_id (StackFrame *frame)
55075546
}
55085547

55095548
method = get_object_id_for_debugger_method (mono_class_from_mono_type (mono_field_get_type (builder_field)));
5549+
if (!method) {
5550+
if (tls)
5551+
tls->disable_breakpoints = old_disable_breakpoints;
5552+
return 0;
5553+
}
55105554
obj = mono_runtime_try_invoke (method, builder, NULL, &ex, &error);
55115555
mono_error_assert_ok (&error);
55125556

@@ -5521,10 +5565,12 @@ get_this_async_id (StackFrame *frame)
55215565
static gboolean
55225566
set_set_notification_for_wait_completion_flag (StackFrame *frame)
55235567
{
5524-
MonoClassField *builder_field = mono_class_get_field_from_name (frame->method->klass, "<>t__builder");
5525-
g_assert (builder_field);
5568+
MonoClassField *builder_field = mono_class_get_field_from_name (get_class_to_get_builder_field(frame), "<>t__builder");
5569+
if (!builder_field)
5570+
return FALSE;
55265571
gpointer builder = get_async_method_builder (frame);
5527-
g_assert (builder);
5572+
if (!builder)
5573+
return FALSE;
55285574

55295575
void* args [1];
55305576
gboolean arg = TRUE;
@@ -6016,7 +6062,6 @@ process_single_step_inner (DebuggerTlsData *tls, gboolean from_signal)
60166062
return;
60176063
}
60186064

6019-
60206065
/*
60216066
* The ip points to the instruction causing the single step event, which is before
60226067
* the offset recorded in the seq point map, so find the next seq point after ip.
@@ -6788,7 +6833,10 @@ ss_create (MonoInternalThread *thread, StepSize size, StepDepth depth, StepFilte
67886833
* We are stopped at a throw site. Stepping should go to the catch site.
67896834
*/
67906835
frame = tls->catch_frame;
6791-
g_assert (frame.type == FRAME_TYPE_MANAGED || frame.type == FRAME_TYPE_INTERP);
6836+
if (frame.type != FRAME_TYPE_MANAGED && frame.type != FRAME_TYPE_INTERP) {
6837+
DEBUG_PRINTF (1, "Current frame is not managed nor interpreter.\n");
6838+
return ERR_INVALID_ARGUMENT;
6839+
}
67926840

67936841
/*
67946842
* Find the seq point corresponding to the landing site ip, which is the first seq
@@ -6798,7 +6846,11 @@ ss_create (MonoInternalThread *thread, StepSize size, StepDepth depth, StepFilte
67986846
sp = (found_sp)? &local_sp : NULL;
67996847
if (!sp)
68006848
no_seq_points_found (frame.method, frame.native_offset);
6801-
g_assert (sp);
6849+
6850+
if (!sp) {
6851+
DEBUG_PRINTF (1, "Could not find next sequence point.\n");
6852+
return ERR_INVALID_ARGUMENT;
6853+
}
68026854

68036855
method = frame.method;
68046856

@@ -6844,7 +6896,10 @@ ss_create (MonoInternalThread *thread, StepSize size, StepDepth depth, StepFilte
68446896
sp = (found_sp)? &local_sp : NULL;
68456897
if (!sp)
68466898
no_seq_points_found (frame->method, frame->native_offset);
6847-
g_assert (sp);
6899+
if (!sp) {
6900+
DEBUG_PRINTF (1, "Could not find next sequence point.\n");
6901+
return ERR_INVALID_ARGUMENT;
6902+
}
68486903
method = frame->method;
68496904
}
68506905
}
@@ -10812,7 +10867,11 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
1081210867
if (mono_class_get_context (klass)) {
1081310868
MonoError error;
1081410869
result = mono_class_inflate_generic_method_full_checked (result, klass, mono_class_get_context (klass), &error);
10815-
g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
10870+
if (!mono_error_ok (&error)) {
10871+
buffer_add_string (buf, mono_error_get_message (&error));
10872+
mono_error_cleanup (&error);
10873+
return ERR_INVALID_ARGUMENT;
10874+
}
1081610875
}
1081710876
}
1081810877
}
@@ -10955,7 +11014,12 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
1095511014
char *s;
1095611015

1095711016
s = mono_string_to_utf8_checked ((MonoString *)val, &error);
10958-
mono_error_assert_ok (&error);
11017+
if (!mono_error_ok (&error)) {
11018+
buffer_add_string (buf, mono_error_get_message (&error));
11019+
mono_error_cleanup (&error);
11020+
g_free (s);
11021+
return ERR_INVALID_ARGUMENT;
11022+
}
1095911023
buffer_add_byte (buf, TOKEN_TYPE_STRING);
1096011024
buffer_add_string (buf, s);
1096111025
g_free (s);
@@ -11023,7 +11087,11 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
1102311087
tmp_context.method_inst = ginst;
1102411088

1102511089
inflated = mono_class_inflate_generic_method_checked (method, &tmp_context, &error);
11026-
g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
11090+
if (!mono_error_ok (&error)) {
11091+
buffer_add_string (buf, mono_error_get_message (&error));
11092+
mono_error_cleanup (&error);
11093+
return ERR_INVALID_ARGUMENT;
11094+
}
1102711095
if (!mono_verifier_is_method_valid_generic_instantiation (inflated))
1102811096
return ERR_INVALID_ARGUMENT;
1102911097
buffer_add_methodid (buf, domain, inflated);
@@ -11492,7 +11560,10 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
1149211560
set_interp_var (&frame->actual_method->klass->this_arg, addr, val_buf);
1149311561
} else {
1149411562
var = jit->this_var;
11495-
g_assert (var);
11563+
if (!var) {
11564+
buffer_add_string (buf, "Invalid this object");
11565+
return ERR_INVALID_ARGUMENT;
11566+
}
1149611567

1149711568
set_var (&frame->actual_method->klass->this_arg, var, &frame->ctx, frame->domain, val_buf, frame->reg_locations, &tls->restore_state.ctx);
1149811569
}
@@ -11535,9 +11606,11 @@ array_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
1153511606
index = decode_int (p, &p, end);
1153611607
len = decode_int (p, &p, end);
1153711608

11538-
g_assert (index >= 0 && len >= 0);
11609+
if (index < 0 || len < 0)
11610+
return ERR_INVALID_ARGUMENT;
1153911611
// Reordered to avoid integer overflow
11540-
g_assert (!(index > arr->max_length - len));
11612+
if (index > arr->max_length - len)
11613+
return ERR_INVALID_ARGUMENT;
1154111614

1154211615
esize = mono_array_element_size (mono_object_get_class (&arr->obj));
1154311616
for (i = index; i < index + len; ++i) {
@@ -11549,9 +11622,11 @@ array_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
1154911622
index = decode_int (p, &p, end);
1155011623
len = decode_int (p, &p, end);
1155111624

11552-
g_assert (index >= 0 && len >= 0);
11625+
if (index < 0 || len < 0)
11626+
return ERR_INVALID_ARGUMENT;
1155311627
// Reordered to avoid integer overflow
11554-
g_assert (!(index > arr->max_length - len));
11628+
if (index > arr->max_length - len)
11629+
return ERR_INVALID_ARGUMENT;
1155511630

1155611631
esize = mono_array_element_size (mono_object_get_class (&arr->obj));
1155711632
for (i = index; i < index + len; ++i) {

mono/mini/mini-exceptions.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -805,8 +805,8 @@ get_generic_info_from_stack_frame (MonoJitInfo *ji, MonoContext *ctx)
805805
/*
806806
* generic_info is either a MonoMethodRuntimeGenericContext or a MonoVTable.
807807
*/
808-
static MonoGenericContext
809-
get_generic_context_from_stack_frame (MonoJitInfo *ji, gpointer generic_info)
808+
MonoGenericContext
809+
mono_get_generic_context_from_stack_frame (MonoJitInfo *ji, gpointer generic_info)
810810
{
811811
MonoGenericContext context = { NULL, NULL };
812812
MonoClass *klass, *method_container_class;
@@ -851,6 +851,7 @@ get_generic_context_from_stack_frame (MonoJitInfo *ji, gpointer generic_info)
851851
return context;
852852
}
853853

854+
854855
static MonoMethod*
855856
get_method_from_stack_frame (MonoJitInfo *ji, gpointer generic_info)
856857
{
@@ -860,7 +861,7 @@ get_method_from_stack_frame (MonoJitInfo *ji, gpointer generic_info)
860861

861862
if (!ji->has_generic_jit_info || !mono_jit_info_get_generic_jit_info (ji)->has_this)
862863
return jinfo_get_method (ji);
863-
context = get_generic_context_from_stack_frame (ji, generic_info);
864+
context = mono_get_generic_context_from_stack_frame (ji, generic_info);
864865

865866
method = jinfo_get_method (ji);
866867
method = mono_method_get_declaring_generic_method (method);
@@ -1386,7 +1387,7 @@ get_exception_catch_class (MonoJitExceptionInfo *ei, MonoJitInfo *ji, MonoContex
13861387

13871388
if (!ji->has_generic_jit_info || !mono_jit_info_get_generic_jit_info (ji)->has_this)
13881389
return catch_class;
1389-
context = get_generic_context_from_stack_frame (ji, get_generic_info_from_stack_frame (ji, ctx));
1390+
context = mono_get_generic_context_from_stack_frame (ji, get_generic_info_from_stack_frame (ji, ctx));
13901391

13911392
/* FIXME: we shouldn't inflate but instead put the
13921393
type in the rgctx and fetch it from there. It
@@ -3473,7 +3474,7 @@ mono_llvm_match_exception (MonoJitInfo *jinfo, guint32 region_start, guint32 reg
34733474
MonoType *inflated_type;
34743475

34753476
g_assert (rgctx || this_obj);
3476-
context = get_generic_context_from_stack_frame (jinfo, rgctx ? rgctx : this_obj->vtable);
3477+
context = mono_get_generic_context_from_stack_frame (jinfo, rgctx ? rgctx : this_obj->vtable);
34773478
inflated_type = mono_class_inflate_generic_type_checked (&catch_class->byval_arg, &context, &error);
34783479
mono_error_assert_ok (&error); /* FIXME don't swallow the error */
34793480

mono/mini/mini.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2883,4 +2883,7 @@ gboolean MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal);
28832883

28842884
#endif
28852885

2886+
MonoGenericContext
2887+
mono_get_generic_context_from_stack_frame (MonoJitInfo *ji, gpointer generic_info);
2888+
28862889
#endif /* __MONO_MINI_H__ */

0 commit comments

Comments
 (0)