【发布时间】:2011-11-18 16:02:20
【问题描述】:
我编写了一个“filemon”实用程序,它基本上记录了一段时间内打开的文件。现在,我的“filemon”实用程序中有这两个功能:
set<wstring> wstrSet;
// callback - get notified by callback filter driver on any file open operation
void CbFltOpenFileN(
CallbackFilter* Sender,
LPWSTR FileName,
ACCESS_MASK DesiredAccess,
WORD FileAttributes,
WORD ShareMode,
DWORD CreateOptions,
WORD CreateDisposition )
{
// don't log for directories
if (FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
return;
}
wstring wstr = FileName;
wstr.append(L"\n");
//wstrSet.insert(wstr); // as soon as I un-comment this line I start getting BSOD in multiple execution of this utility
}
// Read all paths stored in the set and write them into the log file
void WritePathsToLog() {
typedef set<wstring>::const_iterator CI;
printf("\nNo. of files touched ===> %d\n\n", wstrSet.size());
for (CI iter = wstrSet.begin(); iter != wstrSet.end(); iter++) {
fputws((*iter).c_str(), logFile);
}
}
基本上,这段代码的作用是“filemon”实用程序与回调过滤器驱动程序交互,每当文件被任何进程触摸时,驱动程序都会通过 CbFltOpenFileN 函数向“filemon”实用程序报告相应的文件名。
现在的问题是这个 'filemon' 实用程序在 win7 x64 机器 4GB 机器上运行良好,但是一旦我取消注释 CbFltOpenFileN 函数中的最后一行,即开始在集合中插入报告的文件名,然后我开始得到 BSOD,主要是BugCheck 0xCC 有时带有 BugCheck 0x50,这基本上表明“系统正在尝试访问已释放的内存”
附:在具有 8GB RAM 的 win7 x64 上,无论 CbFltOpenFileN 函数中的最后一行是否被注释,我都没有看到任何问题。
目前,'wstrSet' 正在使用默认分配器,所以我需要在声明 set wstrSet 时使用特定的分配器;如果是的话,有人可以告诉我如何以及为什么?
- 让我在这里分享更多信息:
- 我用的是VS2010
- 我的实用程序是针对 x86 平台的 32 位应用程序
- 我使用的文件系统过滤驱动是Eldos corp提供的callabck过滤驱动。
- 现在我正在使用一个生成大量文件的模拟器来测试这个实用程序,然后启动“filemon”实用程序,然后它会触及所有这些文件,最后停止“filemon”实用程序。这个模拟器重复这个过程 25 次。
- 现在,对于最后一行被注释的情况,我创建了 25 次空日志文件,因为我没有在集合中插入任何内容,但“filemon”实用程序也不会导致任何 BSOD
- 但是对于最后一行没有注释的情况,我每次都会使用路径输入创建日志文件,因为现在我在集合中插入路径,但是在最初的几次迭代中,比如第 2 次或第 3 次或第 6 次,它本身就是“filemon”实用程序遇到这种 BSOD 场景。
我很难在调试模式下重现这个问题,因为我的模拟器负责“filemon”实用程序的启动/停止,我需要多次运行它来重现这个问题。
希望这些添加的信息对您有所帮助!!!
感谢和问候, 萨钦
【问题讨论】:
-
您还确定这条确切的行会导致蓝屏死机,即您已经使用调试器逐步完成了您的程序并对其进行了验证?
-
@Kos:代码行不会导致 BSOD,除非它们在内核中运行。现在,如果 OP 正在使用 flakey 驱动程序(比如一些未经充分测试的 RAMFS 文件系统驱动程序可以与所有内存一起工作......),OOM 条件可能会使 that 驱动程序行为不端并抛出在您的桌面上
-
不是我所知道的,这就是我问的原因 - 如果在每个文件打开操作中调用它,从任何进程,wstrSet 对象如何在任何这些地址空间中被访问?
-
您是否碰巧从静态对象的构造函数调用
CbFltOpenFileN(直接或间接)?还是在main开始执行之前调用它? -
不,我不会从任何地方调用它,它是由驱动程序本身调用的回调方法。但是,我的“filemon”实用程序必须向驱动程序注册自身,然后将路径附加到它希望驱动程序监视文件打开操作的驱动程序。完成后,驱动程序开始调用
CbFltOpenFileN方法。换句话说,我的实用程序的第一个主要方法被执行,它告诉驱动程序监视和报告在某个路径上被触摸的文件,最后如果该路径上的任何文件被触摸,驱动程序调用CbFltOpenFileN函数来报告它。