我正在编写套接字程序并在线程中接收消息。但是我遇到了分段错误。 当我在没有启动线程的情况下直接收到时,没有这样的问题(在注释部分中显示)。
在下面的代码中我直接收到并发送给客户端。代码的部分如下所示:
if (acceptor->start() == 0)
{
while (1)
{
stream = acceptor->accept();
if (stream != NULL)
{
/*
ssize_t len;
char line[256];
while ((len = stream->receive(line, sizeof(line))) > 0) {
line[len] = 0;
printf("received - %s\n", line);
stream->send(line, len);
*/
pthread_t sniffer_thread;
if( pthread_create( &sniffer_thread, NULL, connection_handler,NULL) < 0)
{
perror("could not create thread");
return 1;
}
//Now join the thread , so that we dont terminate before the thread
pthread_join( sniffer_thread , NULL);
}
delete stream;
}
}
exit(0);
现在,我在线程函数中收到相同的内容。它显示了分段错误。
代码如下所示。
void *connection_handler(void *arg)
{
TCPStream* stream = NULL;
ssize_t len;
char line[256];
while ((len = stream->receive(line, sizeof(line))) > 0)
{
line[len] = 0;
printf("received - %s\n", line);
stream->send(line, len);
}
}
Valgrind输出的一部分是
==5163== Memcheck, a memory error detector
==5163== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==5163== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==5163== Command: ./appdownload 9999 192.5.60
==5163==
==5163== Thread 2:
==5163== Invalid read of size 4
==5163== at 0x401975: TCPStream::receive(char*, unsigned long, int) (tcpstream.cpp:30)
==5163== by 0x40177B: connection_handler(void*) (appdownload.cpp:68)
==5163== by 0x4E3F181: start_thread (pthread_create.c:312)
==5163== by 0x566947C: clone (clone.S:111)
==5163== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==5163==
==5163==
==5163== Process terminating with default action of signal 11 (SIGSEGV)
==5163== Access not within mapped region at address 0x0
==5163== at 0x401975: TCPStream::receive(char*, unsigned long, int) (tcpstream.cpp:30)
==5163== by 0x40177B: connection_handler(void*) (appdownload.cpp:68)
==5163== by 0x4E3F181: start_thread (pthread_create.c:312)
==5163== by 0x566947C: clone (clone.S:111)
==5163== If you believe this happened as a result of a stack
==5163== overflow in you`enter code here`r program's main thread (unlikely but
==5163== possible), you can try to increase the size of the
==5163== main thread stack using the --main-stacksize= flag.
==5163== The main thread stack size used in this run was 8388608.
答案 0 :(得分:4)
TCPStream* stream = NULL; // HERE
ssize_t len;
char line[256];
while ((len = stream->receive(line, sizeof(line))) > 0) // HERE
您在receive
指针上调用NULL
。 Valgrind告诉你:
==5163== Thread 2:
==5163== Invalid read of size 4
==5163== at 0x401975: TCPStream::receive(char*, unsigned long, int) (tcpstream.cpp:30) // HERE
==5163== by 0x40177B: connection_handler(void*) (appdownload.cpp:68)
==5163== by 0x4E3F181: start_thread (pthread_create.c:312)
==5163== by 0x566947C: clone (clone.S:111)
==5163== Address 0x0 is not stack'd, malloc'd or (recently) free'd
// ^- HERE
如果需要将TCPStream*
从主线程传递到新线程函数,可以使用pthread_create
的第4个参数:
pthread_create()函数在调用中启动一个新线程 处理。新线程通过调用start_routine()开始执行; arg作为start_routine()的唯一参数传递。 (来源:
man pthread_create
)
主线程:
TCPStream *stream = acceptor->accept();
(...)
pthread_create( &sniffer_thread, NULL, connection_handler, stream)
// ^^^^^^
工作人员主题:
void *connection_handler(void *arg)
{
TCPStream* stream = (TCPStream *)arg;
// ^^^^^^^^^^^^^^^^
答案 1 :(得分:1)
在你展示了你的valgrind跟踪之后,显然你只是在空指针上调用receive
。
char line[256]; // 256 bytes space
while ((len = stream->receive(line, sizeof(line))) > 0) // receive up to 256 bytes
{
line[len] = 0; // put 257th byte in
我猜你可以为0
再使用一个字节 - 尝试最多接收sizeof(line)-1
。
或者只使用std::vector
,然后使用push_back
那个0。