Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for LogPoints in OpenDebugAD7 #1013

Merged
merged 8 commits into from
Jun 26, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add comments and handle invalid logpoints
  • Loading branch information
WardenGnaw committed Jun 23, 2020
commit e11846826020ef98cde1a1aa50e03f064c921f35
45 changes: 29 additions & 16 deletions src/OpenDebugAD7/AD7DebugSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 256,7 @@ private IList<Tracepoint> GetTracepoints(IDebugBreakpointEvent2 debugEvent)
{
if (ppBPRequest is AD7BreakPointRequest ad7BreakpointRequest)
{
if (!string.IsNullOrEmpty(ad7BreakpointRequest.LogMessage))
if (ad7BreakpointRequest.HasTracepoint)
{
tracepoints.Add(ad7BreakpointRequest.Tracepoint);
}
Expand Down Expand Up @@ -1641,17 1641,16 @@ protected override void HandleSetBreakpointsRequestAsync(IRequestResponder<SetBr
toRemove.Delete();
dict.Remove(bp.Line);
}
// Check to see if tracepoint changed
else if (!StringComparer.Ordinal.Equals(ad7BPRequest.LogMessage, bp.LogMessage))
{
ad7BPRequest.ClearTracepoint();
var toRemove = dict[bp.Line];
toRemove.Delete();
dict.Remove(bp.Line);
}
else
{
if (!string.IsNullOrWhiteSpace(bp.LogMessage))
{
ad7BPRequest.LogMessage = bp.LogMessage;
}
else
{
ad7BPRequest.LogMessage = null;
}

if (ad7BPRequest.BindResult != null)
{
// use the breakpoint created from IDebugBreakpointErrorEvent2 or IDebugBreakpointBoundEvent2
Expand Down Expand Up @@ -1685,17 1684,31 @@ protected override void HandleSetBreakpointsRequestAsync(IRequestResponder<SetBr

dict[bp.Line] = pendingBp;

bool verified = true;
if (!string.IsNullOrEmpty(bp.LogMessage))
{
pBPRequest.LogMessage = bp.LogMessage;
verified = pBPRequest.SetLogMessage(bp.LogMessage);
}

resBreakpoints.Add(new Breakpoint()
if (verified)
{
Id = (int)pBPRequest.Id,
Verified = true,
Line = bp.Line
});
resBreakpoints.Add(new Breakpoint()
{
Id = (int)pBPRequest.Id,
Verified = verified,
Line = bp.Line
});
}
else
{
resBreakpoints.Add(new Breakpoint()
{
Id = (int)pBPRequest.Id,
Verified = verified,
Line = bp.Line,
Message = "Unable to parse logMessage."
WardenGnaw marked this conversation as resolved.
Show resolved Hide resolved
});
}
}
catch (Exception e)
{
Expand Down
73 changes: 51 additions & 22 deletions src/OpenDebugAD7/AD7Impl/AD7BreakPointRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 19,6 @@ static public uint GetNextBreakpointId()

public string Condition { get; private set; }

private string m_logMessage;

public string LogMessage {
get
{
return m_logMessage;
}
set {
if (value != null)
{
Tracepoint = Tracepoint.CreateTracepoint(value);
}
else
{
Tracepoint = null;
}
m_logMessage = value;
}
}

public Tracepoint Tracepoint { get; private set; }

public AD7DocumentPosition DocumentPosition { get; private set; }

public AD7FunctionPosition FunctionPosition { get; private set; }
Expand Down Expand Up @@ -134,5 112,56 @@ public int GetChecksum(ref Guid guidAlgorithm, CHECKSUM_DATA[] checksumData)
return HRConstants.E_FAIL;
}
}

#region Tracepoints

private string m_logMessage;
private Tracepoint m_Tracepoint;

public void ClearTracepoint()
{
m_logMessage = null;
m_Tracepoint = null;
}

public bool SetLogMessage(string logMessage)
{
try
{
m_Tracepoint = Tracepoint.CreateTracepoint(logMessage);
}
catch (InvalidTracepointException e)
{
return false;
}
m_logMessage = logMessage;
return true;
}

public string LogMessage
WardenGnaw marked this conversation as resolved.
Show resolved Hide resolved
{
get
{
return m_logMessage;
}
}

public bool HasTracepoint
{
get
{
return !string.IsNullOrEmpty(m_logMessage) && m_Tracepoint != null;
}
}

public Tracepoint Tracepoint
{
get
{
return m_Tracepoint;
}
}

#endregion
}
}
107 changes: 70 additions & 37 deletions src/OpenDebugAD7/Tracepoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 27,7 @@ private Tracepoint(string logMessage)

internal static Tracepoint CreateTracepoint(string logMessage)
{
Tracepoint tp = null;

try
{
tp = new Tracepoint(logMessage);
}
catch (InvalidTracepointException)
{
}

return tp;
return new Tracepoint(logMessage); ;
WardenGnaw marked this conversation as resolved.
Show resolved Hide resolved
}

