[runtime] Coverage profiler fixes (#5698)
[mono.git] / mono / metadata / profiler.c
index b10423120d43a649f8fd9a0c160a0fb3f307523f..9f65059f806699088b673fcf01a1896ae59a7576 100644 (file)
@@ -9,6 +9,7 @@
 #include <mono/metadata/mono-config-dirs.h>
 #include <mono/metadata/mono-debug.h>
 #include <mono/metadata/profiler-private.h>
+#include <mono/metadata/debug-internals.h>
 #include <mono/utils/mono-dl.h>
 #include <mono/utils/mono-error-internals.h>
 #include <mono/utils/mono-logger-internals.h>
@@ -208,9 +209,6 @@ mono_profiler_get_coverage_data (MonoProfilerHandle handle, MonoMethod *method,
 
        coverage_unlock ();
 
-       if (!info)
-               return FALSE;
-
        MonoError error;
        MonoMethodHeader *header = mono_method_get_header_checked (method, &error);
        mono_error_assert_ok (&error);
@@ -221,6 +219,45 @@ mono_profiler_get_coverage_data (MonoProfilerHandle handle, MonoMethod *method,
        const unsigned char *end = start + size;
        MonoDebugMethodInfo *minfo = mono_debug_lookup_method (method);
 
+       if (!info) {
+               char *source_file;
+               int i, n_il_offsets;
+               int *source_files;
+               GPtrArray *source_file_list;
+               MonoSymSeqPoint *sym_seq_points;
+
+               /* Return 0 counts for all locations */
+
+               mono_debug_get_seq_points (minfo, &source_file, &source_file_list, &source_files, &sym_seq_points, &n_il_offsets);
+               for (i = 0; i < n_il_offsets; ++i) {
+                       MonoSymSeqPoint *sp = &sym_seq_points [i];
+                       const char *srcfile = "";
+
+                       if (source_files [i] != -1) {
+                               MonoDebugSourceInfo *sinfo = (MonoDebugSourceInfo *)g_ptr_array_index (source_file_list, source_files [i]);
+                               srcfile = sinfo->source_file;
+                       }
+
+                       MonoProfilerCoverageData data = {
+                               .method = method,
+                               .il_offset = sp->il_offset,
+                               .counter = 0,
+                               .file_name = srcfile,
+                               .line = sp->line,
+                               .column = 0,
+                       };
+
+                       cb (handle->prof, &data);
+               }
+
+               g_free (source_files);
+               g_free (sym_seq_points);
+               g_ptr_array_free (source_file_list, TRUE);
+
+               mono_metadata_free_mh (header);
+               return TRUE;
+       }
+
        for (guint32 i = 0; i < info->entries; i++) {
                guchar *cil_code = info->data [i].cil_code;
 
@@ -264,6 +301,9 @@ mono_profiler_coverage_alloc (MonoMethod *method, guint32 entries)
        if (!mono_profiler_state.code_coverage)
                return FALSE;
 
+       if (method->wrapper_type)
+               return FALSE;
+
        gboolean cover = FALSE;
 
        for (MonoProfilerHandle handle = mono_profiler_state.profilers; handle; handle = handle->next) {