高级 Visual Studio 功夫测试——调试期间从立即窗口调用函数
我看到有人提出了一些相关问题,但它们要么太高级,我无法掌握,要么缺乏从头到尾的逐步指导(其中大多数最终都是内部人士谈论他们自己的实验结果)。好吧,给定这个简单的程序:
#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()
之前劫持 FILE 指针有关。无需担心调用fclose()
会泄漏资源。
我尝试了简单的 f = fopen("foobar.txt", "r")
,它给出了
CXX0017: Error: symbol "fopen" not found
任何想法?
编辑
我在 在 Windows 上调试 Mozilla 常见问题解答上偶然发现了解决方案。放入立即窗口的正确命令是
f = {,,MSVCR100D}fopen("foo.txt", "r")
但是,它并没有真正回答这个问题:
- 我仍然不明白这里发生了什么。
- 如何系统地找出任何给定方法的
{,,MSVCR100D}
部分?我知道 MSVCR 版本随系统的不同而变化。我怎样才能找到它? - 谁能解释一下大括号语法,特别是那两个逗号在那里做什么?使用这种语法还有更多隐藏的宝石吗?
I see some related questions have been asked, but they're either too advanced for me to grasp or lacking a step-by-step guide from start to finish (most of them end up being insider talk of their own experiment results). OK here it is, given this simple program:
#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;
}
What it does is basically print itself (assume file name is main.cpp
).
Question
How can I have it print another file, say foobar.txt
without modifying the source code? It has something to do with running it through VS's, stepping through the functions and hijacking the FILE pointer right before fread()
is called. No need to worry about leaking resources by calling fclose()
.
I tried the simple f = fopen("foobar.txt", "r")
which gave
CXX0017: Error: symbol "fopen" not found
Any ideas?
Edit
I found out the solution accidentally on Debugging Mozilla on Windows FAQ. The correct command to put into the Immediate Window is
f = {,,MSVCR100D}fopen("foo.txt", "r")
However, it doesn't really answer this question:
- I still don't understand what is going on here.
- How to systematically find out the
{,,MSVCR100D}
part for any given method? I know the MSVCR version changes from system to system. How can I find that out? - Could anyone explain the curly brace syntax, especially, what are those two commas doing there? Are there more hidden gems using this syntax?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
大括号语法是 VS Context Operator,它大部分都被破坏了 - 正如链接中所详细说明的(或者至少,几乎不是一个隐藏的宝石)。它可用于 VS 表达式求值引擎需要在运行时解析函数的任何地方,例如在监视窗口中求值复合表达式、设置断点或(如您所见)在立即/命令窗口中。
它的第三个参数是二进制文件,其中包含您要调用的函数的实现。对于 CRT 函数(例如 fopen),通常相当于 -
(我似乎记得需要扩展名 - 但也许在 VS2010 中发生了变化)。 “D”表示调试 dll 版本。 VS版本号解码为:VS2005 -> 8、VS2008-> 9、VS2010-> 10.
另请注意,评估引擎具有 各种其他需要注意的问题。
The curly-braces syntax is the VS Context Operator, which is mostly broken - as elaborated at the link (or at least, hardly a hidden gem). It is used anywhere the VS expression-evaluation-engine needs to resolve functions at runtime, e.g. evaluating compound expressions in the watch window, setting breakpoints, or (as you witnessed) in the immediate/command windows.
Its 3rd argument is the binary which includes the implementation of the function you wish to call. For a CRT function such as fopen, that usually amounts to -
(I seem to recall the extension was needed - but maybe that changed in VS2010). The 'D' indicates the debug dll version. The VS version number is decoded as: VS2005 -> 8, VS2008 -> 9, VS2010 -> 10.
Also note the evaluation-engine has various other gotchas to watch out for.
为了补充 Ofek 的出色答案,我发现了一种方法可以系统地找出函数调用属于哪个模块。 (即
MSVCR100D
部分)。fopen
);我相信您可以使用此方法来查找任何类的模块名称。例如,当您正在查看大型代码库并且想要在立即窗口中动态调用某些任意类的方法时,这可能很有用。您或许还可以通过自己调用构造函数来动态创建类的实例。
C++ 不是母语吗?我们几乎感觉就像在一个托管的脚本环境中:P
To supplement Ofek's excellent answer, here is a way I found to systematically find out what module a function call belongs to. (i.e. the
MSVCR100D
part).fopen
);I believe you can use this method to find the module name for any class. This can be useful when for example you're reviewing a large code base and you want to invoke some arbitrary class's method on the fly in the Immediate Window. You can probably also create instances of classes on the fly by calling the constructor yourself.
Now wasn't C++ a native language? We almost feel like in a managed, scripting environment here :P