Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wasm] [debugger] First version of multithreaded debugging #74820

Merged
merged 54 commits into from
Feb 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
67331e6
First version of multithreaded debugging.
thaystg Aug 30, 2022
38aa291
Merge branch 'main' into thays_support_multithreaded_debugging
thaystg Aug 30, 2022
d84c33b
Revert package-lock.json
thaystg Aug 30, 2022
6c1925a
New line at package-lock.json
thaystg Aug 30, 2022
fb7f67e
Fix not used variable.
thaystg Aug 30, 2022
215bca6
Fix debugger on firefox.
thaystg Aug 30, 2022
015ff8d
Merge branch 'thays_support_multithreaded_debugging' of github.com:th…
thaystg Aug 30, 2022
b028deb
Rewrite code to avoid duplicated code.
thaystg Sep 1, 2022
037c9f2
Fix where mono_init_debugger_agent_common is called.
thaystg Sep 1, 2022
df269dd
Remove whitespace.
thaystg Sep 1, 2022
bcf9257
Merge branch 'main' into thays_support_multithreaded_debugging
thaystg Oct 6, 2022
d11eaf8
Update src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs
thaystg Oct 10, 2022
ac4fdec
Update src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs
thaystg Oct 10, 2022
3fdcc8d
Update src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs
thaystg Oct 11, 2022
a9bd192
[wasm] Debugger tests: support running with multithreaded runtime
radical Oct 11, 2022
ec9b436
Add runtime-wasm-dbgtests pipeline with debugger tests running on a m…
radical Oct 11, 2022
c5808dd
Add multi-threaded debugger tests to runtime-wasm
radical Oct 11, 2022
ba0c29c
fix yml
radical Oct 11, 2022
0865ed8
Always run the new tests when the pipeline is invoked manually
radical Oct 11, 2022
ab9b21f
Pass through extra build args for wasm debugger tests
radical Oct 11, 2022
7557dac
Addressing @radical comments.
thaystg Oct 13, 2022
1b6c880
Apply suggestions from code review
thaystg Oct 14, 2022
1aee947
addressing radical comments
thaystg Oct 14, 2022
40e0adb
Merge branch 'dotnet:main' into thays_support_multithreaded_debugging
thaystg Oct 14, 2022
884bd16
Fixing tests failures and adding a schema to run a test that will onl…
thaystg Oct 17, 2022
18cb993
Adding support for run debugger-tests in a multithreaded runtime.
thaystg Oct 18, 2022
40afb37
Fix running debugger tests for multithreaded runtime, passing session…
thaystg Oct 19, 2022
be15c98
Fix CI.
thaystg Oct 19, 2022
369f925
Addressing @radical comments
thaystg Oct 20, 2022
06bae94
Update src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs
thaystg Oct 21, 2022
ff6bba0
Update src/mono/wasm/debugger/DebuggerTestSuite/MiscTests.cs
thaystg Oct 21, 2022
ab98d6a
Update src/mono/wasm/debugger/DebuggerTestSuite/InspectorClient.cs
thaystg Oct 21, 2022
e46bf4d
Dictionary with the scriptId also uses sessionId.
thaystg Oct 21, 2022
b194f06
Addressing @radical review.
thaystg Oct 21, 2022
1d6e5f8
Apply suggestions from code review
thaystg Oct 21, 2022
f87289b
Avoiding getting this error: Cannot transition thread 0x2a15360 from …
thaystg Oct 21, 2022
5db7881
Addressing @radical comments.
thaystg Oct 21, 2022
76c1731
Using more threads in unit test.
thaystg Oct 25, 2022
7af4999
Apply suggestions from code review
thaystg Oct 25, 2022
a9d7468
Addressing @radical comments, and trying to fix ci.
thaystg Oct 25, 2022
3a5b1ea
Merge remote-tracking branch 'origin/main' into thays_support_multith…
thaystg Jan 24, 2023
391b94c
Removing unnecessary changes.
thaystg Jan 27, 2023
1e7f725
Export function used on mini-wasm-debugger.
thaystg Jan 27, 2023
e7779e8
Fixing line number.
thaystg Jan 27, 2023
1a33ae7
Merge branch 'dotnet:main' into thays_support_multithreaded_debugging
thaystg Jan 27, 2023
4e52809
Fix run tests on release.
thaystg Jan 30, 2023
a28845a
fix compilation for multithread runtime
thaystg Jan 30, 2023
0034d64
trying to fix multithread debugger tests on ci
thaystg Jan 30, 2023
2635990
trying to fix debugger tests on ci
thaystg Jan 30, 2023
e22929e
Merge branch 'dotnet:main' into thays_support_multithreaded_debugging
thaystg Jan 30, 2023
33b6485
disabling tests on multithreaded runtime
thaystg Jan 31, 2023
4cd3536
Update eng/pipelines/extra-platforms/runtime-extra-platforms-wasm.yml
thaystg Feb 1, 2023
771d55b
Merge branch 'dotnet:main' into thays_support_multithreaded_debugging
thaystg Feb 1, 2023
c78ec41
Throwing an exception if the "what" is not the one that is being get …
thaystg Feb 1, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions eng/pipelines/common/templates/wasm-debugger-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ parameters:
isWasmOnlyBuild: false
browser: 'chrome'
shouldContinueOnError: false
extraBuildArgs: ''
nameSuffix: ''
platforms: []

