我始终收到以下错误4的段错误(通过检查https://rgeissert.blogspot.com/p/segmentation-fault-error.html,afaik是空指针取消引用):
Aug 6 11:42:54 mypc kernel: [28532305.723536] myapp-new[14784]: segfault at 18 ip 00007f642c6c5d44 sp 00007ffc6a937700 error 4 in libpthread-2.23.so[7f642c6bc000+18000]
代码如下:
void* request(void* p){
// ... code
}
void Daemon::run(){
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
LOG(INFO) << "daemon running...";
int sockfd = serverSocket.getSocket();
struct pollfd fds[1];
fds[0].fd = sockfd;
fds[0].events = POLLIN | POLLPRI;
pthread_t threads[1];
while (!shutdown_daemon) {
int currNrThreads = activeThreads;
int i = 0;
for (; activeThreads > nrThreads; i++) {
usleep(4000);
}
if (i != 0) {
LOG(INFO) << "too many threads, slept for " << i * 4 << "ms (" << currNrThreads
<< " threads, now " << activeThreads << ")";
}
// wait until there is data to read on the listen socket
//
int retVal = poll(fds, 1, 2000);
if (retVal == -1) {
LOG(WARNING) << "error in poll: " << strerror(errno);
}
if (retVal <= 0) {
continue;
}
// open a socket to communicate with and read the header
//
struct sockaddr_storage clientAddr;
unsigned int clientLen = sizeof(clientAddr);
int connectionID = accept(sockfd, (struct sockaddr*)&clientAddr, &clientLen);
if (connectionID == -1) {
LOG(WARNING) << "accept return -1, error: " << strerror(errno);
continue;
}
// pack the payload into buffer
auto buf = new size_t[2];
buf[0] = (size_t)this;
buf[1] = (size_t)connectionID;
int ret = pthread_create(&threads[0], &attr, &request, (void*)buf);
if (ret != 0) {
LOG(ERROR) << "could not start pthread, ret: '" << ret << "'";
delete[] buf;
continue;
}
// Atomic increment
++activeThreads;
}
LOG(INFO) << "term signal received, waiting child processess to finish";
while (activeThreads > 0) {
LOG(INFO) << "waiting for child processes to finish...";
sleep(1); }
LOG(INFO) << "all child processes are finished";
}
具有以下追溯:
(gdb) bt
#0 __pthread_create_2_1 (newthread=<optimized out>, attr=<optimized out>, start_routine=<optimized out>, arg=<optimized out>) at pthread_create.c:713
#1 0x00000000004621fb in Daemon::run (this=0x7ffe1715d260) at src/daemon/daemon.cpp:992
#2 0x0000000000443842 in main (argc=4, argv=0x7ffe1715d6f8) at src/myapp.cpp:991
(gdb) bt full
#0 __pthread_create_2_1 (newthread=<optimized out>, attr=<optimized out>, start_routine=<optimized out>, arg=<optimized out>) at pthread_create.c:713
stackaddr = <optimized out>
iattr = <optimized out>
default_attr = {schedparam = {__sched_priority = 0}, schedpolicy = 0, flags = -1456592096, guardsize = 16,
stackaddr = 0x409d50 <_GLOBAL__sub_I__ZN4YAML5RegExC2Ev+16>, stacksize = 140729285727984, cpuset = 0x0, cpusetsize = 0}
free_cpuset = <optimized out>
pd = 0x7fb373fff700
retval = <optimized out>
self = <optimized out>
thread_ran = true
__PRETTY_FUNCTION__ = "__pthread_create_2_1"
#1 0x00000000004621fb in Daemon::run (this=0x7ffe1715d260) at src/daemon/daemon.cpp:992
currNrThreads = -1447528544
i = 8
retVal = 0
clientAddr = {ss_family = 2,
__ss_padding = "\336L\177\000\000\001", '\000' <repeats 24 times>, "\260\315\025\027\376\177\000\000\006\000\000\000\000\000\000\000daemon\000\000\b\317\025\027\376\177\000\000\320\315\025\027\376\177\000\000\n\000\000\000\000\000\000\000BackupLock\000\027\376\177\000\000\000\316\025\027\376\177\000\000!\303@\000\000\000\000\000\274\204O\000\000\000\000", __ss_align = 140729285725960}
buf = 0x7fb300000000
clientLen = 32691
connectionID = 3
attr = {__size = "\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\020", '\000' <repeats 37 times>, __align = 0}
__PRETTY_FUNCTION__ = "void Daemon::run()"
sockfd = 16
fds = {{fd = 3, events = 3, revents = 1}}
threads = {140408722028288}
怎么可能?我会理解一些内存不足错误,但是此代码(Ubuntu 16.04, glibc 2.2.3
)中哪里会发生错误4
我们还怀疑硬件问题,因此更换了该计算机上的所有RAM,但问题仍然存在。
对此进行更新:将软件移至另一台计算机(使用glibc 2.26)后,崩溃完全停止了(在相同的负载下)。
答案 0 :(得分:1)
我会尝试替换以下内容:
// pack the payload into buffer
auto buf = new size_t[2];
buf[0] = (size_t)this;
buf[1] = (size_t)connectionID;
结构不错,例如:
struct thread_param
{
Daemon* deamon;
int connectionID;
}
也许我只是偏执狂,但是在以后需要抛弃它的情况下,我不会使用自动声明...
压榨的原因可能很多,而您没有提供全部信息。
request
函数中,并且您没有检查分配是否成功...),我看不到您要删除buf。