[sdb] Add end lines/end columns to line number information.
authorZoltan Varga <vargaz@gmail.com>
Wed, 7 May 2014 12:01:57 +0000 (14:01 +0200)
committerZoltan Varga <vargaz@gmail.com>
Wed, 7 May 2014 12:02:28 +0000 (14:02 +0200)
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Location.cs
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodMirror.cs
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StackFrame.cs
mono/metadata/debug-mono-symfile.c
mono/metadata/debug-mono-symfile.h
mono/mini/debugger-agent.c
mono/mini/dwarfwriter.c

index b32e6129831255a2e0a83d5f388759ca6e3dabdf..0062ee9a101a3ca4775141b5787a33ed9b8659c0 100644 (file)
@@ -44,6 +44,8 @@ namespace Mono.Debugger.Soft
                public int[] il_offsets;
                public int[] line_numbers;
                public int[] column_numbers;
+               public int[] end_line_numbers;
+               public int[] end_column_numbers;
                public SourceInfo[] source_files;
        }
 
@@ -411,7 +413,7 @@ namespace Mono.Debugger.Soft
                 * with newer runtimes, and vice versa.
                 */
                internal const int MAJOR_VERSION = 2;
-               internal const int MINOR_VERSION = 31;
+               internal const int MINOR_VERSION = 32;
 
                enum WPSuspendPolicy {
                        NONE = 0,
@@ -1755,6 +1757,8 @@ namespace Mono.Debugger.Soft
                        info.line_numbers = new int [n_il_offsets];
                        info.source_files = new SourceInfo [n_il_offsets];
                        info.column_numbers = new int [n_il_offsets];
+                       info.end_line_numbers = new int [n_il_offsets];
+                       info.end_column_numbers = new int [n_il_offsets];
                        for (int i = 0; i < n_il_offsets; ++i) {
                                info.il_offsets [i] = res.ReadInt ();
                                info.line_numbers [i] = res.ReadInt ();
@@ -1768,6 +1772,13 @@ namespace Mono.Debugger.Soft
                                        info.column_numbers [i] = res.ReadInt ();
                                else
                                        info.column_numbers [i] = 0;
+                               if (Version.AtLeast (2, 32)) {
+                                       info.end_line_numbers [i] = res.ReadInt ();
+                                       info.end_column_numbers [i] = res.ReadInt ();
+                               } else {
+                                       info.end_column_numbers [i] = -1;
+                                       info.end_column_numbers [i] = -1;
+                               }
                        }
 
                        return info;
index 0624095b2851e81ab10a456fa64e2914278909e9..6833e9a906efb22b88b9cfac75e6ecb845c4483a 100644 (file)
@@ -11,8 +11,10 @@ namespace Mono.Debugger.Soft
                int line_number;
                byte[] hash;
                int column_number;
+               int end_line_number;
+               int end_column_number;
                
-               internal Location (VirtualMachine vm, MethodMirror method, long native_addr, int il_offset, string source_file, int line_number, int column_number, byte[] hash) : base (vm, 0) {
+               internal Location (VirtualMachine vm, MethodMirror method, long native_addr, int il_offset, string source_file, int line_number, int column_number, int end_line_number, int end_column_number, byte[] hash) : base (vm, 0) {
                        this.method = method;
                        //this.native_addr = native_addr;
                        this.il_offset = il_offset;
@@ -20,6 +22,8 @@ namespace Mono.Debugger.Soft
                        this.line_number = line_number;
                        this.hash = hash;
                        this.column_number = column_number;
+                       this.end_line_number = end_line_number;
+                       this.end_column_number = end_column_number;
                }
 
                public MethodMirror Method {
@@ -53,6 +57,20 @@ namespace Mono.Debugger.Soft
                        }
            }
 
+               // Since protocol version 2.32, -1 in earlier protocol versions, or if not available
+               public int EndLineNumber {
+                       get {
+                               return end_line_number;
+                       }
+           }
+
+               // Since protocol version 2.32, -1 in earlier protocol versions, or if not available
+               public int EndColumnNumber {
+                       get {
+                               return end_column_number;
+                       }
+           }
+
                // MD5 hash of source file
                // Since protocol version 2.14, null in earlier protocol versions
                public byte[] SourceFileHash {
@@ -62,7 +80,10 @@ namespace Mono.Debugger.Soft
                }
 
                public override string ToString () {
-                       return String.Format ("{0}+0x{1:x} at {2}:{3}", Method.FullName, ILOffset, SourceFile, LineNumber);
+                       if (EndLineNumber != -1 && EndColumnNumber != -1)
+                               return String.Format ("{0}+0x{1:x} at {2}:[{3}:{4}-{5}:{6}]", Method.FullName, ILOffset, SourceFile, LineNumber, ColumnNumber, EndLineNumber, EndColumnNumber);
+                       else
+                               return String.Format ("{0}+0x{1:x} at {2}:{3}", Method.FullName, ILOffset, SourceFile, LineNumber);
                }
     }
 }