jobs:
Expand All @@ -30,8 +32,11 @@ jobs:
jobParameters:
testGroup: innerloop
isExtraPlatforms: ${{ parameters.isExtraPlatformsBuild }}
nameSuffix: Mono_DebuggerTests_${{ parameters.browser }}
buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:TestWasmDebuggerTests=true /p:TestAssemblies=false /p:BrowserHost=$(_hostedOs) /p:DebuggerHost=${{ parameters.browser }}
${{ if eq(parameters.nameSuffix, '') }}:
nameSuffix: Mono_DebuggerTests_${{ parameters.browser }}
${{ else }}:
nameSuffix: ${{ parameters.nameSuffix }}
buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:TestWasmDebuggerTests=true /p:TestAssemblies=false /p:BrowserHost=$(_hostedOs) /p:DebuggerHost=${{ parameters.browser }} ${{ parameters.extraBuildArgs }}
timeoutInMinutes: 180
# if !alwaysRun, then:
# if this is runtime-wasm (isWasmOnlyBuild):
Expand Down
13 changes: 12 additions & 1 deletion eng/pipelines/extra-platforms/runtime-extra-platforms-wasm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ jobs:
- WasmTestOnBrowser
- WasmTestOnNodeJS

# Library tests with full threading
# Library tests with full threading
- template: /eng/pipelines/common/templates/wasm-library-tests.yml
parameters:
platforms:
Expand Down Expand Up @@ -213,6 +213,17 @@ jobs:
# ff tests are unstable currently
shouldContinueOnError: true

- template: /eng/pipelines/common/templates/wasm-debugger-tests.yml
parameters:
platforms:
- Browser_wasm
- Browser_wasm_win
extraBuildArgs: /p:MonoWasmBuildVariant=multithread /p:WasmEnableThreads=true
nameSuffix: DebuggerTests_MultiThreaded
alwaysRun: ${{ parameters.isWasmOnlyBuild }}
isExtraPlatformsBuild: ${{ parameters.isExtraPlatformsBuild }}
isWasmOnlyBuild: ${{ parameters.isWasmOnlyBuild }}

# Disable for now
#- template: /eng/pipelines/coreclr/perf-wasm-jobs.yml
#parameters:
Expand Down
41 changes: 41 additions & 0 deletions eng/pipelines/runtime-wasm-dbgtests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
trigger: none

variables:
- template: /eng/pipelines/common/variables.yml

jobs:

#
# Evaluate paths
#
- template: /eng/pipelines/common/evaluate-default-paths.yml
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine for now. But in a follow up we should change this to use these from runtime-extra-platforms-wasm.yml with a new debuggerTestsOnly parameter.


# Debugger tests
- template: /eng/pipelines/common/templates/wasm-debugger-tests.yml
parameters:
platforms:
- Browser_wasm
- Browser_wasm_win
isExtraPlatformsBuild: ${{ parameters.isExtraPlatformsBuild }}
isWasmOnlyBuild: ${{ parameters.isWasmOnlyBuild }}

- template: /eng/pipelines/common/templates/wasm-debugger-tests.yml
parameters:
platforms:
- Browser_wasm
- Browser_wasm_win
extraBuildArgs: /p:MonoWasmBuildVariant=multithread /p:WasmEnableThreads=true
nameSuffix: DebuggerTests_MultiThreaded
isExtraPlatformsBuild: ${{ parameters.isExtraPlatformsBuild }}
isWasmOnlyBuild: ${{ parameters.isWasmOnlyBuild }}

