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)
是的,修好了.我为浪费时间而道歉,但感谢大家的帮助.