线程C客户端 - 服务器聊天应用程序中SIGSEGV的未知原因

Sho*_*nja 0 c sockets gdb client-server pthreads

我是软件工程专业的三年级大学生,参加过操作系统课程.

我一直在使用pthreads和套接字在C中使用客户端 - 服务器聊天应用程序.我一直在尝试使用pthread来提升客户端处理的并发性,而不会产生分叉的开销.(如果重要的话,我正在开发Ubuntu 11.04 x86).

而不是存储的一切,静态或全局/局部变量,我创建了两个结构化的数据类型,serverInfo_t并且clientInfo_t,其存储互斥,文件描述符,连接标志,和其他这样的信息.客户端列表实现为存储在serverInfo_t其中的简单单链表,在修改期间锁定和解锁.

在启动服务器应用程序时,我首先调用createServer(),它建立服务器,并最终启动一个子线程,其职责是监听新连接.此函数返回指向新分配serverInfo_t实例的指针,然后将其传递给调用createClient(serverInfo_t* pServer, int out_fd)以创建"admin"客户端,从而允许服务器本身用作客户端.这是我遇到问题的地方,因为它似乎一旦调用它就会产生段错误createClient().(一些修剪过的代码在下面:)

int main(int argc, char** argv)
{
    // ...
    // Get listenPort from argv[1].

    // Initialize the server.
    serverInfo_t* pServer = createServer(listenPort);

    // If createServer() failed, exit.
    if (!pServer) {
        fatal_error("ERROR: Unable to create server!"); // exit program
    }

    // Create and register the admin client.
    clientInfo_t* pAdmin = createClient(pServer, STDOUT_FILENO); // Outputs directly to stdout

    // ...
}
Run Code Online (Sandbox Code Playgroud)

在使用gdb调试程序时,我正在遍历main()并注意到一些有趣的输出:

(gdb) n
22      serverInfo_t* pServer = createServer(listenPort);
(gdb) n
[New Thread 0xb7e53b70 (LWP 7986)]
25      if (!pServer) {
(gdb) n
30      clientInfo_t* pAdmin = createClient(pServer, FD_STDOUT);
(gdb) n
server4: malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *)
&((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) &&
old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof
(struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 *
(sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end &
pagemask) == 0)' failed.

Program received signal SIGABRT, Aborted.
0xb7fe1424 in __kernel_vsyscall ()
(gdb) n
Single stepping until exit from function __kernel_vsyscall,
which has no line number information.
[Thread 0xb7e53b70 (LWP 7986) exited]

Program terminated with signal SIGABRT, Aborted.
The program no longer exists.
(gdb)
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?它看起来好像程序完全跳过了对createServer()的调用,即使NULL检查已通过.GDB是否拒绝进入createServer()函数,还是由于某些编译器优化问题而被简单地绕过?如果是这样,那么[New Thread 0xb7e53b70 (LWP 7986)]输出是什么?究竟是什么导致了一个失败的断言malloc.c呢?

如果您能提供此问题,我将不胜感激.如果我的方法或我提供的信息有问题,请告诉我.我愿意在必要时发布我的完整Makefile和源代码,尽管需要一些修改(即更改Makefile的$(OUTDIR)变量)来运行makefile.

编辑:我想我找到了问题的原因.

createClient():

// ...
clientInfo_t* client = (clientInfo_t*)malloc(sizeof(clientInfo_t*)); // Accidental typo.
Run Code Online (Sandbox Code Playgroud)

固定:

// ...
clientInfo_t* client = (clientInfo_t*)malloc(sizeof(clientInfo_t)); 
Run Code Online (Sandbox Code Playgroud)

是的,修好了.我为浪费时间而道歉,但感谢大家的帮助.

cha*_*m15 5

这看起来像是内存错误.尝试通过valgrind运行它:valgind --tool=memcheck [COMMAND]

欲了解更多信息,请访问Valgrind网站.