- template: /eng/pipelines/common/templates/wasm-debugger-tests.yml
parameters:
platforms:
- Browser_wasm_firefox
browser: firefox
isExtraPlatformsBuild: ${{ parameters.isExtraPlatformsBuild }}
isWasmOnlyBuild: ${{ parameters.isWasmOnlyBuild }}
alwaysRun: ${{ parameters.isWasmOnlyBuild }}
# ff tests are unstable currently
shouldContinueOnError: true
93 changes: 45 additions & 48 deletions src/mono/mono/component/debugger-agent.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,6 @@ typedef struct {
/*
* Globals
*/
#ifdef TARGET_WASM
static DebuggerTlsData debugger_wasm_thread;
#endif
static AgentConfig agent_config;

/*
Expand Down Expand Up @@ -414,7 +411,7 @@ static gint32 suspend_count;
/* Whenever to buffer reply messages and send them together */
static gboolean buffer_replies;

#ifndef TARGET_WASM

#define GET_TLS_DATA_FROM_THREAD(thread) \
DebuggerTlsData *tls = NULL; \
mono_loader_lock(); \
Expand All @@ -424,15 +421,6 @@ static gboolean buffer_replies;
#define GET_DEBUGGER_TLS() \
DebuggerTlsData *tls; \
tls = (DebuggerTlsData *)mono_native_tls_get_value (debugger_tls_id);
#else
/* the thread argument is omitted on wasm, to avoid compiler warning */
#define GET_TLS_DATA_FROM_THREAD(...) \
DebuggerTlsData *tls; \
tls = &debugger_wasm_thread;
#define GET_DEBUGGER_TLS() \
DebuggerTlsData *tls; \
tls = &debugger_wasm_thread;
#endif

#define GET_EXTRA_SPACE_FOR_REF_FIELDS(klass) \
extra_space_size = 0; \
Expand Down Expand Up @@ -528,6 +516,8 @@ static void process_profiler_event (EventKind event, gpointer arg);

static void invalidate_frames (DebuggerTlsData *tls);

static void mono_init_debugger_agent_common (MonoProfilerHandle *prof);

/* Callbacks used by debugger-engine */
static MonoContext* tls_get_restore_state (void *the_tls);
static gboolean try_process_suspend (void *tls, MonoContext *ctx, gboolean from_breakpoint);
Expand Down Expand Up @@ -814,25 +804,13 @@ mono_debugger_agent_init_internal (void)
mono_profiler_set_domain_loaded_callback (prof, appdomain_load);
mono_profiler_set_domain_unloading_callback (prof, appdomain_start_unload);
mono_profiler_set_domain_unloaded_callback (prof, appdomain_unload);
mono_profiler_set_thread_started_callback (prof, thread_startup);
mono_profiler_set_thread_stopped_callback (prof, thread_end);
mono_profiler_set_assembly_loaded_callback (prof, assembly_load);
mono_profiler_set_assembly_unloading_callback (prof, assembly_unload);
mono_profiler_set_jit_done_callback (prof, jit_done);
mono_profiler_set_jit_failed_callback (prof, jit_failed);
mono_profiler_set_gc_finalizing_callback (prof, gc_finalizing);
mono_profiler_set_gc_finalized_callback (prof, gc_finalized);

mono_native_tls_alloc (&debugger_tls_id, NULL);

/* Needed by the hash_table_new_type () call below */
mono_gc_base_init ();

thread_to_tls = mono_g_hash_table_new_type_internal ((GHashFunc)mono_object_hash_internal, NULL, MONO_HASH_KEY_GC, MONO_ROOT_SOURCE_DEBUGGER, NULL, "Debugger TLS Table");

tid_to_thread = mono_g_hash_table_new_type_internal (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DEBUGGER, NULL, "Debugger Thread Table");

tid_to_thread_obj = mono_g_hash_table_new_type_internal (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DEBUGGER, NULL, "Debugger Thread Object Table");
mono_init_debugger_agent_common (&prof);

pending_assembly_loads = g_ptr_array_new ();

Expand All @@ -852,7 +830,6 @@ mono_debugger_agent_init_internal (void)
}
mono_de_set_log_level (log_level, log_file);

ids_init ();
objrefs_init ();
suspend_init ();

Expand Down Expand Up @@ -1636,6 +1613,31 @@ static GHashTable *obj_to_objref;
/* Protected by the dbg lock */
static MonoGHashTable *suspended_objs;

