Skip to content

Commit 2e93fab

Browse files
authored
[mono] Disable unsupported apply update scenarios (#55698)
* Disallow mixing ApplyChanges and debugger apply changes * Don't allow debugger thread to start if ApplyChanges has been called * Don't allow ApplyChanges managed API call if debugger is attached * MONO_COMPONENT_API mono_error_set_not_supported
1 parent dc2fe34 commit 2e93fab

File tree

8 files changed

+58
-10
lines changed

8 files changed

+58
-10
lines changed

src/mono/mono/component/debugger-agent.c

+13-1
Original file line numberDiff line numberDiff line change
@@ -6575,7 +6575,7 @@ module_apply_changes (MonoImage *image, MonoArray *dmeta, MonoArray *dil, MonoAr
65756575
int32_t dil_len = mono_array_length_internal (dil);
65766576
gpointer dpdb_bytes = !dpdb ? NULL : (gpointer)mono_array_addr_internal (dpdb, char, 0);
65776577
int32_t dpdb_len = !dpdb ? 0 : mono_array_length_internal (dpdb);
6578-
mono_image_load_enc_delta (image, dmeta_bytes, dmeta_len, dil_bytes, dil_len, dpdb_bytes, dpdb_len, error);
6578+
mono_image_load_enc_delta (MONO_ENC_DELTA_DBG, image, dmeta_bytes, dmeta_len, dil_bytes, dil_len, dpdb_bytes, dpdb_len, error);
65796579
return is_ok (error);
65806580
}
65816581

@@ -10203,6 +10203,18 @@ debugger_thread (void *arg)
1020310203
mono_set_is_debugger_attached (TRUE);
1020410204
}
1020510205

10206+
#ifndef HOST_WASM
10207+
if (!attach_failed) {
10208+
if (mono_metadata_has_updates_api ()) {
10209+
PRINT_DEBUG_MSG (1, "[dbg] Cannot attach after System.Reflection.Metadata.MetadataUpdater.ApplyChanges has been called.\n");
10210+
attach_failed = TRUE;
10211+
command_set = (CommandSet)0;
10212+
command = 0;
10213+
dispose_vm ();
10214+
}
10215+
}
10216+
#endif
10217+
1020610218
while (!attach_failed) {
1020710219
res = transport_recv (header, HEADER_LENGTH);
1020810220

src/mono/mono/component/hot_reload-stub.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ static bool
1515
hot_reload_stub_available (void);
1616

1717
static void
18-
hot_reload_stub_apply_changes (MonoImage *base_image, gconstpointer dmeta, uint32_t dmeta_len, gconstpointer dil, uint32_t dil_len, gconstpointer dpdb_bytes_orig, uint32_t dpdb_length, MonoError *error);
18+
hot_reload_stub_apply_changes (int origin, MonoImage *base_image, gconstpointer dmeta, uint32_t dmeta_len, gconstpointer dil, uint32_t dil_len, gconstpointer dpdb_bytes_orig, uint32_t dpdb_length, MonoError *error);
1919

2020
static MonoComponentHotReload *
2121
component_hot_reload_stub_init (void);
@@ -147,7 +147,7 @@ hot_reload_stub_relative_delta_index (MonoImage *image_dmeta, int token)
147147
}
148148

149149
void
150-
hot_reload_stub_apply_changes (MonoImage *base_image, gconstpointer dmeta, uint32_t dmeta_len, gconstpointer dil, uint32_t dil_len, gconstpointer dpdb_bytes_orig, uint32_t dpdb_length, MonoError *error)
150+
hot_reload_stub_apply_changes (int origin, MonoImage *base_image, gconstpointer dmeta, uint32_t dmeta_len, gconstpointer dil, uint32_t dil_len, gconstpointer dpdb_bytes_orig, uint32_t dpdb_length, MonoError *error)
151151
{
152152
mono_error_set_not_supported (error, "Hot reload not supported in this runtime.");
153153
}

src/mono/mono/component/hot_reload.c

+13-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ static void
5454
hot_reload_effective_table_slow (const MonoTableInfo **t, int *idx);
5555