index 1568fdffcbf45701dca9d35817b5eeb9a31f97bd..e8f9fc1c5cd04edca26e240d5d61f00166b47d7c 100644 (file)
@@ -362,14 +362,14 @@ namespace Mono.Debugger.Soft
                                        var line_numbers = LineNumbers;
                                        IList<Location> res = new Location [ILOffsets.Count];
                                        for (int i = 0; i < il_offsets.Count; ++i)
-                                               res [i] = new Location (vm, this, -1, il_offsets [i], debug_info.source_files [i].source_file, line_numbers [i], debug_info.column_numbers [i], debug_info.source_files [i].hash);
+                                               res [i] = new Location (vm, this, -1, il_offsets [i], debug_info.source_files [i].source_file, line_numbers [i], debug_info.column_numbers [i], debug_info.end_line_numbers [i], debug_info.end_column_numbers [i], debug_info.source_files [i].hash);
                                        locations = res;
                                }
                                return locations;
                        }
                }                               
 
-               internal int il_offset_to_line_number (int il_offset, out string src_file, out byte[] src_hash, out int column_number) {
+               internal int il_offset_to_line_number (int il_offset, out string src_file, out byte[] src_hash, out int column_number, out int end_line_number, out int end_column_number) {
                        if (debug_info == null)
                                debug_info = vm.conn.Method_GetDebugInfo (id);
 
@@ -377,11 +377,15 @@ namespace Mono.Debugger.Soft
                        src_file = null;
                        src_hash = null;
                        column_number = 0;
+                       end_line_number = -1;
+                       end_column_number = -1;
                        for (int i = debug_info.il_offsets.Length - 1; i >= 0; --i) {
                                if (debug_info.il_offsets [i] <= il_offset) {
                                        src_file = debug_info.source_files [i].source_file;
                                        src_hash = debug_info.source_files [i].hash;
                                        column_number = debug_info.column_numbers [i];
+                                       end_line_number = debug_info.end_line_numbers [i];
+                                       end_column_number = debug_info.end_column_numbers [i];
                                        return debug_info.line_numbers [i];
                                }
                        }
index c0b4c7b2e204278d7af42dfad4b57d12fe11be2d..7a6a34fa539c93bf6d58758def7f70f34bf88c50 100644 (file)
@@ -45,13 +45,15 @@ namespace Mono.Debugger.Soft
                                        string src_file = null;
                                        byte[] hash = null;
                                        int column_number = 0;
+                                       int end_line_number = -1;
+                                       int end_column_number = -1;
 
                                        if (il_offset == -1)
                                                line_number = -1;
                                        else
-                                               line_number = method.il_offset_to_line_number (il_offset, out src_file, out hash, out column_number);
+                                               line_number = method.il_offset_to_line_number (il_offset, out src_file, out hash, out column_number, out end_line_number, out end_column_number);
 
-                                       location = new Location (vm, Method, 0, il_offset, src_file != null ? src_file : method.SourceFile, line_number, column_number, hash);
+                                       location = new Location (vm, Method, 0, il_offset, src_file != null ? src_file : method.SourceFile, line_number, column_number, end_line_number, end_column_number, hash);
                                }
                                return location;
                        }
index 9832418bec12990296a243288a4958fdba0f801b..0962499eebe9b04af7cc8636f99d35fdef46416e 100644 (file)
@@ -465,8 +465,13 @@ get_source_info (MonoSymbolFile *symfile, int index)
        return info;
 }
 
-static gboolean
-method_has_column_info (MonoDebugMethodInfo *minfo)
+typedef enum {
+       LNT_FLAG_HAS_COLUMN_INFO = 1 << 1,
+       LNT_FLAG_HAS_END_INFO = 1 << 2,
+} LineNumberTableFlags;
+
+static LineNumberTableFlags
+method_get_lnt_flags (MonoDebugMethodInfo *minfo)
 {
        MonoSymbolFile *symfile;
        const unsigned char *ptr;
@@ -492,7 +497,7 @@ method_has_column_info (MonoDebugMethodInfo *minfo)
        read_leb128 (ptr, &ptr);
 
        flags = read_leb128 (ptr, &ptr);
-       return (flags & 2) > 0;
+       return flags;
 }
 
 /*
@@ -503,15 +508,17 @@ method_has_column_info (MonoDebugMethodInfo *minfo)
  * The MonoDebugSourceFile structures are owned by this module.
  */
 void
