【问题标题】:could stl set::insert cause BSOD?stl set::insert 会导致蓝屏吗?
【发布时间】: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 函数来报告它。

标签: c++ stl set


【解决方案1】:

如果你CbFltOpenFileN是一个回调函数,这是否意味着它有异步调用?在这种情况下,您可能希望使用互斥锁来保护全局变量 (wstrSet)...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多