Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add support for 'source ranges' - we now use StartLine/EndLine/StartC…

…olumn/EndColumn instead of just line numbers.

2009-04-16  Martin Baulig  <martin@ximian.com>

	Add support for 'source ranges' - instead of only using line
	numbers, we now use a struct containing 'StartLine', 'EndLine',
	'StartColumn' and 'EndColumn'.

	* classes/Method.cs
	(LineEntry.SourceRange): New public field.

	* classes/SourceAddress.cs
	(SourceAddress.HasSourceRange): New public property.
	(SourceAddress.SourceRange): New public property.
	(SourceRange): New public struct.

svn path=/trunk/debugger/; revision=131838
  • Loading branch information...
commit 3ad7ce08c7348f6797863c6f275dccec10111e70 1 parent 84c005f
Martin Baulig authored
View
14 ChangeLog
@@ -1,3 +1,17 @@
+2009-04-16 Martin Baulig <martin@ximian.com>
+
+ Add support for 'source ranges' - instead of only using line
+ numbers, we now use a struct containing 'StartLine', 'EndLine',
+ 'StartColumn' and 'EndColumn'.
+
+ * classes/Method.cs
+ (LineEntry.SourceRange): New public field.
+
+ * classes/SourceAddress.cs
+ (SourceAddress.HasSourceRange): New public property.
+ (SourceAddress.SourceRange): New public property.
+ (SourceRange): New public struct.
+
2009-04-15 Martin Baulig <martin@ximian.com>
* classes/SourceAddress.cs
View
7 classes/Method.cs
@@ -45,17 +45,24 @@ public struct LineEntry : IComparable {
public readonly int File;
public readonly int Line;
public readonly bool IsHidden;
+ public readonly SourceRange? SourceRange;
public LineEntry (TargetAddress address, int file, int line)
: this (address, file, line, false)
{ }
public LineEntry (TargetAddress address, int file, int line, bool is_hidden)
+ : this (address, file, line, is_hidden, null)
+ { }
+
+ public LineEntry (TargetAddress address, int file, int line, bool is_hidden,
+ SourceRange? source_range)
{
this.Address = address;;
this.File = file;
this.Line = line;
this.IsHidden = is_hidden;
+ this.SourceRange = source_range;
}
public int CompareTo (object obj)
View
43 classes/SourceAddress.cs
@@ -19,18 +19,26 @@ public class SourceAddress : DebuggerMarshalByRefObject
{
SourceFile file;
SourceBuffer buffer;
+ SourceRange? source_range;
int row;
int line_offset;
int line_range;
public SourceAddress (SourceFile file, SourceBuffer buffer, int row,
- int offset, int range)
+ int line_offset, int line_range)
{
this.file = file;
this.buffer = buffer;
this.row = row;
- this.line_offset = offset;
- this.line_range = range;
+ this.line_offset = line_offset;
+ this.line_range = line_range;
+ }
+
+ public SourceAddress (SourceFile file, SourceBuffer buffer, int row,
+ int line_offset, int line_range, SourceRange? source_range)
+ : this (file, buffer, row, line_offset, line_range)
+ {
+ this.source_range = source_range;
}
public SourceFile SourceFile {
@@ -56,6 +64,18 @@ public class SourceAddress : DebuggerMarshalByRefObject
}
}
+ public bool HasSourceRange {
+ get {
+ return source_range != null;
+ }
+ }
+
+ public SourceRange SourceRange {
+ get {
+ return source_range.Value;
+ }
+ }
+
public int LineRange {
get {
return line_range;
@@ -102,4 +122,21 @@ public override string ToString ()
return builder.ToString ();
}
}
+
+ [Serializable]
+ public struct SourceRange
+ {
+ public readonly int StartLine;
+ public readonly int EndLine;
+ public readonly int StartColumn;
+ public readonly int EndColumn;
+
+ public SourceRange (int start_line, int end_line, int start_col, int end_col)
+ {
+ this.StartLine = start_line;
+ this.EndLine = end_line;
+ this.StartColumn = start_col;
+ this.EndColumn = end_col;
+ }
+ }
}
View
13 languages/mono/MonoSymbolFile.cs
@@ -1645,7 +1645,7 @@ public override SourceAddress Lookup (TargetAddress address)
(int) (Addresses [0].Address - address));
}
- SourceAddress create_address (LineEntry entry, int offset, int range)
+ SourceAddress create_address (LineEntry entry, int line_offset, int line_range)
{
SourceFile file = null;
SourceBuffer buffer = null;
@@ -1659,7 +1659,7 @@ SourceAddress create_address (LineEntry entry, int offset, int range)
buffer = Method.MethodSource.SourceBuffer;
}
- return new SourceAddress (file, buffer, entry.Line, offset, range);
+ return new SourceAddress (file, buffer, entry.Line, line_offset, line_range, entry.SourceRange);
}
public override void DumpLineNumbers (TextWriter writer)
@@ -1733,7 +1733,14 @@ protected class MonoMethodLineNumberTable : MonoLineNumberTable
int file = lne.File != entry.CompileUnit.SourceFile.Index ? lne.File : 0;
bool hidden = lne.IsHidden;
- lines.Add (new LineEntry (address, file, lne.Row, hidden));
+ SourceRange? range = null;
+ if (lne.SourceRange != null)
+ range = new SourceRange (lne.SourceRange.StartLine, lne.SourceRange.EndLine,
+ lne.SourceRange.StartColumn, lne.SourceRange.EndColumn);
+
+ Console.WriteLine ("GENERATE LINE: {0} {1} {2}", lne, lne.Row, lne.SourceRange != null);
+
+ lines.Add (new LineEntry (address, file, lne.Row, hidden, range));
last_line = lne.Row;
}
View
13 symbolwriter/ChangeLog
@@ -1,3 +1,16 @@
+2009-04-16 Martin Baulig <martin@ximian.com>
+
+ * MonoSymbolTable.cs
+ (SourceRangeEntry): New public class.
+ (LineNumberEntry.SourceRange): New public field.
+ (LineNumberTable): Add support for source ranges.
+ (LineNumberTable.DW_LNE_MONO_set_source_range): New private
+ extended opcode to encode source ranges.
+
+ * MonoSymbolWriter.cs
+ (MonoSymbolWriter.MarkSequencePoint): Add overloaded version
+ supporting source ranges.
+
2009-03-31 Martin Baulig <martin@ximian.com>
* MdbSymbolReader.cs
View
11 symbolwriter/MdbSymbolReader.cs
@@ -225,8 +225,15 @@ public void PrintLineNumberTables ()
seen_files.Add (line.File, true);
}
- Message (" Line {0}:{1}:{2}{3}", line.File, line.Row, line.Offset,
- line.IsHidden ? " (hidden)" : "");
+ string range = "";
+ if (line.SourceRange != null) {
+ SourceRangeEntry sre = (SourceRangeEntry) line.SourceRange;
+ range = String.Format (" - {0} {1} {2} {3}", sre.StartLine, sre.EndLine,
+ sre.StartColumn, sre.EndColumn);
+ }
+
+ Message (" Line {0}:{1}:{2}{3}{4}", line.File, line.Row, line.Offset,
+ line.IsHidden ? " (hidden)" : "", range);
}
}
}
View
117 symbolwriter/MonoSymbolTable.cs
@@ -186,6 +186,9 @@ public class LineNumberEntry
public readonly int File;
public readonly int Offset;
public readonly bool IsHidden;
+#if DEBUGGER_SOURCE
+ public readonly SourceRangeEntry SourceRange;
+#endif
#endregion
public LineNumberEntry (int file, int row, int offset)
@@ -198,8 +201,28 @@ public LineNumberEntry (int file, int row, int offset, bool is_hidden)
this.Row = row;
this.Offset = offset;
this.IsHidden = is_hidden;
+
+#if DEBUGGER_SOURCE
+ this.SourceRange = null;
+#endif
+ }
+
+#if DEBUGGER_SOURCE
+ public LineNumberEntry (int file, int offset, int start_row, int end_row,
+ int start_col, int end_col)
+ : this (file, start_row, offset, false)
+ {
+ SourceRange = new SourceRangeEntry (start_row, end_row, start_col, end_col);
}
+ public LineNumberEntry (int file, int row, int offset, bool is_hidden,
+ SourceRangeEntry source_range)
+ : this (file, row, offset, is_hidden)
+ {
+ this.SourceRange = source_range;
+ }
+#endif
+
public static LineNumberEntry Null = new LineNumberEntry (0, 0, 0);
private class OffsetComparerClass : IComparer
@@ -243,6 +266,24 @@ public override string ToString ()
}
}
+#if DEBUGGER_SOURCE
+ public class SourceRangeEntry
+ {
+ public readonly int StartLine;
+ public readonly int EndLine;
+ public readonly int StartColumn;
+ public readonly int EndColumn;
+
+ public SourceRangeEntry (int start_line, int end_line, int start_col, int end_col)
+ {
+ this.StartLine = start_line;
+ this.EndLine = end_line;
+ this.StartColumn = start_col;
+ this.EndColumn = end_col;
+ }
+ }
+#endif
+
public class CodeBlockEntry
{
public int Index;
@@ -713,14 +754,7 @@ internal void WriteData (MyBinaryWriter bw)
if (guid == null) {
guid = Guid.NewGuid ().ToByteArray ();
- try {
- using (FileStream fs = new FileStream (file_name, FileMode.Open, FileAccess.Read)) {
- MD5 md5 = MD5.Create ();
- hash = md5.ComputeHash (fs);
- }
- } catch {
- hash = new byte [16];
- }
+ hash = compute_hash (file_name);
}
bw.Write (guid);
@@ -728,6 +762,21 @@ internal void WriteData (MyBinaryWriter bw)
bw.Write ((byte) (auto_generated ? 1 : 0));
}
+ byte[] compute_hash (string filename)
+ {
+ try {
+ if (!File.Exists (filename))
+ return new byte [16];
+
+ using (FileStream fs = new FileStream (filename, FileMode.Open, FileAccess.Read)) {
+ MD5 md5 = MD5.Create ();
+ return md5.ComputeHash (fs);
+ }
+ } catch {
+ return new byte [16];
+ }
+ }
+
internal void Write (BinaryWriter bw)
{
bw.Write (Index);
@@ -821,6 +870,7 @@ public class LineNumberTable
// MONO extensions.
public const byte DW_LNE_MONO_negate_is_hidden = 0x40;
+ public const byte DW_LNE_MONO_set_source_range = 0x41;
internal const byte DW_LNE_MONO__extensions_start = 0x40;
internal const byte DW_LNE_MONO__extensions_end = 0x7f;
@@ -867,6 +917,27 @@ internal void Write (MonoSymbolFile file, MyBinaryWriter bw)
last_is_hidden = LineNumbers [i].IsHidden;
}
+#if DEBUGGER_SOURCE
+ if (LineNumbers [i].SourceRange != null) {
+ bw.Write ((byte) 0);
+ long tmp_offset = bw.BaseStream.Position;
+ bw.Write ((byte) 0);
+ bw.Write (DW_LNE_MONO_set_source_range);
+
+ SourceRangeEntry range = (SourceRangeEntry) LineNumbers [i].SourceRange;
+ bw.WriteLeb128 (range.StartLine - last_line);
+ bw.WriteLeb128 (range.EndLine - range.StartLine);
+ bw.WriteLeb128 (range.StartColumn);
+ bw.WriteLeb128 (range.EndColumn);
+
+ long tmp_size = bw.BaseStream.Position - tmp_offset - 1;
+ long tmp_end = bw.BaseStream.Position;
+ bw.BaseStream.Position = tmp_offset;
+ bw.Write ((byte) tmp_size);
+ bw.BaseStream.Position = tmp_end;
+ }
+#endif
+
if (offset_inc >= MaxAddressIncrement) {
if (offset_inc < 2 * MaxAddressIncrement) {
bw.Write (DW_LNS_const_add_pc);
@@ -917,6 +988,9 @@ void DoRead (MonoSymbolFile file, MyBinaryReader br)
bool is_hidden = false, modified = false;
int stm_line = 1, stm_offset = 0, stm_file = 1;
+#if DEBUGGER_SOURCE
+ SourceRangeEntry source_range = null;
+#endif
while (true) {
byte opcode = br.ReadByte ();
@@ -927,12 +1001,27 @@ void DoRead (MonoSymbolFile file, MyBinaryReader br)
if (opcode == DW_LNE_end_sequence) {
if (modified)
+#if DEBUGGER_SOURCE
+ lines.Add (new LineNumberEntry (
+ stm_file, stm_line, stm_offset, is_hidden, source_range));
+#else
lines.Add (new LineNumberEntry (
stm_file, stm_line, stm_offset, is_hidden));
+#endif
break;
} else if (opcode == DW_LNE_MONO_negate_is_hidden) {
is_hidden = !is_hidden;
modified = true;
+#if DEBUGGER_SOURCE
+ } else if (opcode == DW_LNE_MONO_set_source_range) {
+ int start_line = stm_line + br.ReadLeb128 ();
+ int end_line = start_line + br.ReadLeb128 ();
+ int start_col = br.ReadLeb128 ();
+ int end_col = br.ReadLeb128 ();
+
+ source_range = new SourceRangeEntry (
+ start_line, end_line, start_col, end_col);
+#endif
} else if ((opcode >= DW_LNE_MONO__extensions_start) &&
(opcode <= DW_LNE_MONO__extensions_end)) {
; // reserved for future extensions
@@ -947,8 +1036,14 @@ void DoRead (MonoSymbolFile file, MyBinaryReader br)
} else if (opcode < OpcodeBase) {
switch (opcode) {
case DW_LNS_copy:
+#if DEBUGGER_SOURCE
+ lines.Add (new LineNumberEntry (
+ stm_file, stm_line, stm_offset, is_hidden, source_range));
+ source_range = null;
+#else
lines.Add (new LineNumberEntry (
stm_file, stm_line, stm_offset, is_hidden));
+#endif
modified = false;
break;
case DW_LNS_advance_pc:
@@ -977,8 +1072,14 @@ void DoRead (MonoSymbolFile file, MyBinaryReader br)
stm_offset += opcode / LineRange;
stm_line += LineBase + (opcode % LineRange);
+#if DEBUGGER_SOURCE
+ lines.Add (new LineNumberEntry (
+ stm_file, stm_line, stm_offset, is_hidden, source_range));
+ source_range = null;
+#else
lines.Add (new LineNumberEntry (
stm_file, stm_line, stm_offset, is_hidden));
+#endif
modified = false;
}
}
View
27 symbolwriter/MonoSymbolWriter.cs
@@ -115,6 +115,17 @@ public void DefineScopeVariable (int scope, int index)
current_method.MarkSequencePoint (offset, file, line, column, is_hidden);
}
+#if DEBUGGER_SOURCE
+ public void MarkSequencePoint (int offset, SourceFileEntry file, int start_line, int end_line,
+ int start_col, int end_col)
+ {
+ if (current_method == null)
+ return;
+
+ current_method.MarkSequencePoint (offset, file, start_line, end_line, start_col, end_col);
+ }
+#endif
+
public SourceMethodBuilder OpenMethod (ICompileUnit file, int ns_id, IMethodDef method)
{
SourceMethodBuilder builder = new SourceMethodBuilder (file, ns_id, method);
@@ -275,6 +286,22 @@ public SourceMethodBuilder (ICompileUnit comp_unit, int ns_id, IMethodDef method
file_idx, line, offset, is_hidden);
}
+#if DEBUGGER_SOURCE
+ public void MarkSequencePoint (int offset, SourceFileEntry file, int start_line, int end_line,
+ int start_col, int end_col)
+ {
+ if (method_lines_pos == method_lines.Length) {
+ LineNumberEntry [] tmp = method_lines;
+ method_lines = new LineNumberEntry [method_lines.Length * 2];
+ Array.Copy (tmp, method_lines, method_lines_pos);
+ }
+
+ int file_idx = file != null ? file.Index : 0;
+ method_lines [method_lines_pos++] = new LineNumberEntry (
+ file_idx, offset, start_line, end_line, start_col, end_col);
+ }
+#endif
+
public void StartBlock (CodeBlockEntry.Type type, int start_offset)
{
if (_block_stack == null)
Please sign in to comment.
Something went wrong with that request. Please try again.