【问题标题】:Invalid write of size 8 during pthread_createpthread_create 期间大小为 8 的无效写入
【发布时间】:2014-06-29 00:59:29
【问题描述】:

我有一个简单的 TCP 服务器应用程序。它由 main 函数、TCP 线程函数和线程定时器(TCP 线程在 45 秒后结束)组成。问题在于创建线程。服务器运行了一段时间,然后突然崩溃。这是我创建线程的方式(在while循环中):

for (i = 0; i < NTHREADS; i++)
    freethreads[i] = i;

clients++;
pthread_mutex_lock(&clientMtx);
tmp.sockfd = new_sockfd;
tmp.threadid = NTHREADS - clients;

pthread_create(&threadid[freethreads[NTHREADS - clients]], &attr, &tcp_main, &tmp);
sleep(0);
pthread_mutex_unlock(&clientMtx);

这里是来自 valgrind 和 helgrind 在 pastebin 的日志:
valgrind
helgrind
我不知道,这部分是什么意思:

==3405== Invalid write of size 8
==3405==    at 0x4E3A52F: pthread_create@@GLIBC_2.2.5 (pthread_create.c:563)
==3405==    by 0x4027DF: main (robot4.c:489)
==3405==  Address 0x8872e9c0 is not stack'd, malloc'd or (recently) free'd

非常感谢您的每一个建议。

编辑:
threadid 和 freethreads 部分:

pthread_t threadid[NTHREADS]; 
int freethreads[NTHREADS];
for (i = 0; i < NTHREADS; i++)
freethreads[i] = i;

【问题讨论】:

  • 显示你对threadid的定义和初始化。
  • 即使使用互斥锁和sleep 调用,将参数传递给线程的方式也不能保证是安全的。相反,我建议您在每个线程的堆上动态分配用于tmp 的结构。一旦线程从结构中保存了数据,他们就可以释放它。
  • 您是否尝试使用 GDB 查看核心转储?它是否为崩溃提供了线索?
  • 是的,我的朋友根据@JoachimPileborg 的帖子发现了这个错误。崩溃是由于我在不同的函数(超时函数)中的错误造成的,该函数使用客户端变量进行操作。你不知道,是否可以删除整个问题?我认为,这对人们来说毫无用处,因为代码不同部分的错误......

标签: c multithreading tcp valgrind


【解决方案1】:

仅根据您在问题中向我们展示的代码,clients 可能会增加到大于NTHREADS,从而导致您对freethreads 数组具有负索引。

在任一方向上超出数组范围的索引都会导致undefined behavior

您需要检查clients 永远不会大于NTHREADS,当然还需要在客户端断开连接时减小它(同时注意它永远不会低于零)。

【讨论】:

  • 每次客户端断开连接时,我都会减少客户端,并以这种方式在 while 循环中检查该变量:pthread_mutex_lock(&amp;clientMtx); if (clients == NTHREADS) pthread_cond_wait(&amp;clientCond, &amp;clientMtx) pthread_mutex_unlock(&amp;clientMtx); 抱歉格式化,我不知道该怎么做...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 2021-12-24
相关资源
最近更新 更多