internal string GetLogMessage(IDebugThread2 pThread, uint radix, string processName)
Expand Down Expand Up @@ -94,8 84,8 @@ private string GetInterpolatedLogMessage(string logMessage, IDebugThread2 pThrea
}
else
{
value = InterpolateVariable(keyValuePair.Value, topFrame[0].m_pFrame, radix);
currIndex = 2;
string toInterpolate = keyValuePair.Value;
value = InterpolateVariable(toInterpolate.Substring(1, toInterpolate.Length - 2), topFrame[0].m_pFrame, radix);
}

// Cache expression
Expand Down Expand Up @@ -278,14 268,31 @@ private string InterpolateVariable(string variable, IDebugStackFrame2 topFrame,

if ((propertyInfo[0].dwAttrib & enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_VALUE_ERROR) == enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_VALUE_ERROR)
{
return errorMessage;
// bstrValue has useful information.
return string.Format(CultureInfo.InvariantCulture, "{0}: {1}", errorMessage, propertyInfo[0].bstrValue);
}

return propertyInfo[0].bstrValue;
}

#region Tracepoint Parsing

/// <summary>
/// The parse method for Tracepoints.
///
/// Algorithm:
/// Go though each character in the string.
/// 1. If previous character was an escape, check to see if current is curl brace. If so, just output curl brace, else output escape and character.
/// 2. If it is an escape character, toggle isEscape to be true. Goto 1.
/// 3. If it is a '$', find the end of the token. If it is a known token, it will be added to m_indexToExpressions and skip over all the characters
/// in the token. If not, it will just add $ and continue.
/// 4. If it is a open curl brace, try to find end match curl brace for the interpolated expression. Add to m_indexToExpressions.
/// If there is no matching end brace, an exception will be thrown.
/// 5. If there is a double quote, find the associated end quote. Ignore any interpolation in here.
/// 6. Other character, just add to message to output.
/// </summary>
/// <param name="input">The logMessage to parse</param>
/// <returns>The new string after it has been parsed, it will check for excaped curl braces.</returns>
private string Parse(string input)
{
StringBuilder replace = new StringBuilder();
Expand Down Expand Up @@ -332,7 339,7 @@ private string Parse(string input)
{
if (FindInterpolatedExpression(input.Substring(index), out int endIndex))
{
string buffer = input.Substring(index 1, endIndex - 1);
string buffer = input.Substring(index, endIndex 1);

if (!string.IsNullOrWhiteSpace(buffer))
{
Expand Down Expand Up @@ -405,6 412,12 @@ private bool FindToken(string input, out int endIndex)
}
}

/// <summary>
/// Method to find the end matching quote.
/// </summary>
/// <param name="input">string to find quote. Index 0 is the open quote.</param>
/// <param name="endIndex">output of where the index of the end quote relative to 'input'</param>
/// <returns>true if a end quote was found</returns>
private bool FindEndQuote(string input, out int endIndex)
{
endIndex = -1;
Expand Down Expand Up @@ -435,56 448,76 @@ private bool FindEndQuote(string input, out int endIndex)
return false;
}

/// <summary>
/// Method to find the interpolated expression.
/// E.g. Find the end curl brace.
/// </summary>
/// <param name="input">String to find the end brace. Index 0 is '{'</param>
/// <param name="endIndex">Index of '}' relative to input.</param>
/// <returns>true if an end brace was found.</returns>
private bool FindInterpolatedExpression(string input, out int endIndex)
{
endIndex = -1;
int index = 0;
StringBuilder buffer = new StringBuilder();
int nested = 0;
bool isEscaped = false;
while ( index < input.Length)
{
char c = input[index];
if (c == '{')
if (isEscaped)
{
nested ;
buffer.Append(c);
isEscaped = false;
}
else if (c == '}')
else
{
if (nested > 0)
if (c == '\\')
{
nested--;
isEscaped = true;
}
else
else if (c == '{')
{
endIndex = index;
return true;
nested ;
}
}
else if (c == '"')
{
if (FindEndQuote(input.Substring(index), out int length))
else if (c == '}')
{
length = length 1;
if (nested > 0)
{
nested--;
}
else
{
endIndex = index;
return true;
}
}
else
else if (c == '"')
{
length = input.Length - index;
if (FindEndQuote(input.Substring(index), out int length))
{
length = length 1;
}
else
{
length = input.Length - index;
}
buffer.Append(input.Substring(index, length));
index = length;
}
buffer.Append(input.Substring(index, length));
index = length;
}
}

return false;
}

#endregion

public class InvalidTracepointException : Exception
}
WardenGnaw marked this conversation as resolved.
Show resolved Hide resolved
public class InvalidTracepointException : Exception
{
public InvalidTracepointException()
{
public InvalidTracepointException()
{
}
}
}

}