Skip to content

Instantly share code, notes, and snippets.

@StollD
Created April 1, 2020 19:26
Show Gist options
  • Save StollD/72362ce179c7d7ffca59a0d172d139ef to your computer and use it in GitHub Desktop.
Save StollD/72362ce179c7d7ffca59a0d172d139ef to your computer and use it in GitHub Desktop.
From bfdbbb3be8516be1926ad49531a0a7812758c650 Mon Sep 17 00:00:00 2001
From: Dorian Stoll <[email protected]>
Date: Wed, 1 Apr 2020 21:22:25 +0200
Subject: [PATCH] mono-debug
To build:
git am ./0001-mono-debug.patch
perl external/buildscripts/build_runtime_linux.pl --build64=1
strip mono/mini/.libs/libmonobdwgc-2.0.so.1.0.0
cp mono/mini/.libs/libmonobdwgc-2.0.so.1.0.0 \
$KSPDIR/KSP_Data/MonoBleedingEdge/x86_64/libmonobdwgc-2.0.so
Signed-off-by: Dorian Stoll <[email protected]>
---
configure.ac | 2 -
external/buildscripts/build.pl | 19 +-------
libgc/configure.ac | 2 -
mono/mini/Makefile.am.in | 2 +
mono/mini/debugger-agent.c | 14 +++++-
mono/mini/dnSpy.c | 82 ++++++++++++++++++++++++++++++++++
mono/mini/dnSpy.h | 21 +++++++++
mono/mini/mini-runtime.c | 3 ++
8 files changed, 121 insertions(+), 24 deletions(-)
create mode 100644 mono/mini/dnSpy.c
create mode 100644 mono/mini/dnSpy.h
diff --git a/configure.ac b/configure.ac
index 53c48fdf65b..4753c4745c4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -484,8 +484,6 @@ AC_LIBTOOL_WIN32_DLL
AC_HEADER_MAJOR
AM_PROG_LIBTOOL
-# Use dolt (http://dolt.freedesktop.org/) instead of libtool for building.
-DOLT
export_ldflags=`(./libtool --config; echo eval echo \\$export_dynamic_flag_spec) | sh`
AC_SUBST(export_ldflags)
diff --git a/external/buildscripts/build.pl b/external/buildscripts/build.pl
index 58eae785fb5..e797492bdb2 100644
--- a/external/buildscripts/build.pl
+++ b/external/buildscripts/build.pl
@@ -281,23 +281,6 @@ if ($build)
push @configureparams, "--with-monotouch=no";
}
- if (!(-d "$extraBuildTools"))
- {
- # Check out on the fly
- print(">>> Checking out mono build tools extra to : $extraBuildTools\n");
- my $repo = '[email protected]:unity/mono-build-tools-extra.git';
- print(">>> Cloning $repo at $extraBuildTools\n");
- my $checkoutResult = system("git", "clone", "--recurse-submodules", $repo, "$extraBuildTools");
-
- if ($checkoutResult ne 0)
- {
- die("Failed to checkout mono build tools extra\n");
- }
-
- # Only clean up if the dir exists. Otherwise abs_path will return empty string
- $extraBuildTools = abs_path($extraBuildTools) if (-d $extraBuildTools);
- }
-
if ($existingMonoRootPath eq "")
{
print(">>> No existing mono supplied. Checking for external...\n");
@@ -308,7 +291,7 @@ if ($build)
{
print(">>> Running bee to download build-deps...\n");
chdir($buildscriptsdir) eq 1 or die ("failed to chdir to $buildscriptsdir directory\n");
- system("./bee") eq 0 or die ("failed to run bee\n");
+ system("./bee");
chdir("$monoroot") eq 1 or die ("failed to chdir to $monoroot\n");
}
else
diff --git a/libgc/configure.ac b/libgc/configure.ac
index 628144d3a16..ee774ad318b 100644
--- a/libgc/configure.ac
+++ b/libgc/configure.ac
@@ -394,8 +394,6 @@ AC_SUBST(addtests)
AM_CONDITIONAL(TARGET_IA64,test x$target_ia64 = xtrue)
AC_PROG_LIBTOOL
-# Use dolt (http://dolt.freedesktop.org/) instead of libtool for building.
-DOLT
#
# Check for AViiON Machines running DGUX
diff --git a/mono/mini/Makefile.am.in b/mono/mini/Makefile.am.in
index 535e2069dae..69cea757a8a 100755
--- a/mono/mini/Makefile.am.in
+++ b/mono/mini/Makefile.am.in
@@ -534,6 +534,8 @@ common_sources = \
mini-gc.c \
debugger-agent.h \
debugger-agent.c \
+ dnSpy.h \
+ dnSpy.c \
xdebug.c \
mini-llvm.h \
mini-llvm-cpp.h \
diff --git a/mono/mini/debugger-agent.c b/mono/mini/debugger-agent.c
index a614611750c..f578bb39ea9 100644
--- a/mono/mini/debugger-agent.c
+++ b/mono/mini/debugger-agent.c
@@ -111,6 +111,7 @@
#define THREAD_TO_INTERNAL(thread) (thread)->internal_thread
#include "debugger-agent.h"
+#include "dnSpy.h"
#ifdef RUNTIME_IL2CPP
extern Il2CppMonoDefaults il2cpp_mono_defaults;
@@ -1140,6 +1141,8 @@ mono_debugger_agent_init (void)
mono_profiler_set_jit_done_callback (prof, jit_done);
mono_profiler_set_jit_failed_callback (prof, jit_failed);
+ dnSpy_debugger_init_after_agent ();
+
mono_native_tls_alloc (&debugger_tls_id, NULL);
/* Needed by the hash_table_new_type () call below */
@@ -4632,6 +4635,7 @@ insert_breakpoint (MonoSeqPointInfo *seq_points, MonoDomain *domain, MonoJitInfo
BreakpointInstance *inst;
SeqPointIterator it;
gboolean it_has_sp = FALSE;
+ SeqPoint found_sp;
if (error)
error_init (error);
@@ -4640,9 +4644,14 @@ insert_breakpoint (MonoSeqPointInfo *seq_points, MonoDomain *domain, MonoJitInfo
while (mono_seq_point_iterator_next (&it)) {
if (it.seq_point.il_offset == bp->il_offset) {
it_has_sp = TRUE;
- break;
+ if (!(it.seq_point.flags & MONO_SEQ_POINT_FLAG_NONEMPTY_STACK)) {
+ found_sp = it.seq_point;
+ break;
+ }
+ found_sp = it.seq_point;
}
}
+ it.seq_point = found_sp;
if (!it_has_sp) {
/*
@@ -11039,7 +11048,8 @@ thread_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
mono_loader_lock ();
tls = (DebuggerTlsData *)mono_g_hash_table_lookup (thread_to_tls, thread);
mono_loader_unlock ();
- g_assert (tls);
+ if (!tls)
+ return ERR_INVALID_ARGUMENT;
compute_frame_info (thread, tls);
diff --git a/mono/mini/dnSpy.c b/mono/mini/dnSpy.c
new file mode 100644
index 00000000000..10892413bfb
--- /dev/null
+++ b/mono/mini/dnSpy.c
@@ -0,0 +1,82 @@
+#include <mono/metadata/profiler.h>
+#include <mono/metadata/mono-debug.h>
+#include "dnSpy.h"
+
+// 0 = .NET 2.0-3.5 Unity
+// 1 = .NET 4.0+ Unity
+#ifndef DNUNITYRT
+#define DNUNITYRT 0
+#endif
+
+#ifndef DEFINED_LEGACY_PROFILER
+#define MonoLegacyProfiler MonoProfiler
+#endif
+
+// dnSpy doesn't know which version this is so it will set both of these environment variables.
+// Older dnSpy versions will only set the first one.
+#define ENV_VAR_NAME_V0 "DNSPY_UNITY_DBG"
+#define ENV_VAR_NAME_V1 "DNSPY_UNITY_DBG2"
+#if DNUNITYRT == 0
+#define ENV_VAR_NAME ENV_VAR_NAME_V0
+#elif DNUNITYRT == 1
+#define ENV_VAR_NAME ENV_VAR_NAME_V1
+#else
+#error Invalid DNUNITYRT value
+#endif
+
+void
+dnSpy_debugger_init ()
+{
+ gboolean fixDefer = FALSE;
+ char* envVal = getenv (ENV_VAR_NAME);
+
+#if DNUNITYRT != 0
+ if (!envVal) {
+ envVal = getenv (ENV_VAR_NAME_V0);
+ fixDefer = TRUE;
+ }
+#endif
+
+ if (!envVal) {
+ envVal = "--debugger-agent=transport=dt_socket,server=y,address=127.0.0.1:55555,defer=y";
+ fixDefer = TRUE;
+ }
+
+#if DNUNITYRT != 0
+
+#define defer_y "defer=y"
+#define suspend_n "suspend=n"
+
+ const char* s = strstr (envVal, defer_y);
+ if (s && fixDefer) {
+ int envVal_len = strlen (envVal);
+ int defer_y_len = strlen (defer_y);
+ int suspend_n_len = strlen (suspend_n);
+ int newStr_len = envVal_len - defer_y_len + suspend_n_len;
+ char* newStr = (char*)malloc (newStr_len + 1);
+ memcpy (newStr, envVal, s - envVal);
+ memcpy (newStr + (s - envVal), suspend_n, suspend_n_len);
+ memcpy (newStr + (s - envVal) + suspend_n_len, s + defer_y_len, envVal_len - (s + defer_y_len - envVal));
+ newStr [newStr_len] = 0;
+ envVal = newStr;
+ }
+#endif
+
+ char* argv[] = { envVal };
+ mono_jit_parse_options (1, (char**)argv);
+ mono_debug_init (MONO_DEBUG_FORMAT_MONO);
+}
+
+typedef struct { void* dummy; } DebuggerProfiler;
+static DebuggerProfiler dnSpy_dummy_profiler;
+static void
+dnSpy_runtime_shutdown (MonoLegacyProfiler *prof)
+{
+}
+
+void
+dnSpy_debugger_init_after_agent ()
+{
+ // Prevent the debugger-agent's profiler events from being overwritten
+ mono_profiler_install ((MonoLegacyProfiler*)&dnSpy_dummy_profiler, dnSpy_runtime_shutdown);
+}
diff --git a/mono/mini/dnSpy.h b/mono/mini/dnSpy.h
new file mode 100644
index 00000000000..6e1660bb52c
--- /dev/null
+++ b/mono/mini/dnSpy.h
@@ -0,0 +1,21 @@
+#ifndef _MONO_MINI_DNSPY_H_
+#define _MONO_MINI_DNSPY_H_
+
+#include <mono/metadata/profiler.h>
+#include <mono/metadata/mono-debug.h>
+#include "debugger-agent.h"
+
+// 0 = .NET 2.0-3.5 Unity
+// 1 = .NET 4.0+ Unity
+#define DNUNITYRT 1
+
+typedef void *MonoLegacyProfiler;
+typedef void (*MonoLegacyProfileFunc) (MonoLegacyProfiler *prof);
+MONO_API void mono_profiler_install (MonoLegacyProfiler *prof, MonoLegacyProfileFunc callback);
+
+#define DEFINED_LEGACY_PROFILER
+
+void dnSpy_debugger_init ();
+void dnSpy_debugger_init_after_agent ();
+
+#endif
diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c
index 472787db6ac..eaad41e30fc 100644
--- a/mono/mini/mini-runtime.c
+++ b/mono/mini/mini-runtime.c
@@ -84,6 +84,7 @@
#include "mini-gc.h"
#include "mini-llvm.h"
#include "debugger-agent.h"
+#include "dnSpy.h"
#include "lldb.h"
#include "mixed_callstack_plugin.h"
#include "mini-runtime.h"
@@ -3812,6 +3813,8 @@ mini_init (const char *filename, const char *runtime_version)
CHECKED_MONO_INIT ();
+ dnSpy_debugger_init ();
+
#if defined(__linux__)
if (access ("/proc/self/maps", F_OK) != 0) {
g_print ("Mono requires /proc to be mounted.\n");
--
2.26.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment