Skip to content

Commit ae99bb2

Browse files
thaystgradical
andauthored
[wasm][debugger] Improve debugger performance based on JMC (#86982)
* Improve debugger performance. * Loading assembly bytes if JMC is disabled after the debugger session is started. * Fix CI. * Load symbols on demand if JMC is enabled, we don't need to spend a lot of time loading information from 149 assemblies if we will probably not need all of them. * Impriving the performance sending only metadata and not the full assembly. * Fixing compilation error on tvos * Apply suggestions from code review Co-authored-by: Ankit Jain <[email protected]> * Apply suggestions from code review Co-authored-by: Ankit Jain <[email protected]> * fix changes from code review * addressing @radical comments * addressing @radical and @lewing comments --------- Co-authored-by: Ankit Jain <[email protected]>
1 parent 2ad94b4 commit ae99bb2

File tree

6 files changed

+327
-151
lines changed

6 files changed

+327
-151
lines changed

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

Lines changed: 136 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
#include <mono/metadata/custom-attrs-internals.h>
100100
#include <mono/metadata/components.h>
101101
#include <mono/mini/debugger-agent-external.h>
102+
#include <mono/metadata/bundled-resources-internals.h>
102103

103104
#ifdef HAVE_UCONTEXT_H
104105
#include <ucontext.h>
@@ -6945,6 +6946,88 @@ valid_memory_address (gpointer addr, gint size)
69456946
return ret;
69466947
}
69476948

6949+
static MonoAssembly*
6950+
find_assembly_by_name (char* assembly_name)
6951+
{
6952+
//we get 'foo.dll' but mono_assembly_load expects 'foo' so we strip the last dot
6953+
char *lookup_name = g_strdup (assembly_name);
6954+
for (int i = ((int)strlen (lookup_name) - 1); i >= 0; --i) {
6955+
if (lookup_name [i] == '.') {
6956+
lookup_name [i] = 0;
6957+
break;
6958+
}
6959+
}
6960+
6961+
//resolve the assembly
6962+
MonoImageOpenStatus status;
6963+
MonoAssemblyName* aname = mono_assembly_name_new (lookup_name);
6964+
g_free (lookup_name);
6965+
if (!aname) {
6966+
PRINT_DEBUG_MSG (1, "Could not resolve assembly %s\n", assembly_name);
6967+
return NULL;
6968+
}
6969+
6970+
MonoAssemblyByNameRequest byname_req;
6971+
mono_assembly_request_prepare_byname (&byname_req, mono_alc_get_default ());
6972+
MonoAssembly *assembly = mono_assembly_request_byname (aname, &byname_req, &status);
6973+
if (!assembly) {
6974+
GPtrArray *assemblies = mono_alc_get_all_loaded_assemblies ();
6975+
for (guint i = 0; i < assemblies->len; ++i) {
6976+
MonoAssembly *assemblyOnALC = (MonoAssembly*)g_ptr_array_index (assemblies, i);
6977+
if (!strcmp(assemblyOnALC->aname.name, aname->name)) {
6978+
assembly = assemblyOnALC;
6979+
break;
6980+
}
6981+
}
6982+
g_ptr_array_free (assemblies, TRUE);
6983+
if (!assembly) {
6984+
PRINT_DEBUG_MSG (1, "Could not resolve assembly %s\n", assembly_name);
6985+
goto exit;
6986+
}
6987+
}
6988+
exit:
6989+
mono_assembly_name_free_internal (aname);
6990+
return assembly;
6991+
}
6992+
6993+
static void
6994+
send_debug_information (MonoAssembly *ass, Buffer *buf)
6995+
{
6996+
guint8 pe_guid [16];
6997+
gint32 pe_age;
6998+
gint32 pe_timestamp;
6999+
guint8 *ppdb_data = NULL;
7000+
int ppdb_size = 0, ppdb_compressed_size = 0;
7001+
char *ppdb_path;
7002+
GArray *pdb_checksum_hash_type = g_array_new (FALSE, TRUE, sizeof (char*));
7003+
GArray *pdb_checksum = g_array_new (FALSE, TRUE, sizeof (guint8*));
7004+
gboolean has_debug_info = mono_get_pe_debug_info_full (ass->image, pe_guid, &pe_age, &pe_timestamp, &ppdb_data, &ppdb_size, &ppdb_compressed_size, &ppdb_path, pdb_checksum_hash_type, pdb_checksum);
7005+
if (!has_debug_info || ppdb_size > 0)
7006+
{
7007+
buffer_add_byte (buf, 0);
7008+
g_array_free (pdb_checksum_hash_type, TRUE);
7009+
g_array_free (pdb_checksum, TRUE);
7010+
return;
7011+
}
7012+
buffer_add_byte (buf, 1);
7013+
buffer_add_int (buf, pe_age);
7014+
buffer_add_byte_array (buf, pe_guid, 16);
7015+
buffer_add_string (buf, ppdb_path);
7016+
buffer_add_int (buf, pdb_checksum_hash_type->len);
7017+
for (int i = 0 ; i < pdb_checksum_hash_type->len; ++i) {
7018+
char* checksum_hash_type = g_array_index (pdb_checksum_hash_type, char*, i);
7019+
buffer_add_string (buf, checksum_hash_type);
7020+
if (!strcmp (checksum_hash_type, "SHA256"))
7021+
buffer_add_byte_array (buf, g_array_index (pdb_checksum, guint8*, i), 32);
7022+
else if (!strcmp (checksum_hash_type, "SHA384"))
7023+
buffer_add_byte_array (buf, g_array_index (pdb_checksum, guint8*, i), 48);
7024+
else if (!strcmp (checksum_hash_type, "SHA512"))
7025+
buffer_add_byte_array (buf, g_array_index (pdb_checksum, guint8*, i), 64);
7026+
}
7027+
g_array_free (pdb_checksum_hash_type, TRUE);
7028+
g_array_free (pdb_checksum, TRUE);
7029+
}
7030+
69487031
static ErrorCode
69497032
vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf)
69507033
{
@@ -7303,45 +7386,9 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf)
73037386
}
73047387
case MDBGPROT_CMD_GET_ASSEMBLY_BY_NAME: {
73057388
char* assembly_name = decode_string (p, &p, end);
7306-
//we get 'foo.dll' but mono_assembly_load expects 'foo' so we strip the last dot
7307-
char *lookup_name = g_strdup (assembly_name);
7308-
for (int i = ((int)strlen (lookup_name) - 1); i >= 0; --i) {
7309-
if (lookup_name [i] == '.') {
7310-
lookup_name [i] = 0;
7311-
break;
7312-
}
7313-
}
7314-
7315-
//resolve the assembly
7316-
MonoImageOpenStatus status;
7317-
MonoAssemblyName* aname = mono_assembly_name_new (lookup_name);
7318-
if (!aname) {
7319-
PRINT_DEBUG_MSG (1, "Could not resolve assembly %s\n", assembly_name);
7320-
buffer_add_int(buf, -1);
7321-
break;
7322-
}
7323-
MonoAssemblyByNameRequest byname_req;
7324-
mono_assembly_request_prepare_byname (&byname_req, mono_alc_get_default ());
7325-
MonoAssembly *assembly = mono_assembly_request_byname (aname, &byname_req, &status);
7326-
g_free (lookup_name);
7327-
if (!assembly) {
7328-
GPtrArray *assemblies = mono_alc_get_all_loaded_assemblies ();
7329-
for (guint i = 0; i < assemblies->len; ++i) {
7330-
MonoAssembly *assemblyOnALC = (MonoAssembly*)g_ptr_array_index (assemblies, i);
7331-
if (!strcmp(assemblyOnALC->aname.name, aname->name)) {
7332-
assembly = assemblyOnALC;
7333-
break;
7334-
}
7335-
}
7336-
g_ptr_array_free (assemblies, TRUE);
7337-
if (!assembly) {
7338-
PRINT_DEBUG_MSG (1, "Could not resolve assembly %s\n", assembly_name);
7339-
buffer_add_int(buf, -1);
7340-
mono_assembly_name_free_internal (aname);
7341-
break;
7342-
}
7343-
}
7344-
mono_assembly_name_free_internal (aname);
7389+
MonoAssembly* assembly = find_assembly_by_name (assembly_name);
7390+
if (!assembly)
7391+
buffer_add_int (buf, -1);
73457392
buffer_add_assemblyid (buf, mono_get_root_domain (), assembly);
73467393
break;
73477394
}
@@ -7418,6 +7465,55 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf)
74187465
}
74197466
break;
74207467
}
7468+
case MDBGPROT_CMD_GET_ASSEMBLY_BYTES: { //only used by wasm
7469+
#ifdef HOST_WASM
7470+
char* assembly_name = m_dbgprot_decode_string (p, &p, end);
7471+
if (assembly_name == NULL)
7472+
{
7473+
m_dbgprot_buffer_add_int (buf, 0);
7474+
m_dbgprot_buffer_add_int (buf, 0);
7475+
m_dbgprot_buffer_add_int (buf, 0);
7476+
}
7477+
else
7478+
{
7479+
int ppdb_size = 0;
7480+
const unsigned char* assembly_bytes = NULL;
7481+
unsigned int assembly_size = 0;
7482+
const unsigned char* pdb_bytes = NULL;
7483+
unsigned int symfile_size = 0;
7484+
mono_bundled_resources_get_assembly_resource_symbol_values (assembly_name, &pdb_bytes, &symfile_size);
7485+
MonoAssembly* assembly = find_assembly_by_name (assembly_name);
7486+
assembly_size = assembly->image->image_info->cli_cli_header.ch_metadata.size;
7487+
assembly_bytes = (const unsigned char*) assembly->image->raw_metadata;
7488+
if (symfile_size == 0) //try to send embedded pdb data
7489+
{
7490+
guint8 pe_guid [16];
7491+
gint32 pe_age;
7492+
gint32 pe_timestamp;
7493+
guint8 *ppdb_data = NULL;
7494+
int ppdb_compressed_size = 0;
7495+
char *ppdb_path;
7496+
mono_get_pe_debug_info_full (assembly->image, pe_guid, &pe_age, &pe_timestamp, &ppdb_data, &ppdb_size, &ppdb_compressed_size, &ppdb_path, NULL, NULL);
7497+
if (ppdb_compressed_size > 0)
7498+
{
7499+
symfile_size = ppdb_compressed_size;
7500+
pdb_bytes = ppdb_data;
7501+
}
7502+
}
7503+
m_dbgprot_buffer_init (buf, assembly_size + symfile_size + 1024);
7504+
m_dbgprot_buffer_add_byte_array (buf, (uint8_t *) assembly_bytes, assembly_size);
7505+
m_dbgprot_buffer_add_int (buf, ppdb_size);
7506+
m_dbgprot_buffer_add_byte_array (buf, (uint8_t *) pdb_bytes, symfile_size);
7507+
if (assembly)
7508+
send_debug_information (assembly, buf);
7509+
}
7510+
#else
7511+
m_dbgprot_buffer_add_int (buf, 0);
7512+
m_dbgprot_buffer_add_int (buf, 0);
7513+
m_dbgprot_buffer_add_int (buf, 0);
7514+
#endif
7515+
break;
7516+
}
74217517
default:
74227518
return ERR_NOT_IMPLEMENTED;
74237519
}
@@ -8042,39 +8138,7 @@ assembly_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
80428138
break;
80438139
}
80448140
case MDBGPROT_CMD_ASSEMBLY_GET_DEBUG_INFORMATION: {
8045-
guint8 pe_guid [16];
8046-
gint32 pe_age;
8047-
gint32 pe_timestamp;
8048-
guint8 *ppdb_data = NULL;
8049-
int ppdb_size = 0, ppdb_compressed_size = 0;
8050-
char *ppdb_path;
8051-
GArray *pdb_checksum_hash_type = g_array_new (FALSE, TRUE, sizeof (char*));
8052-
GArray *pdb_checksum = g_array_new (FALSE, TRUE, sizeof (guint8*));
8053-
gboolean has_debug_info = mono_get_pe_debug_info_full (ass->image, pe_guid, &pe_age, &pe_timestamp, &ppdb_data, &ppdb_size, &ppdb_compressed_size, &ppdb_path, pdb_checksum_hash_type, pdb_checksum);
8054-
if (!has_debug_info || ppdb_size > 0)
8055-
{
8056-
buffer_add_byte (buf, 0);
8057-
g_array_free (pdb_checksum_hash_type, TRUE);
8058-
g_array_free (pdb_checksum, TRUE);
8059-
return ERR_NONE;
8060-
}
8061-
buffer_add_byte (buf, 1);
8062-
buffer_add_int (buf, pe_age);
8063-
buffer_add_byte_array (buf, pe_guid, 16);
8064-
buffer_add_string (buf, ppdb_path);
8065-
buffer_add_int (buf, pdb_checksum_hash_type->len);
8066-
for (int i = 0 ; i < pdb_checksum_hash_type->len; ++i) {
8067-
char* checksum_hash_type = g_array_index (pdb_checksum_hash_type, char*, i);
8068-
buffer_add_string (buf, checksum_hash_type);
8069-
if (!strcmp (checksum_hash_type, "SHA256"))
8070-
buffer_add_byte_array (buf, g_array_index (pdb_checksum, guint8*, i), 32);
8071-
else if (!strcmp (checksum_hash_type, "SHA384"))
8072-
buffer_add_byte_array (buf, g_array_index (pdb_checksum, guint8*, i), 48);
8073-
else if (!strcmp (checksum_hash_type, "SHA512"))
8074-
buffer_add_byte_array (buf, g_array_index (pdb_checksum, guint8*, i), 64);
8075-
}
8076-
g_array_free (pdb_checksum_hash_type, TRUE);
8077-
g_array_free (pdb_checksum, TRUE);
8141+
send_debug_information (ass, buf);
80788142
break;
80798143
}
80808144
case MDBGPROT_CMD_ASSEMBLY_HAS_DEBUG_INFO_LOADED: {

src/mono/mono/component/debugger-protocol.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*/
1212

1313
#define MAJOR_VERSION 2
14-
#define MINOR_VERSION 63
14+
#define MINOR_VERSION 64
1515

1616
typedef enum {
1717
MDBGPROT_CMD_COMPOSITE = 100

src/mono/mono/component/mini-wasm-debugger.c

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -432,28 +432,6 @@ mono_wasm_send_dbg_command (int id, MdbgProtCommandSet command_set, int command,
432432
invoke_data.flags = INVOKE_FLAG_DISABLE_BREAKPOINTS_AND_STEPPING;
433433
error = mono_do_invoke_method (tls, &buf, &invoke_data, data, &data);
434434
}
435-
else if (command_set == MDBGPROT_CMD_SET_VM && (command == MDBGPROT_CMD_GET_ASSEMBLY_BYTES))
436-
{
437-
char* assembly_name = m_dbgprot_decode_string (data, &data, data + size);
438-
if (assembly_name == NULL)
439-
{
440-
m_dbgprot_buffer_init (&buf, 128);
441-
m_dbgprot_buffer_add_int (&buf, 0);
442-
m_dbgprot_buffer_add_int (&buf, 0);
443-
}
444-
else
445-
{
446-
const unsigned char* assembly_bytes = NULL;
447-
unsigned int assembly_size = 0;
448-
mono_bundled_resources_get_assembly_resource_values (assembly_name, &assembly_bytes, &assembly_size);
449-
const unsigned char* pdb_bytes = NULL;
450-
unsigned int symfile_size = 0;
451-
mono_bundled_resources_get_assembly_resource_symbol_values (assembly_name, &pdb_bytes, &symfile_size);
452-
m_dbgprot_buffer_init (&buf, assembly_size + symfile_size);
453-
m_dbgprot_buffer_add_byte_array (&buf, (uint8_t *) assembly_bytes, assembly_size);
454-
m_dbgprot_buffer_add_byte_array (&buf, (uint8_t *) pdb_bytes, symfile_size);
455-
}
456-
}
457435
else
458436
{
459437
m_dbgprot_buffer_init (&buf, 128);

0 commit comments

Comments
 (0)