Skip to content

Commit 8e1a318

Browse files
authored
Add support for debugging on old net35 mono (#60)
1 parent 2b37810 commit 8e1a318

File tree

2 files changed

+39
-12
lines changed

2 files changed

+39
-12
lines changed

README.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,9 @@ Doorstop sets some environment variables useful for code execution:
8989
### Debugging
9090

9191
Doorstop 4 supports debugging the assemblies in the runtime.
92-
At the moment, debugging is somewhat limited depending on the runtime.
9392

9493
#### Debugging in UnityMono
9594

96-
At the moment, debugging is supported in Unity 2017+ games.
97-
9895
To enable debugging, set `debug_enabled` to `true` and optionally change the debug server address via `debug_address` (see [configuration options](#doorstop-configuration)).
9996
After launching the game, you may connect to the debugger using the server address (default is `127.0.0.1:10000`).
10097
By default, the game won't wait for the debugger to connect; you may change the behaviour with the `debug_suspend` option.

src/bootstrap.c

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "util/util.h"
1010

1111
bool_t mono_debug_init_called = FALSE;
12+
bool_t mono_is_net35 = FALSE;
1213

1314
void mono_doorstop_bootstrap(void *mono_domain) {
1415
if (getenv(TEXT("DOORSTOP_INITIALIZED"))) {
@@ -129,8 +130,15 @@ void mono_doorstop_bootstrap(void *mono_domain) {
129130

130131
void *init_mono(const char *root_domain_name, const char *runtime_version) {
131132
char_t *root_domain_name_w = widen(root_domain_name);
133+
char_t *runtime_version_w = widen(runtime_version);
132134
LOG("Starting mono domain \"%s\"", root_domain_name_w);
135+
LOG("Runtime version: %s", runtime_version_w);
136+
if (strlen(runtime_version_w) > 2 &&
137+
(runtime_version_w[1] == L'2' || runtime_version_w[1] == L'1')) {
138+
mono_is_net35 = TRUE;
139+
}
133140
free(root_domain_name_w);
141+
free(runtime_version_w);
134142
char *root_dir_n = mono.assembly_getrootdir();
135143
char_t *root_dir = widen(root_dir_n);
136144
LOG("Current root: %s", root_dir);
@@ -211,17 +219,31 @@ void *init_mono(const char *root_domain_name, const char *runtime_version) {
211219

212220
hook_mono_jit_parse_options(0, NULL);
213221

214-
void *domain = mono.jit_init_version(root_domain_name, runtime_version);
215-
216222
bool_t debugger_already_enabled = mono_debug_init_called;
217223
if (mono.debug_enabled) {
218224
debugger_already_enabled |= mono.debug_enabled();
219225
}
220226

221-
if (config.mono_debug_enabled && !debugger_already_enabled) {
222-
LOG("Detected mono debugger is not initialized; initialized it");
223-
mono.debug_init(MONO_DEBUG_FORMAT_MONO);
224-
mono.debug_domain_create(domain);
227+
void *domain = NULL;
228+
if (mono_is_net35) {
229+
if (config.mono_debug_enabled && !debugger_already_enabled) {
230+
LOG("Detected mono debugger is not initialized; initialized it");
231+
mono.debug_init(MONO_DEBUG_FORMAT_MONO);
232+
}
233+
234+
domain = mono.jit_init_version(root_domain_name, runtime_version);
235+
236+
if (config.mono_debug_enabled && !debugger_already_enabled) {
237+
mono.debug_domain_create(domain);
238+
}
239+
} else {
240+
domain = mono.jit_init_version(root_domain_name, runtime_version);
241+
242+
if (config.mono_debug_enabled && !debugger_already_enabled) {
243+
LOG("Detected mono debugger is not initialized; initialized it");
244+
mono.debug_init(MONO_DEBUG_FORMAT_MONO);
245+
mono.debug_domain_create(domain);
246+
}
225247
}
226248

227249
mono_doorstop_bootstrap(domain);
@@ -315,8 +337,8 @@ int init_il2cpp(const char *domain_name) {
315337

316338
#define MONO_DEBUG_ARG_START \
317339
TEXT("--debugger-agent=transport=dt_socket,server=y,address=")
318-
// TODO: For .NET 3.5 monos, need to use defer=y instead
319340
#define MONO_DEBUG_NO_SUSPEND TEXT(",suspend=n")
341+
#define MONO_DEBUG_NO_SUSPEND_NET35 TEXT(",suspend=n,defer=y")
320342

321343
void hook_mono_jit_parse_options(int argc, char **argv) {
322344
char_t *debug_options = getenv(TEXT("DNSPY_UNITY_DBG2"));
@@ -334,15 +356,23 @@ void hook_mono_jit_parse_options(int argc, char **argv) {
334356
size_t debug_args_len =
335357
STR_LEN(MONO_DEBUG_ARG_START) + strlen(config.mono_debug_address);
336358
if (!config.mono_debug_suspend) {
337-
debug_args_len += STR_LEN(MONO_DEBUG_NO_SUSPEND);
359+
if (mono_is_net35) {
360+
debug_args_len += STR_LEN(MONO_DEBUG_NO_SUSPEND_NET35);
361+
} else {
362+
debug_args_len += STR_LEN(MONO_DEBUG_NO_SUSPEND);
363+
}
338364
}
339365

340366
if (!debug_options) {
341367
debug_options = calloc(debug_args_len + 1, sizeof(char_t));
342368
strcat(debug_options, MONO_DEBUG_ARG_START);
343369
strcat(debug_options, config.mono_debug_address);
344370
if (!config.mono_debug_suspend) {
345-
strcat(debug_options, MONO_DEBUG_NO_SUSPEND);
371+
if (mono_is_net35) {
372+
strcat(debug_options, MONO_DEBUG_NO_SUSPEND_NET35);
373+
} else {
374+
strcat(debug_options, MONO_DEBUG_NO_SUSPEND);
375+
}
346376
}
347377
}
348378

0 commit comments

Comments
 (0)