static void
mono_init_debugger_agent_common (MonoProfilerHandle *prof)
{
ids_init ();

event_requests = g_ptr_array_new ();

pending_assembly_loads = g_ptr_array_new ();

mono_profiler_set_thread_started_callback (*prof, thread_startup);
mono_profiler_set_thread_stopped_callback (*prof, thread_end);
mono_profiler_set_jit_done_callback (*prof, jit_done);

mono_native_tls_alloc (&debugger_tls_id, NULL);

/* Needed by the hash_table_new_type () call below */
mono_gc_base_init ();

thread_to_tls = mono_g_hash_table_new_type_internal ((GHashFunc)mono_object_hash_internal, NULL, MONO_HASH_KEY_GC, MONO_ROOT_SOURCE_DEBUGGER, NULL, "Debugger TLS Table");

tid_to_thread = mono_g_hash_table_new_type_internal (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DEBUGGER, NULL, "Debugger Thread Table");

tid_to_thread_obj = mono_g_hash_table_new_type_internal (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DEBUGGER, NULL, "Debugger Thread Object Table");
}

#ifdef TARGET_WASM
void
mono_init_debugger_agent_for_wasm (int log_level_parm, MonoProfilerHandle *prof)
Expand All @@ -1646,23 +1648,17 @@ mono_init_debugger_agent_for_wasm (int log_level_parm, MonoProfilerHandle *prof)
int ntransports = 0;
DebuggerTransport *transports = mono_debugger_agent_get_transports (&ntransports);

ids_init();
objrefs = g_hash_table_new_full (NULL, NULL, NULL, mono_debugger_free_objref);
obj_to_objref = g_hash_table_new (NULL, NULL);
pending_assembly_loads = g_ptr_array_new ();

log_level = log_level_parm;
event_requests = g_ptr_array_new ();

vm_start_event_sent = TRUE;
transport = &transports [0];

memset(&debugger_wasm_thread, 0, sizeof(DebuggerTlsData));
mono_native_tls_alloc (&debugger_tls_id, NULL);
mono_native_tls_set_value (debugger_tls_id, &debugger_wasm_thread);

agent_config.enabled = TRUE;

mono_profiler_set_jit_done_callback (*prof, jit_done);
mono_init_debugger_agent_common (prof);
}

void
Expand Down Expand Up @@ -2255,14 +2251,17 @@ save_thread_context (MonoContext *ctx)
void
mono_wasm_save_thread_context (void)
{
debugger_wasm_thread.really_suspended = TRUE;
mono_thread_state_init_from_current (&debugger_wasm_thread.context);
DebuggerTlsData* tls = mono_wasm_get_tls ();
tls->really_suspended = TRUE;
mono_thread_state_init_from_current (&tls->context);
}

DebuggerTlsData*
mono_wasm_get_tls (void)
{
return &debugger_wasm_thread;
MonoThread *thread = mono_thread_current ();
GET_TLS_DATA_FROM_THREAD (thread);
return tls;
}
#endif

Expand Down Expand Up @@ -2855,7 +2854,11 @@ wait_for_suspend (void)
static gboolean
is_suspended (void)
{
#ifdef HOST_WASM
return true;
#else
return count_threads_to_wait_for () == 0;
#endif
}

static void
Expand Down Expand Up @@ -3762,6 +3765,7 @@ process_event (EventKind event, gpointer arg, gint32 il_offset, MonoContext *ctx

#ifdef TARGET_WASM
PRINT_DEBUG_MSG (1, "[%p] Sent %d events %s(%d), suspend=%d.\n", (gpointer) (gsize) mono_native_thread_id_get (), nevents, event_to_string (event), ecount, suspend_policy);
mono_wasm_save_thread_context();
#endif

send_success = send_packet (CMD_SET_EVENT, CMD_COMPOSITE, &buf);
Expand Down Expand Up @@ -3910,8 +3914,9 @@ thread_startup (MonoProfiler *prof, uintptr_t tid)
/*
* suspend_vm () could have missed this thread, so wait for a resume.
*/

#ifndef HOST_WASM
suspend_current_func ();
#endif
}

static void
Expand Down Expand Up @@ -9313,7 +9318,7 @@ thread_commands (int command, guint8 *p, guint8 *end, Buffer *buf)

