【发布时间】: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 *以外的指针类型,并实际写入分配的内存。