gpt4 book ai didi

c# - 调试器引擎。方法重写、局部变量提升和变量解析

转载 作者:太空狗 更新时间:2023-10-29 23:43:53 25 4
gpt4 key购买 nike

我正在使用 MDBG 示例制作托管 .NET 调试器。它适用于简单的场景,但在发生方法重写时会出现问题。最关键的部分是 yield 方法和异步方法。

我已经问了一个更一般的 question关于这些问题。现在我想专注于局部变量解析。请考虑代码:

    using System;
using System.Threading.Tasks;

class C
{
public static void Main() {

var instance = new Instance();
instance.Start().Wait();
}
}
class Instance
{
public static async Task F() { for(var i=0; i<100; i++) { Console.WriteLine(i); await Task.Delay(100); } }
public async Task Start() {
var z = "test";<------- Breakpoint
var x = 10;
await F();
}
}

当调试器到达断点时,我正在查询调试器以获取局部变量,唯一的变量是 this .变量 xz悬卡在生成的结构上,无法直接解析 Image .

那么问题来了:在调试yield方法和async方法中的局部变量时如何解决?

在对我上一个问题的评论中,@Brian Reichle 给了我一些提示,我可以如何在现有变量和提升的变量之间获取映射。探索 SymAttribute和 Roslyn 来源我得出的结论是它不直接存储它们之间的映射。 SymAttribute用于获取CustomDebugInfoRecord ,它存储了部分信息(使用 Roslyn 的 Pdb2Xml 库生成它):

    <method containingType="Instance+&lt;Start&gt;d__1" name="MoveNext">
<customDebugInfo>
<forward declaringType="C" methodName="Main" />
<hoistedLocalScopes>
<slot startOffset="0x0" endOffset="0xcc" />
<slot startOffset="0x0" endOffset="0xcc" />
</hoistedLocalScopes>
<encLocalSlotMap>
<slot kind="27" offset="0" />
<slot kind="33" offset="161" />
<slot kind="temp" />
<slot kind="temp" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
<entry offset="0x0" hidden="true" document="1" />
<entry offset="0x7" hidden="true" document="1" />
<entry offset="0xe" startLine="16" startColumn="37" endLine="16" endColumn="38" document="1" />
<entry offset="0xf" startLine="17" startColumn="14" endLine="17" endColumn="29" document="1" />
<entry offset="0x1a" startLine="18" startColumn="14" endLine="18" endColumn="35" document="1" />
<entry offset="0x26" startLine="19" startColumn="14" endLine="19" endColumn="25" document="1" />
<entry offset="0x2e" startLine="19" startColumn="25" endLine="19" endColumn="46" document="1" />
<entry offset="0x3a" startLine="20" startColumn="14" endLine="20" endColumn="24" document="1" />
<entry offset="0x45" hidden="true" document="1" />
<entry offset="0xa0" hidden="true" document="1" />
<entry offset="0xb8" startLine="21" startColumn="11" endLine="21" endColumn="12" document="1" />
<entry offset="0xc0" hidden="true" document="1" />
</sequencePoints>
<asyncInfo>
<kickoffMethod declaringType="Instance" methodName="Start" />
<await yield="0x57" resume="0x72" declaringType="Instance+&lt;Start&gt;d__1" methodName="MoveNext" />
</asyncInfo>
</method>

所以我现在能看到的解决提升变量的唯一方法是:

  1. 检查方法是否被重写。
  2. 对于此类方法,获取 asyncInfo 并发现它是 await declaringType。它给出了生成的结构的名称以及提升变量的位置。
  3. 解决this.generatedStructureName
  4. Roslyn 源代码揭示 naming conventions for hoisted variables , 可用于翻译 x变量为 <x>5__2

这种方法似乎不对,我不确定它是否会奏效,但这是我现在唯一能想到的。还有其他可能解决这个问题吗? VisualStudio 如何解决这个问题?

我创建了一个小型存储库来重现问题 here

最佳答案

好吧,我在这里或 msdn 论坛上没有找到任何人可以启发我了解 VS 算法的工作原理,但我发现 SharpDevelop 支持异步方法的变量解析。令人惊讶的是,它使用的算法与我在问题中所描述的相似:仅解析提升的字段名称。

相关资源可用here在gitHub上,如果别人遇到类似的问题就会卡住。不过,我认为这不是一个好的解决方案,希望有更好的方法来解决这个问题......

关于c# - 调试器引擎。方法重写、局部变量提升和变量解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39471479/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com