以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,这意味着调试端已nulltarget参数中接收到。

什么可能导致这种情况?我该如何解决?


一些随机笔记

  • 这不是因为调试器端总是 32 位,而被调试器端有时是 64 位。
  • 也不是因为不同的 TFM - 当调试器端面向 .NET Framework,而被调试端可以面向 .NET Standard 或 .NET Core 时。
  • TransferData影响覆盖;在GetData覆盖总是得到目标值(我实际使用GetData要解决这一点,但我真的宁愿用GetData别的东西。)我已经尝试测试ReplaceData/ ReplaceObject,但IsObjectReplaceable物业始终回报false
  • 我已经针对其他值类型进行了测试 - TimeSpanDateTimeOffset和自定义struct- 并看到了相同的行为。int但是,当我针对 进行测试时,目标进程崩溃并且调试会话被中断。
  • 针对 aDateTime?显示与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>

以上是以DateTime为目标的调试可视化工具不传输值的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>