5656
static void
57-
hot_reload_apply_changes (MonoImage *base_image, gconstpointer dmeta, uint32_t dmeta_len, gconstpointer dil, uint32_t dil_len, gconstpointer dpdb_bytes_orig, uint32_t dpdb_length, MonoError *error);
57+
hot_reload_apply_changes (int origin, MonoImage *base_image, gconstpointer dmeta, uint32_t dmeta_len, gconstpointer dil, uint32_t dil_len, gconstpointer dpdb_bytes_orig, uint32_t dpdb_length, MonoError *error);
5858

5959
static int
6060
hot_reload_relative_delta_index (MonoImage *image_dmeta, int token);
@@ -1349,13 +1349,24 @@ apply_enclog_pass2 (MonoImage *image_base, BaselineInfo *base_info, uint32_t gen
13491349
* LOCKING: Takes the publish_lock
13501350
*/
13511351
void
1352-
hot_reload_apply_changes (MonoImage *image_base, gconstpointer dmeta_bytes, uint32_t dmeta_length, gconstpointer dil_bytes_orig, uint32_t dil_length, gconstpointer dpdb_bytes_orig, uint32_t dpdb_length, MonoError *error)
1352+
hot_reload_apply_changes (int origin, MonoImage *image_base, gconstpointer dmeta_bytes, uint32_t dmeta_length, gconstpointer dil_bytes_orig, uint32_t dil_length, gconstpointer dpdb_bytes_orig, uint32_t dpdb_length, MonoError *error)
13531353
{
13541354
if (!assembly_update_supported (image_base->assembly)) {
13551355
mono_error_set_invalid_operation (error, "The assembly can not be edited or changed.");
13561356
return;
13571357
}
13581358

1359+
static int first_origin = -1;
1360+
1361+
if (first_origin < 0) {
1362+
first_origin = origin;
1363+
}
1364+
1365+
if (first_origin != origin) {
1366+
mono_error_set_not_supported (error, "Applying deltas through the debugger and System.Reflection.Metadata.MetadataUpdater.ApplyUpdate simultaneously is not supported");
1367+
return;
1368+
}
1369+
13591370
const char *basename = image_base->filename;
13601371

13611372
if (mono_trace_is_traced (G_LOG_LEVEL_DEBUG, MONO_TRACE_METADATA_UPDATE)) {

src/mono/mono/component/hot_reload.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ typedef struct _MonoComponentHotReload {
2323
void (*cleanup_on_close) (MonoImage *image);
2424
void (*effective_table_slow) (const MonoTableInfo **t, int *idx);
2525
int (*relative_delta_index) (MonoImage *image_dmeta, int token);
26-
void (*apply_changes) (MonoImage *base_image, gconstpointer dmeta, uint32_t dmeta_len, gconstpointer dil, uint32_t dil_len, gconstpointer dpdb_bytes_orig, uint32_t dpdb_length, MonoError *error);
26+
void (*apply_changes) (int origin, MonoImage *base_image, gconstpointer dmeta, uint32_t dmeta_len, gconstpointer dil, uint32_t dil_len, gconstpointer dpdb_bytes_orig, uint32_t dpdb_length, MonoError *error);
2727
void (*image_close_except_pools_all) (MonoImage *base_image);
2828
void (*image_close_all) (MonoImage *base_image);
2929
gpointer (*get_updated_method_rva) (MonoImage *base_image, uint32_t idx);

src/mono/mono/metadata/icall.c

+9-1
Original file line numberDiff line numberDiff line change
@@ -5783,7 +5783,15 @@ ves_icall_AssemblyExtensions_ApplyUpdate (MonoAssembly *assm,
57835783
MonoImage *image_base = assm->image;
57845784
g_assert (image_base);
57855785

5786-
mono_image_load_enc_delta (image_base, dmeta_bytes, dmeta_len, dil_bytes, dil_len, dpdb_bytes, dpdb_len, error);
5786+
#ifndef HOST_WASM
5787+
if (mono_is_debugger_attached ()) {
5788+
mono_error_set_not_supported (error, "Cannot use System.Reflection.Metadata.MetadataUpdater.ApplyChanges while debugger is attached");
5789+
mono_error_set_pending_exception (error);
5790+
return;
5791+
}
5792+
#endif
5793+
5794+
mono_image_load_enc_delta (MONO_ENC_DELTA_API, image_base, dmeta_bytes, dmeta_len, dil_bytes, dil_len, dpdb_bytes, dpdb_len, error);
57875795

57885796
mono_error_set_pending_exception (error);
57895797
}

src/mono/mono/metadata/metadata-internals.h

+11-1
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,11 @@ mono_metadata_has_updates (void)
802802
return mono_metadata_update_data_private.has_updates != 0;
803803
}
804804

805+
/* components can't call the inline function directly since the private data isn't exported */
806+
MONO_COMPONENT_API
807+
gboolean
808+
mono_metadata_has_updates_api (void);
809+
805810
void
806811
mono_image_effective_table_slow (const MonoTableInfo **t, int *idx);
807812

@@ -821,8 +826,13 @@ mono_image_effective_table (const MonoTableInfo **t, int *idx)
821826
int
822827
mono_image_relative_delta_index (MonoImage *image_dmeta, int token);
823828

829+
enum MonoEnCDeltaOrigin {
830+
MONO_ENC_DELTA_API = 0,
831+
MONO_ENC_DELTA_DBG = 1,
832+
};
833+
824834
MONO_COMPONENT_API void
825-
mono_image_load_enc_delta (MonoImage *base_image, gconstpointer dmeta, uint32_t dmeta_len, gconstpointer dil, uint32_t dil_len, gconstpointer dpdb, uint32_t dpdb_len, MonoError *error);
835+
mono_image_load_enc_delta (int delta_origin, MonoImage *base_image, gconstpointer dmeta, uint32_t dmeta_len, gconstpointer dil, uint32_t dil_len, gconstpointer dpdb, uint32_t dpdb_len, MonoError *error);
826836

827837
gboolean
828838
mono_image_load_cli_header (MonoImage *image, MonoCLIImageInfo *iinfo);

src/mono/mono/metadata/metadata-update.c

+8-2
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@ mono_image_relative_delta_index (MonoImage *image_dmeta, int token)
7373
}
7474

7575
void
76-
mono_image_load_enc_delta (MonoImage *base_image, gconstpointer dmeta, uint32_t dmeta_len, gconstpointer dil, uint32_t dil_len, gconstpointer dpdb, uint32_t dpdb_len, MonoError *error)
76+
mono_image_load_enc_delta (int origin, MonoImage *base_image, gconstpointer dmeta, uint32_t dmeta_len, gconstpointer dil, uint32_t dil_len, gconstpointer dpdb, uint32_t dpdb_len, MonoError *error)
7777
{
78-
mono_component_hot_reload ()->apply_changes (base_image, dmeta, dmeta_len, dil, dil_len, dpdb, dpdb_len, error);
78+
mono_component_hot_reload ()->apply_changes (origin, base_image, dmeta, dmeta_len, dil, dil_len, dpdb, dpdb_len, error);
7979
if (is_ok (error)) {
8080
mono_component_debugger ()->send_enc_delta (base_image, dmeta, dmeta_len, dpdb, dpdb_len);
8181
}
@@ -135,3 +135,9 @@ mono_metadata_update_has_modified_rows (const MonoTableInfo *table)
135135
{
136136
return mono_component_hot_reload ()->has_modified_rows (table);
137137
}
138+
139+
gboolean
140+
mono_metadata_has_updates_api (void)
141+
{
142+
return mono_metadata_has_updates ();
143+
}

src/mono/mono/utils/mono-error-internals.h

+1
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ mono_error_set_execution_engine (MonoError *error, const char *msg_format, ...)
205205
void
206206
mono_error_set_not_implemented (MonoError *error, const char *msg_format, ...) MONO_ATTR_FORMAT_PRINTF(2,3);
207207

208+
MONO_COMPONENT_API
208209
void
209210
mono_error_set_not_supported (MonoError *error, const char *msg_format, ...) MONO_ATTR_FORMAT_PRINTF(2,3);
210211

0 commit comments

Comments
 (0)