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

fprintf stderr SEGFULTS在自己的线程中,在主线程中工作

  •  0
  • Bwebb  · 技术社区  · 6 年前

    我建立了一个小的原型测试程序来处理windows性能计数器,一切都正常。我将它移动到我的dll中,我的主程序将加载该dll,并且有一些fprintf(stderr,“sometext”)导致访问冲突。

    我就此进行了调查,没有找到任何令人满意的答案。我知道当它在主线程中运行时工作正常。我假设从我生成的关键线程开始执行性能计数器轮询。

    1. 这种访问违规的原因是什么?它显示“main.exe 0xC00000005中0x7deadbeef处未处理的异常。从0xFbeefdead读取的访问冲突”。
    2. 从单独的线程打印到stderr的适当方式是什么?

    这似乎有点“随机”,因为我在轮询函数的开头有printfs,可以很好地打印。在底部,他们抛出了访问冲突。为什么一些printf/fprintf(stderr)可以正常工作,而另一些却失败了?

    编辑 我使用0作为堆栈大小参数创建线程,该参数应默认为默认堆栈大小。我怀疑我在这条线索上搞砸了,有人对此有什么见解吗? https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createthread

    1 回复  |  直到 6 年前
        1
  •  0
  •   Bwebb    6 年前

    因为我怀疑症状是与printf/fprintfs无关的问题。在程序的早期,我冲刺了许多字符串,这是结构的一部分。我没有将结构成员的大小传递给sprintf,而是传递了整个结构的大小,这导致缓冲区溢出并损坏了不知有多少内存。当这是在一个主线程中时,它没有溢出到足以破坏我的堆栈并导致segfault,但它仍然写过缓冲区。

    由于独立程序中的函数调用较少,因此过度写入堆栈指针的可能性为零,当引入实际程序/dll时,调用层次结构变得非常重要,大量缓冲区溢出肯定会覆盖堆栈指针,因此,地址范围为0x7ABCDEF的线程的printf试图跳转到返回地址0xF1234567,从而导致访问错误。

    我把我的故事贴在这里供将来的读者阅读。如果下一个家伙有类似的问题,这里有一些sprintf_的资源: What is sprintf_s analog of sprintf(newpath, "%s%s",...)?