-mono_debug_symfile_get_line_numbers_full (MonoDebugMethodInfo *minfo, char **source_file, GPtrArray **source_file_list, int *n_il_offsets, int **il_offsets, int **line_numbers, int **column_numbers, int **source_files)
+mono_debug_symfile_get_line_numbers_full (MonoDebugMethodInfo *minfo, char **source_file, GPtrArray **source_file_list, int *n_il_offsets, int **il_offsets, int **line_numbers, int **column_numbers, int **source_files, int **end_line_numbers, int **end_column_numbers)
 {
        // FIXME: Unify this with mono_debug_symfile_lookup_location
        MonoSymbolFile *symfile;
        const unsigned char *ptr;
        StatementMachine stm;
        uint32_t i;
+       LineNumberTableFlags flags;
        GPtrArray *il_offset_array, *line_number_array, *source_file_array;
-       gboolean has_column_info;
+       gboolean has_column_info, has_end_info;
+       gboolean column_info_read = FALSE;
 
        if (source_file_list)
                *source_file_list = NULL;
@@ -527,7 +534,9 @@ mono_debug_symfile_get_line_numbers_full (MonoDebugMethodInfo *minfo, char **sou
        if ((symfile = minfo->handle->symfile) == NULL)
                return;
 
-       has_column_info = method_has_column_info (minfo);
+       flags = method_get_lnt_flags (minfo);
+       has_column_info = (flags & LNT_FLAG_HAS_COLUMN_INFO) > 0;
+       has_end_info = (flags & LNT_FLAG_HAS_END_INFO) > 0;
 
        il_offset_array = g_ptr_array_new ();
        line_number_array = g_ptr_array_new ();
@@ -564,7 +573,6 @@ mono_debug_symfile_get_line_numbers_full (MonoDebugMethodInfo *minfo, char **sou
                                if (il_offset_array->len == 0)
                                        /* Empty table */
                                        break;
-                               add_line (&stm, il_offset_array, line_number_array, source_file_array);
                                break;
                        } else if (opcode == DW_LNE_MONO_negate_is_hidden) {
                                stm.is_hidden = !stm.is_hidden;
@@ -658,11 +666,33 @@ mono_debug_symfile_get_line_numbers_full (MonoDebugMethodInfo *minfo, char **sou
        }
 
        if (column_numbers && has_column_info) {
+               column_info_read = TRUE;
                *column_numbers = g_malloc (il_offset_array->len * sizeof (int));
                for (i = 0; i < il_offset_array->len; ++i)
                        (*column_numbers) [i] = read_leb128 (ptr, &ptr);
        }
 
+       if (has_end_info && end_line_numbers) {
+               g_assert (end_column_numbers);
+               *end_line_numbers = g_malloc (il_offset_array->len * sizeof (int));
+               *end_column_numbers = g_malloc (il_offset_array->len * sizeof (int));
+               if (has_column_info && !column_info_read) {
+                       for (i = 0; i < il_offset_array->len; ++i)
+                               read_leb128 (ptr, &ptr);
+               }
+               for (i = 0; i < il_offset_array->len; ++i) {
+                       int end_row, end_column = -1;
+
+                       end_row = read_leb128 (ptr, &ptr);
+                       if (end_row != 0xffffff) {
+                               end_row += GPOINTER_TO_UINT (g_ptr_array_index (line_number_array, i));
+                               end_column = read_leb128 (ptr, &ptr);
+                               (*end_line_numbers) [i] = end_row;
+                               (*end_column_numbers) [i] = end_column;
+                       }
+               }
+       }
+
        g_ptr_array_free (il_offset_array, TRUE);
        g_ptr_array_free (line_number_array, TRUE);
 
@@ -678,7 +708,7 @@ mono_debug_symfile_get_line_numbers_full (MonoDebugMethodInfo *minfo, char **sou
 void
 mono_debug_symfile_get_line_numbers (MonoDebugMethodInfo *minfo, char **source_file, int *n_il_offsets, int **il_offsets, int **line_numbers)
 {
-       mono_debug_symfile_get_line_numbers_full (minfo, source_file, NULL, n_il_offsets, il_offsets, line_numbers, NULL, NULL);
+       mono_debug_symfile_get_line_numbers_full (minfo, source_file, NULL, n_il_offsets, il_offsets, line_numbers, NULL, NULL, NULL, NULL);
 }
        
 int32_t
index 6ea3bccfc6edff1c6a01caaec81ee281751550f0..9decc58bad9598c54f242b1eea209a502fcf4a74 100644 (file)
@@ -159,7 +159,7 @@ MONO_API void
 mono_debug_symfile_get_line_numbers (MonoDebugMethodInfo *minfo, char **source_file, int *n_il_offsets, int **il_offsets, int **line_numbers);
 
 MONO_API void
-mono_debug_symfile_get_line_numbers_full (MonoDebugMethodInfo *minfo, char **source_file, GPtrArray **source_file_list, int *n_il_offsets, int **il_offsets, int **line_numbers, int **column_numbers, int **source_files);
+mono_debug_symfile_get_line_numbers_full (MonoDebugMethodInfo *minfo, char **source_file, GPtrArray **source_file_list, int *n_il_offsets, int **il_offsets, int **line_numbers, int **column_numbers, int **source_files, int **end_line_numbers, int **end_column_numbers);
 
 MONO_END_DECLS
 
index 5b451ff20140d38e046412b7c1288367b82671d3..1d829c69a60a701aa684a0dae024adc799c55c72 100644 (file)
@@ -285,7 +285,7 @@ typedef struct {
 #define HEADER_LENGTH 11
 
 #define MAJOR_VERSION 2
-#define MINOR_VERSION 31
+#define MINOR_VERSION 32
 
 typedef enum {
        CMD_SET_VM = 1,
@@ -3416,7 +3416,7 @@ create_event_list (EventKind event, GPtrArray *reqs, MonoJitInfo *ji, EventInfo
                                                MonoDebugMethodInfo *minfo = mono_debug_lookup_method (method);
 
                                                if (minfo) {
-                                                       mono_debug_symfile_get_line_numbers_full (minfo, &source_file, &source_file_list, NULL, NULL, NULL, NULL, NULL);
+                                                       mono_debug_symfile_get_line_numbers_full (minfo, &source_file, &source_file_list, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
                                                        for (i = 0; i < source_file_list->len; ++i) {
                                                                sinfo = g_ptr_array_index (source_file_list, i);
                                                                /*
@@ -6567,7 +6567,7 @@ get_source_files_for_type (MonoClass *klass)
                GPtrArray *source_file_list;
 
                if (minfo) {
-                       mono_debug_symfile_get_line_numbers_full (minfo, NULL, &source_file_list, NULL, NULL, NULL, NULL, NULL);
+                       mono_debug_symfile_get_line_numbers_full (minfo, NULL, &source_file_list, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
                        for (j = 0; j < source_file_list->len; ++j) {
                                sinfo = g_ptr_array_index (source_file_list, j);
                                for (i = 0; i < files->len; ++i)
@@ -8051,6 +8051,8 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
                int *il_offsets;
                int *line_numbers;
                int *column_numbers;
+               int *end_line_numbers;
+               int *end_column_numbers;
                int *source_files;
                GPtrArray *source_file_list;
 
@@ -8071,7 +8073,7 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
                        break;
                }
 
-               mono_debug_symfile_get_line_numbers_full (minfo, &source_file, &source_file_list, &n_il_offsets, &il_offsets, &line_numbers, &column_numbers, &source_files);
+               mono_debug_symfile_get_line_numbers_full (minfo, &source_file, &source_file_list, &n_il_offsets, &il_offsets, &line_numbers, &column_numbers, &source_files, &end_line_numbers, &end_column_numbers);
                buffer_add_int (buf, header->code_size);
                if (CHECK_PROTOCOL_VERSION (2, 13)) {
                        buffer_add_int (buf, source_file_list->len);
@@ -8102,10 +8104,17 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
                                buffer_add_int (buf, source_files [i]);
                        if (CHECK_PROTOCOL_VERSION (2, 19))
                                buffer_add_int (buf, column_numbers ? column_numbers [i] : -1);
+                       if (CHECK_PROTOCOL_VERSION (2, 32)) {
+                               buffer_add_int (buf, end_line_numbers ? end_line_numbers [i] : -1);
+                               buffer_add_int (buf, end_column_numbers ? end_column_numbers [i] : -1);
+                       }
                }
                g_free (source_file);
                g_free (il_offsets);
                g_free (line_numbers);
+               g_free (column_numbers);
+               g_free (end_line_numbers);
+               g_free (end_column_numbers);
                g_free (source_files);
                g_ptr_array_free (source_file_list, TRUE);
                mono_metadata_free_mh (header);
index 7542f49aa75d234f995cf7834b667a5f00bb3d9a..9f68a62683e94c6033c25e4995891bf282e2fb5d 100644 (file)
@@ -723,7 +723,7 @@ emit_all_line_number_info (MonoDwarfWriter *w)
                if (!minfo)
                        continue;
 
-               mono_debug_symfile_get_line_numbers_full (minfo, &source_file, &source_file_list, NULL, NULL, NULL, NULL, NULL);
+               mono_debug_symfile_get_line_numbers_full (minfo, &source_file, &source_file_list, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
                for (i = 0; i < source_file_list->len; ++i) {
                        MonoDebugSourceInfo *sinfo = g_ptr_array_index (source_file_list, i);
                        add_line_number_file_name (w, sinfo->source_file, 0, 0);