【问题标题】:How to find what variable a value is assigned to?如何找到赋值给哪个变量?
【发布时间】:2014-04-01 19:02:06
【问题描述】:

我正在调试一个旧的 C# 应用程序。有一个屏幕,我可以单击以对服务器运行查询并获取结果列表。

问题是我无法弄清楚结果是如何计算的。每个结果都有一个与之关联的浮点数,显示在屏幕上。为了便于讨论,假设第一个结果旁边的数字是 123.45。

我猜数字 123.45 必须在某个时候分配给浮点变量,但如果有数百万行代码,我还有很多工作要做!

因此,我想知道如果我确定数字 123.45 在某个时候被分配给了一个变量,是否有一些方便的方法可以找到它发生的位置以及它被分配给什么变量?有这样的调试工具吗?

编辑: 这里的评论者正确地指出我不确定该数字是否已分配给变量;我只是猜测它可能是。另外,我对在断点上设置条件很熟悉,但这在这里无济于事,因为要设置断点,您必须知道赋值发生在哪一行。

我的问题是,是否有办法检测在代码中的 unknown 位置分配给 unknown 变量的特定值。我想找到赋值发生的哪里,以及赋值给了哪个变量。

第二次编辑:让我们将其与使用 SQL 分析器进行比较。如果我知道值 123.45 被插入到表中或作为参数传递给存储过程,我可以使用 SQL 分析器并过滤包含字符串“123.45”的命令的命令文本。这可能会找到用于将 123.45 发送到 SQL 服务器的确切命令。如果我正在寻找要分配给 C# 变量的值,但我不知道是哪一个,我可以做类似的事情吗?

我认为答案可能是“否”,但我认为这里有人可能能够对此有所了解。

【问题讨论】:

  • 没有被分配给一个“变量”。例如,可以是 UI 元素的一部分。
  • 我假设您熟悉可以在断点上设置的条件?
  • 你有来源吗?如果可以,你可以设置断点并使用调用堆栈吗?
  • 在本机代码调试器中,您似乎能够中断(CPU 寄存器的)状态。您可能需要进行长时间的调试,但您可以先尝试一个小型测试程序,看看是否可行:msdn.microsoft.com/en-us/library/windows/hardware/…
  • this channel9 video 正在使用windbg 和sos。该系列中有更多视频可能值得一看。

标签: c# .net visual-studio debugging variables


【解决方案1】:

如果您可以将范围缩小到更新屏幕的不同 UI 调度程序,您可以添加一个条件来检查该特定值,如下所示:

【讨论】:

  • 感谢您的回答,但我不知道我可以通过任何方式缩小范围。问题是应用程序的编写比它需要的复杂得多。
【解决方案2】:

考虑到这两种方法,添加另一个答案是一个不同的概念。

找到它的一种可能的解决方案是添加一个小方法,使用Debugger.Break() 进行检查并以编程方式中断调试会话。

恐怕我的 WPF 不是很好,所以我通过简单地将值直接添加到 Control.Items 来快速模拟数据源,通过每次添加项目时调用的小 event 处理程序(所以我模拟OnItemSourceChanged 事件)。

您当然应该使用内置的数据绑定集合,但概念是相同的(如果您有一个使用“干净”方法的工作示例,请随时编辑和添加它)。

考虑这个例子:

public partial class MainWindow : Window
{
    public event EventHandler<EventArgs> UpdateUI; 

    public MainWindow()
    {
        InitializeComponent();
        UpdateUI += sniff;

        PrintFromA();
        PrintFromB();
    }

    private void sniff(object sender, EventArgs e)
    {
        if (lstSample.Items.Contains(45))
        {
            Debugger.Break();
        }
    }

    private void updateUI(int i)
    {
        Dispatcher.Invoke(() =>
        {
            lstSample.Items.Add(i);
        });

        UpdateUI.Invoke(this, new EventArgs());
    }


    private void PrintFromA()
    {
        for (int i = 0; i < 50; i += 2)
        {
            updateUI(i);
        }
    }

    private void PrintFromB()
    {
        for (int i = 0; i < 50; i++)
        {
            updateUI(i);
        }
    } 
}

我们仍在检查该值是否为 45,因此 PrintFromB 应该是我们正在寻找的方法(PrintFromA 将绕过它)。

当我们执行这个时,我们可以看到我们的代码在 PrintFromB 几乎完全执行时停止了,就在刚刚添加 45 的位置。

查看堆栈跟踪,我们看到:

现在我们可以清楚地看到我们从PrintFromB 方法中得到了这个值。转到堆栈跟踪中的这一点将非常清楚地向您显示哪个变量保存了您要查找的值。

【讨论】:

    【解决方案3】:

    如果您的 in vs 2012,您可以尝试在其中添加手表?我不确定在您的环境中是否可能,但在您想要找到它的方法调用的开头设置一个断点。右键单击您的变量,然后单击添加手表并在底部关注它。

    【讨论】:

    • 如果我知道要监视哪个变量,监视列表变量可能会有所帮助,但在这种情况下,我什至不知道变量的名称!
    猜你喜欢
    • 2014-04-30
    • 2012-03-07
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-31
    • 1970-01-01
    相关资源
    最近更新 更多