* Creating more test for hot reload debugging.
* Fixing step on android after hot reload.
* Fix get document information from enc pdb.
* Addressing Aleksey comments.
* Addressing @lambdageek comments and fixing implementation of mono_ppdb_lookup_location
* Fixing compilation on ios.
* Fix android compilation.
ERROR_DECL (error);
MonoDebugMethodInfo *minfo;
char *source_file;
- int i, j, n_il_offsets, n_il_offsets_original;
+ int i, j, n_il_offsets;
int *source_files;
GPtrArray *source_file_list;
MonoSymSeqPoint *sym_seq_points;
break;
}
- mono_debug_get_seq_points (minfo, &source_file, &source_file_list, &source_files, NULL, &n_il_offsets_original);
- mono_debug_get_seq_points (minfo, NULL, NULL, NULL, &sym_seq_points, &n_il_offsets);
+ mono_debug_get_seq_points (minfo,&source_file, &source_file_list, &source_files, &sym_seq_points, &n_il_offsets);
buffer_add_int (buf, header->code_size);
if (CHECK_PROTOCOL_VERSION (2, 13)) {
buffer_add_int (buf, source_file_list->len);
if (source_files [i] != -1) {
int idx = i;
- if (i >= n_il_offsets_original)
- idx = 0;
MonoDebugSourceInfo *sinfo = (MonoDebugSourceInfo *)g_ptr_array_index (source_file_list, source_files [idx]);
srcfile = sinfo->source_file;
}
buffer_add_int (buf, sp->il_offset);
buffer_add_int (buf, sp->line);
if (CHECK_PROTOCOL_VERSION (2, 13))
- buffer_add_int (buf, i >= n_il_offsets_original ? source_files [0] : source_files [i]);
+ buffer_add_int (buf, source_files [i]);
if (CHECK_PROTOCOL_VERSION (2, 19))
buffer_add_int (buf, sp->column);
if (CHECK_PROTOCOL_VERSION (2, 32)) {
#include "mono/utils/mono-lazy-init.h"
#include "mono/utils/mono-logger-internals.h"
#include "mono/utils/mono-path.h"
+#include "mono/metadata/debug-internals.h"
#include "mono/metadata/mono-debug.h"
+#include "mono/metadata/debug-mono-ppdb.h"
#include <mono/component/hot_reload.h>
// for each table, the row in the EncMap table that has the first token for remapping it?
uint32_t enc_recs [MONO_TABLE_NUM];
delta_row_count count [MONO_TABLE_NUM];
+
+ MonoPPDBFile *ppdb_file;
} DeltaInfo;
}
static DeltaInfo*
-delta_info_init (MonoImage *image_dmeta, MonoImage *image_base, BaselineInfo *base_info, uint32_t generation);
+delta_info_init (MonoImage *image_dmeta, MonoImage *image_base, MonoPPDBFile *ppdb_file, BaselineInfo *base_info, uint32_t generation);
static void
free_ppdb_entry (gpointer key, gpointer val, gpointer user_data)
g_hash_table_foreach (dinfo->method_ppdb_table_update, free_ppdb_entry, NULL);
g_hash_table_destroy (dinfo->method_ppdb_table_update);
}
+ mono_ppdb_close (dinfo->ppdb_file);
g_free (dinfo);
}
/* LOCKING: assumes publish_lock is held */
static DeltaInfo*
-delta_info_init (MonoImage *image_dmeta, MonoImage *image_base, BaselineInfo *base_info, uint32_t generation)
+delta_info_init (MonoImage *image_dmeta, MonoImage *image_base, MonoPPDBFile *ppdb_file, BaselineInfo *base_info, uint32_t generation)
{
MonoTableInfo *encmap = &image_dmeta->tables [MONO_TABLE_ENCMAP];
g_assert (!delta_info_lookup (image_dmeta));
DeltaInfo *delta_info = g_malloc0 (sizeof (DeltaInfo));
delta_info->generation = generation;
+ delta_info->ppdb_file = ppdb_file;
table_to_image_lock ();
g_hash_table_insert (delta_image_to_info, image_dmeta, delta_info);
}
static MonoDebugInformationEnc *
-hot_reload_get_method_debug_information (MonoImage *image_dppdb, int idx)
+hot_reload_get_method_debug_information (MonoPPDBFile *ppdb_file, int idx)
{
- if (!image_dppdb)
+ if (!ppdb_file)
return NULL;
-
+
+ MonoImage *image_dppdb = ppdb_file->image;
MonoTableInfo *table_encmap = &image_dppdb->tables [MONO_TABLE_ENCMAP];
int rows = table_info_get_rows (table_encmap);
for (int i = 0; i < rows ; ++i) {
int token_index = mono_metadata_token_index (map_token);
if (token_index == idx) {
MonoDebugInformationEnc *encDebugInfo = g_new0 (MonoDebugInformationEnc, 1);
- encDebugInfo->idx = i;
- encDebugInfo->image = image_dppdb;
+ encDebugInfo->idx = i + 1;
+ encDebugInfo->ppdb_file = ppdb_file;
return encDebugInfo;
}
}
/* do actuall enclog application */
static gboolean
-apply_enclog_pass2 (MonoImage *image_base, BaselineInfo *base_info, uint32_t generation, MonoImage *image_dmeta, MonoImage *image_dppdb, DeltaInfo *delta_info, gconstpointer dil_data, uint32_t dil_length, MonoError *error)
+apply_enclog_pass2 (MonoImage *image_base, BaselineInfo *base_info, uint32_t generation, MonoImage *image_dmeta, DeltaInfo *delta_info, gconstpointer dil_data, uint32_t dil_length, MonoError *error)
{
MonoTableInfo *table_enclog = &image_dmeta->tables [MONO_TABLE_ENCLOG];
int rows = table_info_get_rows (table_enclog);
int rva = mono_metadata_decode_row_col (&image_dmeta->tables [MONO_TABLE_METHOD], mapped_token - 1, MONO_METHOD_RVA);
if (rva < dil_length) {
char *il_address = ((char *) dil_data) + rva;
- MonoDebugInformationEnc *method_debug_information = hot_reload_get_method_debug_information (image_dppdb, token_index);
+ MonoDebugInformationEnc *method_debug_information = hot_reload_get_method_debug_information (delta_info->ppdb_file, token_index);
set_update_method (image_base, base_info, generation, image_dmeta, delta_info, token_index, il_address, method_debug_information);
} else {
/* rva points probably into image_base IL stream. can this ever happen? */
/* makes a copy of dil_bytes_orig */
gpointer dil_bytes = open_dil_data (image_base, dil_bytes_orig, dil_length);
- MonoImage *image_dpdb = NULL;
+ MonoPPDBFile *ppdb_file = NULL;
if (dpdb_length > 0)
{
- image_dpdb = image_open_dmeta_from_data (image_base, generation, dpdb_bytes_orig, dpdb_length);
+ MonoImage *image_dpdb = image_open_dmeta_from_data (image_base, generation, dpdb_bytes_orig, dpdb_length);
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_METADATA_UPDATE, "pdb image string size: 0x%08x", image_dpdb->heap_strings.size);
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_METADATA_UPDATE, "pdb image user string size: 0x%08x", image_dpdb->heap_us.size);
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_METADATA_UPDATE, "pdb image blob heap addr: %p", image_dpdb->heap_blob.data);
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_METADATA_UPDATE, "pdb image blob heap size: 0x%08x", image_dpdb->heap_blob.size);
+ ppdb_file = mono_create_ppdb_file (image_dpdb, FALSE);
}
BaselineInfo *base_info = baseline_info_lookup_or_add (image_base);
- DeltaInfo *delta_info = delta_info_init (image_dmeta, image_base, base_info, generation);
+ DeltaInfo *delta_info = delta_info_init (image_dmeta, image_base, ppdb_file, base_info, generation);
if (image_dmeta->minimal_delta) {
if (mono_trace_is_traced (G_LOG_LEVEL_DEBUG, MONO_TRACE_METADATA_UPDATE))
dump_update_summary (image_base, image_dmeta);
- if (!apply_enclog_pass2 (image_base, base_info, generation, image_dmeta, image_dpdb, delta_info, dil_bytes, dil_length, error)) {
+ if (!apply_enclog_pass2 (image_base, base_info, generation, image_dmeta, delta_info, dil_bytes, dil_length, error)) {
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_METADATA_UPDATE, "Error applying delta image to base=%s, due to: %s", basename, mono_error_get_message (error));
hot_reload_update_cancel (generation);
return;
#include "debug-mono-ppdb.h"
-struct _MonoPPDBFile {
- MonoImage *image;
- GHashTable *doc_hash;
- GHashTable *method_hash;
- gboolean is_embedded;
-};
-
typedef struct {
gint32 signature;
guint8 guid [16];
g_free (info);
}
-static MonoPPDBFile*
-create_ppdb_file (MonoImage *ppdb_image, gboolean is_embedded_ppdb)
+MonoPPDBFile*
+mono_create_ppdb_file (MonoImage *ppdb_image, gboolean is_embedded_ppdb)
{
MonoPPDBFile *ppdb;
if (table_info_get_rows (&image->tables [MONO_TABLE_DOCUMENT])) {
/* Embedded ppdb */
mono_image_addref (image);
- return create_ppdb_file (image, TRUE);
+ return mono_create_ppdb_file (image, TRUE);
}
if (!get_pe_debug_info (image, pe_guid, &pe_age, &pe_timestamp, &ppdb_data, &ppdb_size, &ppdb_compressed_size)) {
return NULL;
}
- return create_ppdb_file (ppdb_image, is_embedded_ppdb);
+ return mono_create_ppdb_file (ppdb_image, is_embedded_ppdb);
}
void
-mono_ppdb_close (MonoDebugHandle *handle)
+mono_ppdb_close (MonoPPDBFile *ppdb)
{
- MonoPPDBFile *ppdb = handle->ppdb;
-
mono_image_close (ppdb->image);
g_hash_table_destroy (ppdb->doc_hash);
g_hash_table_destroy (ppdb->method_hash);
int size, part_size, partidx, nparts;
char sep;
GString *s;
- MonoDebugSourceInfo *res, *cached;
+ MonoDebugSourceInfo *res, *cached = NULL;
mono_debugger_lock ();
- cached = (MonoDebugSourceInfo *)g_hash_table_lookup (ppdb->doc_hash, GUINT_TO_POINTER (docidx));
+ if (ppdb)
+ cached = (MonoDebugSourceInfo *)g_hash_table_lookup (ppdb->doc_hash, GUINT_TO_POINTER (docidx));
mono_debugger_unlock ();
if (cached)
return cached;
* already looked up the method and also already did the
* native address -> IL offset mapping.
*/
-MonoDebugSourceLocation *
-mono_ppdb_lookup_location (MonoDebugMethodInfo *minfo, uint32_t offset)
+static MonoDebugSourceLocation *
+mono_ppdb_lookup_location_internal (MonoImage *image, int idx, uint32_t offset, MonoPPDBFile *ppdb)
{
- MonoPPDBFile *ppdb = minfo->handle->ppdb;
- MonoImage *image = ppdb->image;
- MonoMethod *method = minfo->method;
MonoTableInfo *tables = image->tables;
guint32 cols [MONO_METHODBODY_SIZE];
const char *ptr;
const char *end;
- char *docname;
- int idx, size, docidx, iloffset, delta_il, delta_lines, delta_cols, start_line, start_col, adv_line, adv_col;
+ char *docname = NULL;
+ int size, docidx, iloffset, delta_il, delta_lines, delta_cols, start_line, start_col, adv_line, adv_col;
gboolean first = TRUE, first_non_hidden = TRUE;
MonoDebugSourceLocation *location;
- if (!method->token)
- return NULL;
-
- idx = mono_metadata_token_index (method->token);
-
mono_metadata_decode_row (&tables [MONO_TABLE_METHODBODY], idx-1, cols, MONO_METHODBODY_SIZE);
docidx = cols [MONO_METHODBODY_DOCUMENT];
if (docidx == 0)
docidx = mono_metadata_decode_value (ptr, &ptr);
docname = get_docname (ppdb, image, docidx);
-
iloffset = 0;
start_line = 0;
start_col = 0;
return location;
}
+
+MonoDebugSourceLocation *
+mono_ppdb_lookup_location (MonoDebugMethodInfo *minfo, uint32_t offset)
+{
+ MonoPPDBFile *ppdb = minfo->handle->ppdb;
+ MonoImage *image = ppdb->image;
+ MonoMethod *method = minfo->method;
+ if (!method->token)
+ return NULL;
+ return mono_ppdb_lookup_location_internal (image, mono_metadata_token_index (method->token), offset, ppdb);
+}
+
+MonoDebugSourceLocation *
+mono_ppdb_lookup_location_enc (MonoPPDBFile *ppdb_file, int idx, uint32_t offset)
+{
+ return mono_ppdb_lookup_location_internal (ppdb_file->image, idx, offset, ppdb_file);
+}
+
MonoImage *
mono_ppdb_get_image (MonoPPDBFile *ppdb)
{
return ppdb->is_embedded;
}
-static int
-mono_ppdb_get_seq_points_internal (const char* ptr, MonoSymSeqPoint **seq_points, int *n_seq_points, int docidx, MonoImage *image, MonoPPDBFile *ppdb, GPtrArray **sfiles, char **source_file, int **source_files, GPtrArray **sindexes, gboolean read_doc_value)
+static int
+mono_ppdb_get_seq_points_internal (MonoImage *image, MonoPPDBFile *ppdb, MonoMethod* method, int method_idx, char **source_file, GPtrArray **source_file_list, int **source_files, MonoSymSeqPoint **seq_points, int *n_seq_points)
{
+ MonoTableInfo *tables = image->tables;
+ guint32 cols [MONO_METHODBODY_SIZE];
+ const char *ptr;
+ const char *end;
+ MonoDebugSourceInfo *docinfo;
+ int i, size, docidx, iloffset, delta_il, delta_lines, delta_cols, start_line, start_col, adv_line, adv_col;
+ gboolean first = TRUE, first_non_hidden = TRUE;
GArray *sps;
MonoSymSeqPoint sp;
- int iloffset = 0;
- int start_line = 0;
- int start_col = 0;
- int delta_cols = 0;
- gboolean first_non_hidden = TRUE;
- int adv_line, adv_col;
- int size = mono_metadata_decode_blob_size (ptr, &ptr);
- const char* end = ptr + size;
- MonoDebugSourceInfo *docinfo;
- gboolean first = TRUE;
+ GPtrArray *sfiles = NULL;
+ GPtrArray *sindexes = NULL;
+ if (source_file)
+ *source_file = NULL;
+ if (source_file_list)
+ *source_file_list = NULL;
+ if (source_files)
+ *source_files = NULL;
+ if (seq_points)
+ *seq_points = NULL;
+ if (n_seq_points)
+ *n_seq_points = 0;
+
+ if (source_file_list)
+ *source_file_list = sfiles = g_ptr_array_new ();
+ if (source_files)
+ sindexes = g_ptr_array_new ();
+
+ if (!method->token || table_info_get_rows (&tables [MONO_TABLE_METHODBODY]) == 0)
+ return -1;
+
+ MonoTableInfo *methodbody_table = &tables [MONO_TABLE_METHODBODY];
+ if (G_UNLIKELY (method_idx - 1 >= table_info_get_rows (methodbody_table))) {
+ char *method_name = mono_method_full_name (method, FALSE);
+ g_error ("Method idx %d is greater than number of rows (%d) in PPDB MethodDebugInformation table, for method %s in '%s'. Likely a malformed PDB file.",
+ method_idx - 1, table_info_get_rows (methodbody_table), method_name, image->name);
+ g_free (method_name);
+ }
+
+ mono_metadata_decode_row (methodbody_table, method_idx - 1, cols, MONO_METHODBODY_SIZE);
+
+ docidx = cols [MONO_METHODBODY_DOCUMENT];
+
+ if (!cols [MONO_METHODBODY_SEQ_POINTS])
+ return -1;
+
+ ptr = mono_metadata_blob_heap (image, cols [MONO_METHODBODY_SEQ_POINTS]);
+ size = mono_metadata_decode_blob_size (ptr, &ptr);
+ end = ptr + size;
sps = g_array_new (FALSE, TRUE, sizeof (MonoSymSeqPoint));
/* Header */
/* LocalSignature */
mono_metadata_decode_value (ptr, &ptr);
- if (docidx == 0 && read_doc_value)
+ if (docidx == 0)
docidx = mono_metadata_decode_value (ptr, &ptr);
- if (sfiles && *sfiles)
- {
- docinfo = get_docinfo (ppdb, image, docidx);
- g_ptr_array_add (*sfiles, docinfo);
- }
+ docinfo = get_docinfo (ppdb, image, docidx);
+
+ if (sfiles)
+ g_ptr_array_add (sfiles, docinfo);
- if (source_file && *source_file)
+ if (source_file)
*source_file = g_strdup (docinfo->source_file);
iloffset = 0;
start_line = 0;
start_col = 0;
while (ptr < end) {
- int delta_il = mono_metadata_decode_value (ptr, &ptr);
- if (!first && delta_il == 0 && read_doc_value) {
+ delta_il = mono_metadata_decode_value (ptr, &ptr);
+ if (!first && delta_il == 0) {
/* subsequent-document-record */
docidx = mono_metadata_decode_value (ptr, &ptr);
docinfo = get_docinfo (ppdb, image, docidx);
- if (sfiles && *sfiles)
- {
- g_ptr_array_add (*sfiles, docinfo);
- }
+ if (sfiles)
+ g_ptr_array_add (sfiles, docinfo);
continue;
}
iloffset += delta_il;
first = FALSE;
- int delta_lines = mono_metadata_decode_value (ptr, &ptr);
+ delta_lines = mono_metadata_decode_value (ptr, &ptr);
if (delta_lines == 0)
delta_cols = mono_metadata_decode_value (ptr, &ptr);
else
sp.end_column = start_col + delta_cols;
g_array_append_val (sps, sp);
- if (sindexes && *sindexes) {
- g_ptr_array_add (*sindexes, GUINT_TO_POINTER ((*sfiles)->len - 1));
- }
+ if (source_files)
+ g_ptr_array_add (sindexes, GUINT_TO_POINTER (sfiles->len - 1));
}
if (n_seq_points) {
*n_seq_points = sps->len;
- if (seq_points) {
- *seq_points = g_new (MonoSymSeqPoint, sps->len);
- memcpy (*seq_points, sps->data, sps->len * sizeof (MonoSymSeqPoint));
- }
+ g_assert (seq_points);
+ *seq_points = g_new (MonoSymSeqPoint, sps->len);
+ memcpy (*seq_points, sps->data, sps->len * sizeof (MonoSymSeqPoint));
}
- int sps_len = sps->len;
+
+ if (source_files) {
+ *source_files = g_new (int, sps->len);
+ for (i = 0; i < sps->len; ++i)
+ (*source_files)[i] = GPOINTER_TO_INT (g_ptr_array_index (sindexes, i));
+ g_ptr_array_free (sindexes, TRUE);
+ }
+ int n_seqs = sps->len;
g_array_free (sps, TRUE);
- return sps_len;
+
+ return n_seqs;
}
gboolean
-mono_ppdb_get_seq_points_enc (MonoImage *image, int idx, MonoSymSeqPoint **seq_points, int *n_seq_points)
+mono_ppdb_get_seq_points_enc (MonoDebugMethodInfo *minfo, MonoPPDBFile *ppdb_file, int idx, char **source_file, GPtrArray **source_file_list, int **source_files, MonoSymSeqPoint **seq_points, int *n_seq_points)
{
- guint32 cols [MONO_METHODBODY_SIZE];
- MonoTableInfo *tables = image->tables;
- MonoTableInfo *methodbody_table = &tables [MONO_TABLE_METHODBODY];
- mono_metadata_decode_row (methodbody_table, idx, cols, MONO_METHODBODY_SIZE);
- if (!cols [MONO_METHODBODY_SEQ_POINTS])
- return FALSE;
-
- const char *ptr = mono_metadata_blob_heap (image, cols [MONO_METHODBODY_SEQ_POINTS]);
- mono_ppdb_get_seq_points_internal (ptr, seq_points, n_seq_points, 0, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
- return TRUE;
+ MonoMethod *method = minfo->method;
+ if (mono_ppdb_get_seq_points_internal (ppdb_file->image, ppdb_file, method, idx, source_file, source_file_list, source_files, seq_points, n_seq_points) > 0)
+ return TRUE;
+ return FALSE;
}
void
MonoPPDBFile *ppdb = minfo->handle->ppdb;
MonoImage *image = ppdb->image;
MonoMethod *method = minfo->method;
- MonoTableInfo *tables = image->tables;
- guint32 cols [MONO_METHODBODY_SIZE];
- const char *ptr;
- int i, method_idx, docidx;
- GPtrArray *sfiles = NULL;
- GPtrArray *sindexes = NULL;
-
- if (source_file)
- *source_file = NULL;
- if (source_file_list)
- *source_file_list = NULL;
- if (source_files)
- *source_files = NULL;
- if (seq_points)
- *seq_points = NULL;
- if (n_seq_points)
- *n_seq_points = 0;
- if (source_file_list)
- *source_file_list = sfiles = g_ptr_array_new ();
- if (source_files)
- sindexes = g_ptr_array_new ();
-
- if (!method->token || table_info_get_rows (&tables [MONO_TABLE_METHODBODY]) == 0)
- return;
-
- method_idx = mono_metadata_token_index (method->token);
-
- MonoTableInfo *methodbody_table = &tables [MONO_TABLE_METHODBODY];
- if (G_UNLIKELY (method_idx - 1 >= table_info_get_rows (methodbody_table))) {
- char *method_name = mono_method_full_name (method, FALSE);
- g_error ("Method idx %d is greater than number of rows (%d) in PPDB MethodDebugInformation table, for method %s in '%s'. Likely a malformed PDB file.",
- method_idx - 1, table_info_get_rows (methodbody_table), method_name, image->name);
- g_free (method_name);
- }
- mono_metadata_decode_row (methodbody_table, method_idx - 1, cols, MONO_METHODBODY_SIZE);
-
- docidx = cols [MONO_METHODBODY_DOCUMENT];
-
- if (!cols [MONO_METHODBODY_SEQ_POINTS])
- return;
-
- ptr = mono_metadata_blob_heap (image, cols [MONO_METHODBODY_SEQ_POINTS]);
+ int method_idx = mono_metadata_token_index (method->token);
- int sps_len = mono_ppdb_get_seq_points_internal (ptr, seq_points, n_seq_points, docidx, image, ppdb, &sfiles, source_file, source_files, &sindexes, TRUE);
-
- if (source_files) {
- *source_files = g_new (int, sps_len);
- for (i = 0; i < sps_len; ++i)
- (*source_files)[i] = GPOINTER_TO_INT (g_ptr_array_index (sindexes, i));
- g_ptr_array_free (sindexes, TRUE);
- }
-
+ mono_ppdb_get_seq_points_internal (image, ppdb, method, method_idx, source_file, source_file_list, source_files, seq_points, n_seq_points);
}
static MonoDebugLocalsInfo*
-mono_ppdb_lookup_locals_internal (MonoImage *image, int method_idx, gboolean is_enc)
+mono_ppdb_lookup_locals_internal (MonoImage *image, int method_idx)
{
MonoDebugLocalsInfo *res;
MonoTableInfo *tables = image->tables;
MonoDebugLocalsInfo*
mono_ppdb_lookup_locals_enc (MonoImage *image, int method_idx)
{
- return mono_ppdb_lookup_locals_internal (image, method_idx + 1, TRUE);
+ return mono_ppdb_lookup_locals_internal (image, method_idx);
}
MonoDebugLocalsInfo*
method_idx = mono_metadata_token_index (method->token);
- return mono_ppdb_lookup_locals_internal (image, method_idx, FALSE);
+ return mono_ppdb_lookup_locals_internal (image, method_idx);
}
/*
#include <mono/metadata/metadata-internals.h>
#include <mono/metadata/mono-debug.h>
+typedef struct _MonoDebugInformationEnc MonoDebugInformationEnc;
+
+
+struct _MonoPPDBFile {
+ MonoImage *image;
+ GHashTable *doc_hash;
+ GHashTable *method_hash;
+ gboolean is_embedded;
+};
+
+struct _MonoDebugInformationEnc {
+ MonoPPDBFile *ppdb_file;
+ int idx;
+};
+
MonoPPDBFile*
mono_ppdb_load_file (MonoImage *image, const guint8 *raw_contents, int size);
-void
-mono_ppdb_close (MonoDebugHandle *handle);
+MONO_COMPONENT_API void
+mono_ppdb_close (MonoPPDBFile *ppdb_file);
MonoDebugMethodInfo *
mono_ppdb_lookup_method (MonoDebugHandle *handle, MonoMethod *method);
MonoDebugSourceLocation *
mono_ppdb_lookup_location (MonoDebugMethodInfo *minfo, uint32_t offset);
+MonoDebugSourceLocation *
+mono_ppdb_lookup_location_enc (MonoPPDBFile *ppdb_file, int idx, uint32_t offset);
+
void
mono_ppdb_get_seq_points (MonoDebugMethodInfo *minfo, char **source_file, GPtrArray **source_file_list, int **source_files, MonoSymSeqPoint **seq_points, int *n_seq_points);
gboolean
-mono_ppdb_get_seq_points_enc (MonoImage *image, int idx, MonoSymSeqPoint **seq_points, int *n_seq_points);
+mono_ppdb_get_seq_points_enc (MonoDebugMethodInfo *minfo, MonoPPDBFile *ppdb_file, int idx, char **source_file, GPtrArray **source_file_list, int **source_files, MonoSymSeqPoint **seq_points, int *n_seq_points);
MonoDebugLocalsInfo*
mono_ppdb_lookup_locals (MonoDebugMethodInfo *minfo);
gboolean
mono_ppdb_is_embedded (MonoPPDBFile *ppdb);
+MONO_COMPONENT_API MonoPPDBFile*
+mono_create_ppdb_file (MonoImage *ppdb_image, gboolean is_embedded_ppdb);
+
#endif
free_debug_handle (MonoDebugHandle *handle)
{
if (handle->ppdb)
- mono_ppdb_close (handle);
+ mono_ppdb_close (handle->ppdb);
if (handle->symfile)
mono_debug_close_mono_symbol_file (handle->symfile);
/* decrease the refcount added with mono_image_addref () */
MonoDebugSourceLocation *
mono_debug_method_lookup_location (MonoDebugMethodInfo *minfo, int il_offset)
{
+ MonoImage* img = m_class_get_image (minfo->method->klass);
+ if (img->has_updates) {
+ int idx = mono_metadata_token_index (minfo->method->token);
+ MonoDebugInformationEnc *mdie = (MonoDebugInformationEnc *) mono_metadata_update_get_updated_method_ppdb (img, idx);
+ if (mdie != NULL) {
+ MonoDebugSourceLocation * ret = mono_ppdb_lookup_location_enc (mdie->ppdb_file, mdie->idx, il_offset);
+ if (ret)
+ return ret;
+ }
+ }
+
MonoDebugSourceLocation *location;
mono_debugger_lock ();
int idx = mono_metadata_token_index (method->token);
MonoDebugInformationEnc *mdie = (MonoDebugInformationEnc *) mono_metadata_update_get_updated_method_ppdb (img, idx);
if (mdie != NULL) {
- res = mono_ppdb_lookup_locals_enc (mdie->image, mdie->idx);
+ res = mono_ppdb_lookup_locals_enc (mdie->ppdb_file->image, mdie->idx);
if (res != NULL)
return res;
}
mono_debug_get_seq_points (MonoDebugMethodInfo *minfo, char **source_file, GPtrArray **source_file_list, int **source_files, MonoSymSeqPoint **seq_points, int *n_seq_points)
{
MonoImage* img = m_class_get_image (minfo->method->klass);
- if (img->has_updates && !source_file_list) {
+ if (img->has_updates) {
int idx = mono_metadata_token_index (minfo->method->token);
MonoDebugInformationEnc *mdie = (MonoDebugInformationEnc *) mono_metadata_update_get_updated_method_ppdb (img, idx);
if (mdie != NULL) {
- if (mono_ppdb_get_seq_points_enc (mdie->image, mdie->idx, seq_points, n_seq_points))
+ if (mono_ppdb_get_seq_points_enc (minfo, mdie->ppdb_file, mdie->idx, source_file, source_file_list, source_files, seq_points, n_seq_points))
return;
}
}
typedef struct _MonoDebugLocalsInfo MonoDebugLocalsInfo;
typedef struct _MonoDebugMethodAsyncInfo MonoDebugMethodAsyncInfo;
typedef struct _MonoDebugSourceLocation MonoDebugSourceLocation;
-typedef struct _MonoDebugInformationEnc MonoDebugInformationEnc;
typedef struct _MonoDebugList MonoDebugList;
uint32_t il_offset;
};
-
-struct _MonoDebugInformationEnc {
- MonoImage *image;
- int idx;
-};
-
MONO_API mono_bool mono_debug_enabled (void);
/*
pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 30, 12, "StaticMethod3");
locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
CheckBool(locals, "c", true);
+
+ await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 31, 12, "StaticMethod3",
+ locals_fn: (locals) =>
+ {
+ CheckNumber(locals, "d", 10);
+ }
+ );
+ await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 32, 12, "StaticMethod3",
+ locals_fn: (locals) =>
+ {
+ CheckNumber(locals, "d", 10);
+ CheckNumber(locals, "e", 20);
+ }
+ );
+ await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 33, 8, "StaticMethod3",
+ locals_fn: (locals) =>
+ {
+ CheckNumber(locals, "d", 10);
+ CheckNumber(locals, "e", 20);
+ CheckNumber(locals, "f", 50);
+ }
+ );
}
+
+ [Fact]
+ public async Task DebugHotReloadMethodEmpty()
+ {
+ int line = 38;
+ await SetBreakpoint(".*/MethodBody1.cs$", line, 0, use_regex: true);
+ var pause_location = await LoadAssemblyAndTestHotReload(
+ Path.Combine(DebuggerTestAppPath, "ApplyUpdateReferencedAssembly.dll"),
+ Path.Combine(DebuggerTestAppPath, "ApplyUpdateReferencedAssembly.pdb"),
+ Path.Combine(DebuggerTestAppPath, "../wasm/ApplyUpdateReferencedAssembly.dll"),
+ "MethodBody4", "StaticMethod4");
+
+ var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
+ pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 38, 12, "StaticMethod4");
+ locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
+ await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 39, 12, "StaticMethod4",
+ locals_fn: (locals) =>
+ {
+ CheckNumber(locals, "a", 10);
+ }
+ );
+ await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 40, 12, "StaticMethod4",
+ locals_fn: (locals) =>
+ {
+ CheckNumber(locals, "a", 10);
+ CheckNumber(locals, "b", 20);
+ }
+ );
+ await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 41, 12, "StaticMethod4",
+ locals_fn: (locals) =>
+ {
+ CheckNumber(locals, "a", 10);
+ CheckNumber(locals, "b", 20);
+ }
+ );
+ await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 42, 12, "StaticMethod4",
+ locals_fn: (locals) =>
+ {
+ CheckNumber(locals, "a", 10);
+ CheckNumber(locals, "b", 20);
+ }
+ );
+ await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 43, 8, "StaticMethod4",
+ locals_fn: (locals) =>
+ {
+ CheckNumber(locals, "a", 10);
+ CheckNumber(locals, "b", 20);
+ }
+ );
+ pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 38, 8, "StaticMethod4");
+ locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
+ }
}
}
</PropertyGroup>
<ItemGroup>
+ <Compile Include="MethodBody0.cs" />
<Compile Include="MethodBody1.cs" />
</ItemGroup>
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Diagnostics;
+using System;
+
+namespace ApplyUpdateReferencedAssembly
+{
+ public class MethodBodyUnchangedAssembly {
+ public static string StaticMethod1 () {
+ Console.WriteLine("original");
+ return "ok";
+ }
+ }
+}
return "OLD STRING";
}
}
+
+
+
+ public class MethodBody4 {
+ public static void StaticMethod4 () {
+ }
+ }
}
return "NEW STRING";
}
}
+
+
+
+ public class MethodBody4 {
+ public static void StaticMethod4 () {
+ int a = 10;
+ int b = 20;
+ Console.WriteLine(a + b);
+ Console.WriteLine(a + b);
+ Console.WriteLine(a + b);
+ }
+ }
}
public class MethodBody3 {
public static string StaticMethod3 () {
bool c = true;
- Console.WriteLine("v2");
+ int d = 10;
+ int e = 20;
+ int f = 50;
return "NEWEST STRING";
}
}
+
+ public class MethodBody4 {
+ public static void StaticMethod4 () {
+ }
+ }
}