Sfoglia il codice sorgente

[debugger] Ports from dotnet/runtime to maintain compatibility (#21653)

Changes:

- Support symbol server on mobile devices: port from https://github.com/dotnet/runtime/pull/82555
- Show loaded symbols on VS module window: port from https://github.com/dotnet/runtime/pull/82587
- Added compatibility with CMD_GET_ENC_CAPABILITIES message: even if C# Hot Reload is not supported in Xamarin Forms, the debug client can send this message if the version is at least 2.61, which it is since the latest changes. See code for reference: https://github.com/mono/debugger-libs/blob/main/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs#L799-L800. For that reason and for compatibility, we should support that message and return "Baseline", the same as the client code does with a lower version.

The main motivation of these ports is to support symbol server in Xamarin legacy, however the other ports are needed because we had to bump the minor version from 58 to 63.
Mauro Agnoletti 2 anni fa
parent
commit
0532e3ee8b

+ 20 - 3
mono/metadata/debug-mono-ppdb.c

@@ -65,9 +65,9 @@ enum {
 	MONO_HAS_CUSTOM_DEBUG_MASK = 0x1f
 };
 
-static gboolean
-get_pe_debug_info (MonoImage *image, guint8 *out_guid, gint32 *out_age, gint32 *out_timestamp, guint8 **ppdb_data,
-				   int *ppdb_uncompressed_size, int *ppdb_compressed_size)
+gboolean 
+mono_get_pe_debug_info_full  (MonoImage *image, guint8 *out_guid, gint32 *out_age, gint32 *out_timestamp, guint8 **ppdb_data,
+									int *ppdb_uncompressed_size, int *ppdb_compressed_size, char **pdb_path, GArray *pdb_checksum_hash_type, GArray *pdb_checksum)
 {
 	MonoPEDirEntry *debug_dir_entry;
 	ImageDebugDirectory debug_dir;
@@ -93,6 +93,14 @@ get_pe_debug_info (MonoImage *image, guint8 *out_guid, gint32 *out_age, gint32 *
 		debug_dir.address         = read32(data + 20);
 		debug_dir.pointer         = read32(data + 24);
 		
+		if (pdb_checksum_hash_type && pdb_checksum && debug_dir.type == DEBUG_DIR_PDB_CHECKSUM)
+		{
+			data  = (guint8 *) (image->raw_data + debug_dir.pointer);
+			char* alg_name = (char*)data;
+			guint8*	checksum = (guint8 *) (data + strlen(alg_name)+ 1);
+			g_array_append_val (pdb_checksum_hash_type, alg_name);
+			g_array_append_val (pdb_checksum, checksum);
+		}
 		if (debug_dir.type == DEBUG_DIR_ENTRY_CODEVIEW && debug_dir.major_version == 0x100 && debug_dir.minor_version == 0x504d) {
 			/* This is a 'CODEVIEW' debug directory */
 			CodeviewDebugDirectory dir;
@@ -102,6 +110,8 @@ get_pe_debug_info (MonoImage *image, guint8 *out_guid, gint32 *out_age, gint32 *
 			if (dir.signature == 0x53445352) {
 				memcpy (out_guid, data + 4, 16);
 				*out_age = read32(data + 20);
+				if (pdb_path)
+					*pdb_path = (char*) data + 24;
 				*out_timestamp = debug_dir.time_date_stamp;
 				guid_found = TRUE;
 			}
@@ -121,6 +131,13 @@ get_pe_debug_info (MonoImage *image, guint8 *out_guid, gint32 *out_age, gint32 *
 	return guid_found;
 }
 
+static gboolean
+get_pe_debug_info (MonoImage *image, guint8 *out_guid, gint32 *out_age, gint32 *out_timestamp, guint8 **ppdb_data,
+									int *ppdb_uncompressed_size, int *ppdb_compressed_size)
+{
+	return mono_get_pe_debug_info_full  (image, out_guid, out_age, out_timestamp, ppdb_data, ppdb_uncompressed_size, ppdb_compressed_size, NULL, NULL, NULL);
+}
+
 static void
 doc_free (gpointer key)
 {

+ 3 - 0
mono/metadata/debug-mono-ppdb.h

@@ -47,4 +47,7 @@ mono_ppdb_get_sourcelink (MonoDebugHandle *handle);
 gboolean 
 mono_ppdb_is_embedded (MonoPPDBFile *ppdb);
 
+gboolean
+mono_get_pe_debug_info_full (MonoImage *image, guint8 *out_guid, gint32 *out_age, gint32 *out_timestamp, guint8 **ppdb_data,
+                                int *ppdb_uncompressed_size, int *ppdb_compressed_size, char **pdb_path, GArray *pdb_checksum_hash_type, GArray *pdb_checksum);
 #endif

+ 61 - 2
mono/mini/debugger-agent.c

@@ -269,7 +269,7 @@ typedef struct {
 #define HEADER_LENGTH 11
 
 #define MAJOR_VERSION 2
-#define MINOR_VERSION 58
+#define MINOR_VERSION 63
 
 typedef enum {
 	CMD_SET_VM = 1,
@@ -358,7 +358,8 @@ typedef enum {
 	CMD_VM_GET_TYPES = 12,
 	CMD_VM_INVOKE_METHODS = 13,
 	CMD_VM_START_BUFFERING = 14,
-	CMD_VM_STOP_BUFFERING = 15
+	CMD_VM_STOP_BUFFERING = 15,
+	CMD_GET_ENC_CAPABILITIES = 21
 } CmdVM;
 
 typedef enum {
@@ -408,6 +409,8 @@ typedef enum {
 	CMD_ASSEMBLY_GET_METHOD_FROM_TOKEN = 12,
 	CMD_ASSEMBLY_HAS_DEBUG_INFO = 13,
 	CMD_ASSEMBLY_GET_CATTRS = 14,
+	CMD_ASSEMBLY_GET_DEBUG_INFORMATION = 17,
+	CMD_ASSEMBLY_HAS_DEBUG_INFO_LOADED = 18
 } CmdAssembly;
 
 typedef enum {
@@ -7312,6 +7315,10 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf)
 	case CMD_VM_STOP_BUFFERING:
 		/* Handled in the main loop */
 		break;
+	case CMD_GET_ENC_CAPABILITIES: {
+		buffer_add_string (buf, "Baseline");
+		break;
+	}
 	default:
 		return ERR_NOT_IMPLEMENTED;
 	}
@@ -7914,6 +7921,58 @@ assembly_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 			return err;
 		break;
 	}
+	case CMD_ASSEMBLY_GET_DEBUG_INFORMATION: {
+		guint8 pe_guid [16];
+		gint32 pe_age;
+		gint32 pe_timestamp;
+		guint8 *ppdb_data = NULL;
+		int ppdb_size = 0, ppdb_compressed_size = 0;
+		char *ppdb_path;
+		GArray *pdb_checksum_hash_type = g_array_new (FALSE, TRUE, sizeof (char*));
+		GArray *pdb_checksum = g_array_new (FALSE, TRUE, sizeof (guint8*));
+		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);
+		if (!has_debug_info || ppdb_size > 0)
+		{
+			buffer_add_byte (buf, 0);
+			g_array_free (pdb_checksum_hash_type, TRUE);
+			g_array_free (pdb_checksum, TRUE);
+			return ERR_NONE;
+		}
+		buffer_add_byte (buf, 1);
+		buffer_add_int (buf, pe_age);
+		buffer_add_byte_array (buf, pe_guid, 16);
+		buffer_add_string (buf, ppdb_path);
+		buffer_add_int (buf, pdb_checksum_hash_type->len);
+		for (int i = 0 ; i < pdb_checksum_hash_type->len; ++i) {
+			char* checksum_hash_type =  g_array_index (pdb_checksum_hash_type, char*, i);
+			buffer_add_string (buf, checksum_hash_type);
+			if (!strcmp (checksum_hash_type, "SHA256"))
+				buffer_add_byte_array (buf, g_array_index (pdb_checksum, guint8*, i), 32);
+			else if (!strcmp (checksum_hash_type, "SHA384"))
+				buffer_add_byte_array (buf, g_array_index (pdb_checksum, guint8*, i), 48);
+			else if (!strcmp (checksum_hash_type, "SHA512"))
+				buffer_add_byte_array (buf, g_array_index (pdb_checksum, guint8*, i), 64);
+		}
+		g_array_free (pdb_checksum_hash_type, TRUE);
+		g_array_free (pdb_checksum, TRUE);
+		break;
+	}
+	case CMD_ASSEMBLY_HAS_DEBUG_INFO_LOADED: {
+		MonoImage* image = ass->image;
+		MonoDebugHandle* handle = mono_debug_get_handle (image);
+		if (!handle) {
+			buffer_add_byte (buf, 0);
+			return ERR_NONE;
+		}
+		MonoPPDBFile* ppdb = handle->ppdb;
+		if (ppdb) {
+			image = mono_ppdb_get_image (ppdb);
+			buffer_add_byte (buf, image->raw_data_len > 0);
+		} else {
+			buffer_add_byte (buf, 0);
+		}
+		break;
+	}
 	default:
 		return ERR_NOT_IMPLEMENTED;
 	}