【问题标题】:malloc / calloc crash on side-thread on LinuxLinux 上的侧线程上的 malloc / calloc 崩溃
【发布时间】:2011-05-24 14:25:56
【问题描述】:

我正在用 C 语言编写一个服务器-客户端应用程序来共享一些信息。服务器以双线程模式工作——主线程等待输入,侧线程响应客户端的请求。客户端也是这样工作的,但它等待用户输入(来自标准输入),如果它收到正确的命令,它会向服务器发送请求并等待响应。等待在处理响应的侧线程中完成。虽然这看起来一切都很好并且适用于基于 Ubuntu 的发行版(我使用 Ultimate Edition 2.7),但它在其他一些发行版上崩溃。这就是发生的事情。

服务器按原样完美运行,但客户端遭受 glibc 检测到 崩溃(我希望我输入正确)。当它收到响应时,它会解析其结构,其中包含:
a) 标题,
b) 一些静态标识符,
c) 包含长度和数据本身的数据部分。

会发生什么:
a) 客户端接收数据包,
b) 客户端检查它的大小(至少 sizeof(header) + sizeof(static_data) + sizeof(length) + data -- 并且数据大小与长度所说的一样大)),
c)创建结构 - 从字符缓冲区转换为上述结构, d) 创建一些其他结构来存储这些结构。

结构被正确解释。我通过服务器接口向客户端发送“固定”结构并打印原始、发送数据和接收信息来测试它。所以事实并非如此。 c) 点一切都很好。

至点 d) 我处理用于接收传入数据包的缓冲区(指定了最大大小并且缓冲区是该大小)。为了存储我得到的结构数据。我这样做:
a) 分配正确大小的新内存
b) 复制数据。

我不讨论方法。只要它有效,一切都很好。但正如我所说,它不在其他发行版上。它在点 a) 中分配内存时 MALLOC 失败。它在所有事情上都失败了。我的猜测是,它可能是另一个发行版上 malloc 和/或 printf 的线程安全问题,但问题是主线程在 scanf(..) 方法上大多空闲。
回到主题:它在任何事情上都失败了:
char* buffer = (char*)malloc(fixed_size * sizeof(char))
STRUCT_T* struct = (STRUCT_T*)malloc(sizeof(STRUCT_T)) 等等。无论我尝试分配什么,它总是抛出 glibc 检测到的错误并且总是指向 malloc 方法(即使它是 calloc)。

这让我想知道这有什么问题?这是我的线程问题。看起来有点像我正在溢出“内存空间”,但我怀疑它总是发生在第一次响应接收时。我会很感激任何帮助,如果需要可以发布更多细节。侧螺纹是可连接的。

我编译的选项:
CC = gcc CFLAGS = -Wall -ansi --pedantic -c -O0 -g -std=c99 -pthread $(CC) $(CFLAGS) server.c -o server.o gcc server.o $(OBJECTS) -o server -pthread -lm
并包含在 client.c 文件中:
sys/fcntl.h netdb.h errno.h stdio.h unistd.h stdlib.h string.h time.h pthread.h math.h

我不是 C 和 Linux 的新手,但我主要在 Windows 和 C++ 上工作,所以这很令人不安。正如我所说,它在我使用的发行版上工作得很好,但在正确解析缓冲区时它在其他发行版上却不行。


提前致谢。

【问题讨论】:

  • 我认为这与线程没有任何直接关系,即使错误代码可能位于您的非主线程之一中。这几乎可以肯定是简单的内存损坏(写入缓冲区末尾)。
  • 而规范的解决方案是在 valgrind 下运行您的程序。很遗憾,您在此处提供的信息不足以让我们给出比这更好的答案。
  • 我无法想象如何。我在堆栈上有一个普通的指针,我尝试动态分配一些东西让它指向。我说的是像 void* a = malloc(1); 这样的正常分配。稍后我将使用 valgrind 完成这项工作。希望能够检测并指定错误。
  • void *a = malloc(1); 是所谓的dummy code,在这里通常不受欢迎。显然,您的实际代码分配了多个字节,使用void * 以外的指针类型,并实际写入分配的内存。

标签: c linux unix crash malloc


【解决方案1】:

当 malloc 崩溃时,通常是因为您之前已经踩到了它用来管理自身(和免费)的数据。在崩溃时很难或不可能诊断,因为问题确实发生在以前的某个时间。正如已经建议的那样,捕获先前内存覆盖发生位置的最佳方法是通过 valgrind、purify、insure++ 等程序运行您的程序。如果您覆盖了不应该覆盖的内容,它将通知您。 valgrind 是免费软件,它可能已经安装了。可以很简单,只需将 valgrind 这个词放在客户调用字符串上的其他所有内容之前。

【讨论】:

  • 我正在清除错误。服务器代码现在没有这些。客户的时间。我知道 malloc 崩溃的原因,但我觉得这很奇怪。可能在缓冲区中到处丢失一个字节。
猜你喜欢
  • 2018-08-01
  • 2019-05-04
  • 1970-01-01
  • 2011-03-21
  • 2011-07-29
  • 2020-10-04
  • 2019-09-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多