fprintf stderr segfaults在其自己的线程中运行,在主线程中

时间:2019-01-30 04:54:19

标签: c windows printf

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

我在SO上对此进行了调查,但未找到满意的答案。我知道它在主线程中运行时效果很好。我假设它是从产生的TIME_CRITICAL线程执行性能计数器轮询的。

  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 个答案:

答案 0 :(得分:0)

由于我怀疑症状是与printf / fprintfs无关的问题。在程序的早期,我冲刺了许多字符串,这是结构的一部分。我没有将struct成员的大小传递给sprintf,而是传递了整个struct的大小,这使我溢出了一个缓冲区,使上帝知道多少内存。当它在一个主线程中时,它没有溢出到足以炸毁我的堆栈并引起段错误的程度,但是它仍然写通过了缓冲区。

由于独立程序中的函数调用次数较少,因此覆盖堆栈指针的机会为零,因此当将其放入真实程序/ dll中时,调用层次结构变得很简单,并且大量缓冲区溢出肯定会覆盖堆栈指针,因此来自地址范围为0x7ABCDEF的线程中的printf尝试跳转到返回地址0xF1234567,从而导致访问无效。

我在这里写了我的故事给以后的读者。如果下一个家伙有类似问题,这是一些sprintf_s资源: What is sprintf_s analog of sprintf(newpath, "%s%s",...)?