代码之家  ›  专栏  ›  技术社区  ›  kizzx2

高级Visual Studio功夫测试-调试期间从即时窗口调用函数

  •  5
  • kizzx2  · 技术社区  · 16 年前

    我看到有人问了一些相关的问题,但这些问题要么太高级了,我无法理解,要么缺乏从头到尾的循序渐进的指导(大多数问题最终都是关于他们自己的实验结果的内部讨论)。好的,这里是,给定这个简单的程序:

    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
        FILE * f;
        char buffer[100];
    
        memset(buffer, 0, 100);
    
        fun();
    
        f = fopen("main.cpp", "r");
        fread(buffer, 1, 99, f);
        printf(buffer);
        fclose(f);
    
        return 0;
    }
    

    它所做的基本上是打印自身(假定文件名为 main.cpp )

    问题

    我怎样才能让它打印另一个文件,比如 foobar.txt 不修改源代码 ?它与通过VS运行、单步执行函数和劫持文件指针有关。 fread() 被称为。无需担心通过呼叫泄漏资源 fclose() .

    我试过简单的 f = fopen("foobar.txt", "r") 给予

    CXX0017: Error: symbol "fopen" not found
    

    有什么想法吗?

    编辑

    我偶然发现了解决办法 Debugging Mozilla on Windows FAQ . 要放入即时窗口的正确命令是

    f = {,,MSVCR100D}fopen("foo.txt", "r")
    

    但是,它并不能真正回答这个问题:

    • 我还是不明白这是怎么回事。
    • 如何系统地找出 {,,MSVCR100D} 任何给定方法的一部分?我知道MSVCR的版本会随着系统的变化而变化。我怎么知道?
    • 有人能解释大括号语法吗,特别是这两个逗号在那里做什么?是否有更多隐藏的宝石使用这种语法?
    2 回复  |  直到 15 年前
        1
  •  6
  •   Community Mohan Dere    9 年前

    大括号语法是vs Context Operator 大部分都被破坏了——正如在链接中详细描述的那样(或者至少,几乎不是一块隐藏的宝石)。它用于VS表达式计算引擎在运行时需要解析函数的任何地方,例如在监视窗口中计算复合表达式、设置断点或在立即/命令窗口中(如您所见)。

    它的第三个参数是二进制,其中包括要调用的函数的实现。对于像fopen这样的crt函数,通常等于-

    msvcr[vs版本].dll

    (我似乎记得扩展是必要的——但可能在VS2010中有所改变)。“d”表示调试dll版本。vs版本号解码为:vs2005->8,vs2008->9,vs2010->10。

    还要注意评估引擎 various other gotchas 小心。

        2
  •  4
  •   kizzx2    16 年前

    为了补充OFEK出色的答案,我发现了一种方法,可以系统地找出函数调用属于哪个模块。(即 MSVCR100D 部分)。

    • 单步执行调试器,查找要调用的函数的实例。(在这个案例中,我正在寻找 fopen ;
    • 找到后,按F11进入。
    • 右键单击并选择“显示反汇编”
    • 您可以找到当前执行指令的地址。(在查看选项周围单击可在未显示时切换该选项)
    • 打开模块调试窗口(alt+ctrl+u)
    • 查看包含当前指令地址的地址范围的已加载模块列表。你找到了函数的模块名!

    我相信您可以使用这个方法来查找任何类的模块名。例如,当您查看一个大型代码库,并且希望在即时窗口中即时调用某个任意类的方法时,这一点非常有用。您也可以通过自己调用构造函数来动态创建类的实例。

    现在C++不是一种母语吗?我们几乎感觉像是在一个托管的脚本环境中:p

    推荐文章