X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fdebug-mono-ppdb.c;h=8357099a551aa9bec2f6c5dcb147724731e1ee5f;hb=f1bc138d686e19b1c91b43d31a65b569d4af8bb5;hp=014586cb1e4abed891f18431d590455073c86b68;hpb=44f4429237816e808e42136783c6fb885e13a5dd;p=mono.git diff --git a/mono/metadata/debug-mono-ppdb.c b/mono/metadata/debug-mono-ppdb.c index 014586cb1e4..8357099a551 100644 --- a/mono/metadata/debug-mono-ppdb.c +++ b/mono/metadata/debug-mono-ppdb.c @@ -7,6 +7,7 @@ * Mono Project (http://www.mono-project.com) * * Copyright 2015 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include @@ -88,7 +89,7 @@ get_pe_debug_guid (MonoImage *image, guint8 *out_guid, gint32 *out_age, gint32 * static void doc_free (gpointer key) { - MonoDebugSourceInfo *info = key; + MonoDebugSourceInfo *info = (MonoDebugSourceInfo *)key; g_free (info->source_file); g_free (info); @@ -97,7 +98,7 @@ doc_free (gpointer key) MonoPPDBFile* mono_ppdb_load_file (MonoImage *image, const guint8 *raw_contents, int size) { - MonoImage *ppdb_image; + MonoImage *ppdb_image = NULL; const char *filename; char *s, *ppdb_filename; MonoImageOpenStatus status; @@ -106,8 +107,12 @@ mono_ppdb_load_file (MonoImage *image, const guint8 *raw_contents, int size) gint32 pe_timestamp; MonoPPDBFile *ppdb; + if (!get_pe_debug_guid (image, pe_guid, &pe_age, &pe_timestamp)) + return NULL; + if (raw_contents) { - ppdb_image = mono_image_open_from_data_internal ((char*)raw_contents, size, TRUE, &status, FALSE, TRUE, NULL); + if (size > 4 && strncmp ((char*)raw_contents, "BSJB", 4) == 0) + ppdb_image = mono_image_open_from_data_internal ((char*)raw_contents, size, TRUE, &status, FALSE, TRUE, NULL); } else { /* ppdb files drop the .exe/.dll extension */ filename = mono_image_get_filename (image); @@ -132,18 +137,16 @@ mono_ppdb_load_file (MonoImage *image, const guint8 *raw_contents, int size) * The same id is stored in the Debug Directory of the PE file, and in the * #Pdb stream in the ppdb file. */ - if (get_pe_debug_guid (image, pe_guid, &pe_age, &pe_timestamp)) { - PdbStreamHeader *pdb_stream = (PdbStreamHeader*)ppdb_image->heap_pdb.data; + PdbStreamHeader *pdb_stream = (PdbStreamHeader*)ppdb_image->heap_pdb.data; - g_assert (pdb_stream); + g_assert (pdb_stream); - /* The pdb id is a concentation of the pe guid and the timestamp */ - if (memcmp (pe_guid, pdb_stream->guid, 16) != 0 || memcmp (&pe_timestamp, pdb_stream->guid + 16, 4) != 0) { - g_warning ("Symbol file %s doesn't match image %s", ppdb_image->name, - image->name); - mono_image_close (ppdb_image); - return NULL; - } + /* The pdb id is a concentation of the pe guid and the timestamp */ + if (memcmp (pe_guid, pdb_stream->guid, 16) != 0 || memcmp (&pe_timestamp, pdb_stream->guid + 16, 4) != 0) { + g_warning ("Symbol file %s doesn't match image %s", ppdb_image->name, + image->name); + mono_image_close (ppdb_image); + return NULL; } ppdb = g_new0 (MonoPPDBFile, 1); @@ -176,7 +179,7 @@ mono_ppdb_lookup_method (MonoDebugHandle *handle, MonoMethod *method) mono_debugger_lock (); - minfo = g_hash_table_lookup (ppdb->method_hash, method); + minfo = (MonoDebugMethodInfo *)g_hash_table_lookup (ppdb->method_hash, method); if (minfo) { mono_debugger_unlock (); return minfo; @@ -208,7 +211,7 @@ get_docinfo (MonoPPDBFile *ppdb, MonoImage *image, int docidx) MonoDebugSourceInfo *res, *cached; mono_debugger_lock (); - cached = g_hash_table_lookup (ppdb->doc_hash, GUINT_TO_POINTER (docidx)); + cached = (MonoDebugSourceInfo *)g_hash_table_lookup (ppdb->doc_hash, GUINT_TO_POINTER (docidx)); mono_debugger_unlock (); if (cached) return cached; @@ -246,7 +249,7 @@ get_docinfo (MonoPPDBFile *ppdb, MonoImage *image, int docidx) res->hash = (guint8*)mono_metadata_blob_heap (image, cols [MONO_DOCUMENT_HASH]); mono_debugger_lock (); - cached = g_hash_table_lookup (ppdb->doc_hash, GUINT_TO_POINTER (docidx)); + cached = (MonoDebugSourceInfo *)g_hash_table_lookup (ppdb->doc_hash, GUINT_TO_POINTER (docidx)); if (!cached) { g_hash_table_insert (ppdb->doc_hash, GUINT_TO_POINTER (docidx), res); } else { @@ -291,7 +294,8 @@ mono_ppdb_lookup_location (MonoDebugMethodInfo *minfo, uint32_t offset) gboolean first = TRUE, first_non_hidden = TRUE; MonoDebugSourceLocation *location; - g_assert (method->token); + if (!method->token) + return NULL; idx = mono_metadata_token_index (method->token); @@ -518,16 +522,39 @@ mono_ppdb_lookup_locals (MonoDebugMethodInfo *minfo) scope_idx = start_scope_idx; mono_metadata_decode_row (&tables [MONO_TABLE_LOCALSCOPE], scope_idx-1, cols, MONO_LOCALSCOPE_SIZE); locals_idx = cols [MONO_LOCALSCOPE_VARIABLELIST]; - while (scope_idx == tables [MONO_TABLE_LOCALSCOPE].rows) { + + // https://github.com/dotnet/roslyn/blob/2ae8d5fed96ab3f1164031f9b4ac827f53289159/docs/specs/PortablePdb-Metadata.md#LocalScopeTable + // + // The variableList attribute in the pdb metadata table is a contiguous array that starts at a + // given offset (locals_idx) above and + // + // """ + // continues to the smaller of: + // + // the last row of the LocalVariable table + // the next run of LocalVariables, found by inspecting the VariableList of the next row in this LocalScope table. + // """ + // this endpoint becomes locals_end_idx below + + // March to the last scope that is in this method + while (scope_idx <= tables [MONO_TABLE_LOCALSCOPE].rows) { mono_metadata_decode_row (&tables [MONO_TABLE_LOCALSCOPE], scope_idx-1, cols, MONO_LOCALSCOPE_SIZE); if (cols [MONO_LOCALSCOPE_METHOD] != method_idx) break; scope_idx ++; } + // The number of scopes is the difference in the indices + // for the first and last scopes nscopes = scope_idx - start_scope_idx; - if (scope_idx == tables [MONO_TABLE_LOCALSCOPE].rows) { - locals_end_idx = tables [MONO_TABLE_LOCALVARIABLE].rows; + + // Ends with "the last row of the LocalVariable table" + // this happens if the above loop marched one past the end + // of the rows + if (scope_idx > tables [MONO_TABLE_LOCALSCOPE].rows) { + locals_end_idx = tables [MONO_TABLE_LOCALVARIABLE].rows + 1; } else { + // Ends with "the next run of LocalVariables, + // found by inspecting the VariableList of the next row in this LocalScope table." locals_end_idx = cols [MONO_LOCALSCOPE_VARIABLELIST]; } @@ -544,7 +571,7 @@ mono_ppdb_lookup_locals (MonoDebugMethodInfo *minfo) locals_idx = cols [MONO_LOCALSCOPE_VARIABLELIST]; if (scope_idx == tables [MONO_TABLE_LOCALSCOPE].rows) { - locals_end_idx = tables [MONO_TABLE_LOCALVARIABLE].rows; + locals_end_idx = tables [MONO_TABLE_LOCALVARIABLE].rows + 1; } else { locals_end_idx = mono_metadata_decode_row_col (&tables [MONO_TABLE_LOCALSCOPE], scope_idx-1 + 1, MONO_LOCALSCOPE_VARIABLELIST); }