不使用printf时出现段错误

4

我正在使用POSIX线程,在程序结束时,我等待加入每个线程。尽管一段时间内运行良好,但在等待线程时代码开始返回奇怪的错误。

pthreads threads[C+P];

for(i = 0; i < (C+P); i++)
{
    printf("%d\n", i);  
    pthread_join(threads[i]);
}

如果我删除printf语句,或者用其他printf语句、延迟或任何其他操作替换它,我仍然会收到一个段错误。我该如何开始调试呢?

我会从使用 gdb 获取程序段错误的堆栈跟踪开始。 - Jamey Sharp
知道threads[]的位置、它所包含的内容(我假设是pthread_t值)、i相对于它在栈中的位置(我知道这样问很奇怪,但你的问题也很奇怪)以及C+P与threads[]的数量大小关系,这些都可能有助于解决问题。目前来看,如果你从片段中删除了for-loop,那么这里面提供的信息就更少了。我们不知道threads[]是动态数组(“pthread_t * threads;”)、固定数组(“pthread_t threads[N];”)等等。你能给我们一些更详细的信息吗? - WhozCraig
3
猜测你的代码其他地方可能存在某种竞态条件。printf() 是控制台 I/O,每次调用都会刷新,速度较慢,掩盖了这种情况。 - millimoose
millimoose: 如果是这样的话,我会期望延迟也能解决问题。WhozCraig: 除了最近的编辑之外,我真的不知道还能给你什么。我正在尝试使用gdb来解决这个问题,但我对它并不熟练。 - SeanVDH
使用fflush替换edit具有相同的效果。你是正确的,我在其他地方确定了一个竞争条件。 - SeanVDH
1个回答

7
插入printf()调用会影响内存布局(因此它可能会纯粹地掩盖一些内存损坏),以及执行时间(您使用线程,因此时间也很重要)。
但是,与其进行任何猜测,不如进行一些常规调试:
  • gdb下运行可执行文件,这样您应该能够看到导致崩溃的确切操作,从哪里调用等。

  • valgrind下运行 - 这个工具可以检测许多常见错误,例如访问已释放的内存块,使用未初始化的变量,超出数组/缓冲区边界等。使用valgrind,很常见就可以立即获得错误的确切位置,我强烈推荐使用!


这不是一个答案,应该是一条评论。 - Jim Garrison

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接