// Wait for suspending if it already started
// FIXME: Races with suspend_count
#ifndef HOST_WASI
#if !defined(HOST_WASI) && !defined(HOST_WASM)
while (!is_suspended ()) {
if (suspend_count)
wait_for_suspend ();
Expand Down Expand Up @@ -9498,9 +9503,7 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
int objid;
ErrorCode err;
MonoThread *thread_obj;
#ifndef TARGET_WASM
MonoInternalThread *thread;
#endif
int pos, i, len, frame_idx;
StackFrame *frame;
MonoDebugMethodJitInfo *jit;
Expand All @@ -9514,16 +9517,10 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
if (err != ERR_NONE)
return err;

#ifndef TARGET_WASM
thread = THREAD_TO_INTERNAL (thread_obj);
#endif
id = decode_id (p, &p, end);

#ifndef TARGET_WASM
GET_TLS_DATA_FROM_THREAD (thread);
#else
GET_TLS_DATA_FROM_THREAD ();
#endif
g_assert (tls);

for (i = 0; i < tls->frame_count; ++i) {
Expand Down
17 changes: 10 additions & 7 deletions src/mono/mono/component/mini-wasm-debugger.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ EMSCRIPTEN_KEEPALIVE gboolean mono_wasm_send_dbg_command_with_parms (int id, Mdb


//JS functions imported that we use
extern void mono_wasm_fire_debugger_agent_message (void);
extern void mono_wasm_fire_debugger_agent_message_with_data (const char *data, int len);
extern void mono_wasm_asm_loaded (const char *asm_name, const char *assembly_data, guint32 assembly_len, const char *pdb_data, guint32 pdb_len);

G_END_DECLS
Expand Down Expand Up @@ -382,7 +382,7 @@ mono_wasm_send_dbg_command_with_parms (int id, MdbgProtCommandSet command_set, i
goto done;
}
MdbgProtBuffer bufWithParms;
buffer_init (&bufWithParms, 128);
m_dbgprot_buffer_init (&bufWithParms, 128);
radical marked this conversation as resolved.
Show resolved Hide resolved
m_dbgprot_buffer_add_data (&bufWithParms, data, size);
if (!write_value_to_buffer(&bufWithParms, valtype, newvalue)) {
mono_wasm_add_dbg_command_received(0, id, 0, 0);
Expand Down Expand Up @@ -410,11 +410,11 @@ mono_wasm_send_dbg_command (int id, MdbgProtCommandSet command_set, int command,
}
ss_calculate_framecount (NULL, NULL, TRUE, NULL, NULL);
MdbgProtBuffer buf;
buffer_init (&buf, 128);
gboolean no_reply;
MdbgProtErrorCode error = 0;
if (command_set == MDBGPROT_CMD_SET_VM && command == MDBGPROT_CMD_VM_INVOKE_METHOD )
{
m_dbgprot_buffer_init (&buf, 128);
DebuggerTlsData* tls = mono_wasm_get_tls ();
InvokeData invoke_data;
memset (&invoke_data, 0, sizeof (InvokeData));
Expand All @@ -426,6 +426,7 @@ mono_wasm_send_dbg_command (int id, MdbgProtCommandSet command_set, int command,
char* assembly_name = m_dbgprot_decode_string (data, &data, data + size);
if (assembly_name == NULL)
{
m_dbgprot_buffer_init (&buf, 128);
m_dbgprot_buffer_add_int (&buf, 0);
m_dbgprot_buffer_add_int (&buf, 0);
}
Expand All @@ -435,16 +436,20 @@ mono_wasm_send_dbg_command (int id, MdbgProtCommandSet command_set, int command,
int symfile_size = 0;
const unsigned char* assembly_bytes = mono_wasm_get_assembly_bytes (assembly_name, &assembly_size);
const unsigned char* pdb_bytes = mono_get_symfile_bytes_from_bundle (assembly_name, &symfile_size);
m_dbgprot_buffer_init (&buf, assembly_size + symfile_size);
m_dbgprot_buffer_add_byte_array (&buf, (uint8_t *) assembly_bytes, assembly_size);
m_dbgprot_buffer_add_byte_array (&buf, (uint8_t *) pdb_bytes, symfile_size);
}
}
else
{
m_dbgprot_buffer_init (&buf, 128);
error = mono_process_dbg_packet (id, command_set, command, &no_reply, data, data + size, &buf);
}

mono_wasm_add_dbg_command_received (error == MDBGPROT_ERR_NONE, id, buf.buf, buf.p-buf.buf);

buffer_free (&buf);
m_dbgprot_buffer_free (&buf);
result = TRUE;
done:
MONO_EXIT_GC_UNSAFE;
Expand All @@ -454,9 +459,7 @@ mono_wasm_send_dbg_command (int id, MdbgProtCommandSet command_set, int command,
static gboolean
receive_debugger_agent_message (void *data, int len)
{
mono_wasm_add_dbg_command_received(1, 0, data, len);
mono_wasm_save_thread_context();
mono_wasm_fire_debugger_agent_message ();
mono_wasm_fire_debugger_agent_message_with_data ((const char*)data, len);
return FALSE;
}

Expand Down
Loading