以DateTime为目标的调试可视化工具不传输值
c#
我写了一个Visual Studio 调试可视化工具,它的目标是DateTime(repo)。我的问题是,如果目标表达式是 of object,而不是DateTime( issue ) ,则调试器端仅将目标值传递给调试对象端。
我已经发布了一个 GH 存储库,其中包含一个重现问题的MCVE。调试器端看起来像这样:
protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider) {
var response = objectProvider.TransferObject(5);
var msg = response switch {
string s => s,
IEnumerable e => string.Join(", ", e.Cast<object>()),
_ => "Unhandled type"
};
MessageBox.Show(msg);
}
被调试方看起来像这样:
public override void TransferData(object target, Stream incomingData, Stream outgoingData) {
int? repetitions = Deserialize(incomingData) switch {
int i when i > 0 => i,
string s when int.TryParse(s, out int i) && i > 0 => i,
_ => null
};
object toSerialize =
repetitions is null ? $"Invalid value for repetitions" :
target switch {
DateTime dt => Repeat(dt, repetitions.Value).ToArray(),
null => $"{nameof(target)} is null",
_ => $"Not implemented for target of type {target.GetType().FullName}" as object
};
Serialize(outgoingData, toSerialize);
}
构建并安装可视化工具后,开始调试以下代码:
var dte = DateTime.UtcNow;
object o = dte;
如果我将鼠标悬停在上面o并触发可视化器,则目标DateTime将传递到调试对象端,并返回一个DateTime. 但是,如果我在 上触发可视化器dte,我会返回字符串target is null,这意味着调试端已null在target参数中接收到。
什么可能导致这种情况?我该如何解决?
一些随机笔记
- 这不是因为调试器端总是 32 位,而被调试器端有时是 64 位。
- 也不是因为不同的 TFM - 当调试器端面向 .NET Framework,而被调试端可以面向 .NET Standard 或 .NET Core 时。
- 只
TransferData影响覆盖;在GetData覆盖总是得到目标值(我实际使用GetData要解决这一点,但我真的宁愿用GetData别的东西。)我已经尝试测试ReplaceData/ReplaceObject,但IsObjectReplaceable物业始终回报false。 - 我已经针对其他值类型进行了测试 -
TimeSpan、DateTimeOffset和自定义struct- 并看到了相同的行为。int但是,当我针对 进行测试时,目标进程崩溃并且调试会话被中断。 - 针对 a
DateTime?显示与DateTime;相同的行为。我想这是因为它们都以相同的方式序列化。
当类似地针对一个目标时,异常命中的堆栈跟踪 int
针对此评论,可视化an时的错误信息int如下:
目标进程在评估函数“Microsoft.VisualStudio.DebuggerVisualizers.DebuggeeSide.Impl.ClrCustomVisualizerDebuggeeHost.TransferData”时退出,代码为 -1073740791 (0xC0000409)。
如果问题经常发生,请考虑禁用工具->选项设置“调试->常规->启用属性评估和其他隐式函数调用”或通过从立即窗口评估表达式来调试原因。有关执行此操作的信息,请参阅帮助。
接着是另一条消息:
无法加载自定义查看器。
目标进程崩溃并且调试会话结束。
我尝试使用代码断点 ( Debugger.Break())附加调试器失败。如果我从可视化器 ( new System.Diagnostics.StackTrace().ToString())返回调用堆栈并且可视化器成功运行,我会得到以下信息:
在 SimpleValueTypeVisualizer.Debuggee.VisualizerObjectSource.TransferData(对象目标,流传入数据,流传出数据)
在 Microsoft.VisualStudio.DebuggerVisualizers.DebuggeeSide.Impl.ClrCustomVisualizerDebuggeeHost.TransferData(对象可视化对象,字节 [] uiSideData)
在 TestNoRef.Program.Main(String[] args)
这似乎意味着在Microsoft.VisualStudio.DebuggerVisualizers.DebuggeeSide.Impl.ClrCustomVisualizerDebuggeeHost.TransferData.
当我打开DebuggerVisualizers.dllusing ILSpy 时,相关TransferData方法如下所示:
// Microsoft.VisualStudio.DebuggerVisualizers.DebuggeeSide.Impl.ClrCustomVisualizerDebuggeeHost
using System.IO;
public byte[] TransferData(object visualizedObject, byte[] uiSideData)
{
MemoryStream memoryStream = new MemoryStream();
MemoryStream incomingData = ((uiSideData != null) ? new MemoryStream(uiSideData) : null);
m_debuggeeSideVisualizerObject.TransferData(visualizedObject, incomingData, memoryStream);
return memoryStream.ToArray();
}
我猜想例外是在方法 ( MemoryStream incomingData = ...)的第三行。但是我仍然不清楚异常的细节,特别是为什么问题只出现在未装箱的值而不是装箱的值中。
事件日志详细信息
根据此评论,我将在类型表达式上打开可视化工具时创建的事件日志中包含数据int:
Log Name: Application
Source: Application Error
Date: 22/04/2021 12:14:36
Event ID: 1000
Task Category: (100)
Level: Error
Keywords: Classic
User: N/A
Computer: LAPTOP-7O43T4OO
Description:
Faulting application name: TestNoRef.exe, version: 1.0.0.0, time stamp: 0xd9f9e12d
Faulting module name: clr.dll, version: 4.8.4341.0, time stamp: 0x6023024f
Exception code: 0xc0000409
Fault offset: 0x00574845
Faulting process ID: 0x94c4
Faulting application start time: 0x01d73757c33e87c0
Faulting application path: ***********
Faulting module path: C:WindowsMicrosoft.NETFrameworkv4.0.30319clr.dll
Report ID: 1dcf070b-71ff-4279-be71-822698cc6168
Faulting package full name:
Faulting package-relative application ID:
Event Xml:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Application Error" />
<EventID Qualifiers="0">1000</EventID>
<Version>0</Version>
<Level>2</Level>
<Task>100</Task>
<Opcode>0</Opcode>
<Keywords>0x80000000000000</Keywords>
<TimeCreated SystemTime="2021-04-22T09:14:36.4507272Z" />
<EventRecordID>1180760705</EventRecordID>
<Correlation />
<Execution ProcessID="0" ThreadID="0" />
<Channel>Application</Channel>
<Computer>LAPTOP-7O43T4OO</Computer>
<Security />
</System>
<EventData>
<Data>TestNoRef.exe</Data>
<Data>1.0.0.0</Data>
<Data>d9f9e12d</Data>
<Data>clr.dll</Data>
<Data>4.8.4341.0</Data>
<Data>6023024f</Data>
<Data>c0000409</Data>
<Data>00574845</Data>
<Data>94c4</Data>
<Data>01d73757c33e87c0</Data>
<Data>***********</Data>
<Data>C:WindowsMicrosoft.NETFrameworkv4.0.30319clr.dll</Data>
<Data>1dcf070b-71ff-4279-be71-822698cc6168</Data>
<Data>
</Data>
<Data>
</Data>
</EventData>
</Event>