当我的应用程序尝试将文本写入文件时,我正面临核心转储。它正在使用代码中所示的字符串操作。当多个线程尝试调用此函数并尝试写入日志文件时,我的应用程序正在转储核心。我已经通过不同的论坛,并试图搜索字符串赋值中的任何问题。我已经看到我们中的一些人已经对该字符串赋值语句进行了评论,因为它不适合使用。而是使用字符串成员函数。
功能:
void Debug::writeToFile()
{
if(_ptrMutex == NULL)
_ptrMutex = new Mutex();
_ptrMutex->getLock();
write(_fd,_cacheStr.c_str(),_cacheStr.size());
_cacheStr = ""; //flush the write string
_ptrMutex->releaseLock();
}
cacheWriteString
bool Debug::cacheWriteString(string strIn)
{
if(_ptrMutex == NULL)
_ptrMutex = new CndMutex();
_ptrMutex->getLock();
char timeStamp[100];
struct timeval tv;
struct tm tm;
if (gettimeofday(&tv, NULL)==0 && localtime_r((time_t*)&(tv.tv_sec), &tm)) {
int ret = strftime(timeStamp,sizeof(timeStamp),"%F-%T",&tm);
snprintf(timeStamp+ret, sizeof(timeStamp)-ret, ".%03ld", tv.tv_usec/1000);
} else
Time::getTimeStamp(timeStamp,100);
_cacheStr = _cacheStr + "[" + timeStamp + "] " + strIn;
if(_cacheStr.size() >= _maxCacheSize)
{
_ptrMutex->releaseLock();
return true;
}
_ptrMutex->releaseLock();
return false;
}
此功能称为
void Debug::LOG_PRINT_ERROR(char* ptrFormat,...)
{
va_list argList;
va_start(argList,ptrFormat);
if(_logType == CONSOLE_LOG) //console log
{
cout<<"#### [ERROR] ";
vprintf(ptrFormat,argList);
cout<<endl;
}
else if(_logType == SYS_LOG)// [syslog]
{
syslog(LOG_ERR,"%s","[ERROR]####");
vsyslog(LOG_ERR,ptrFormat,argList);
}
else if(_logType == FILE_LOG)
{
char str[1024];
//SBYTE4 ret = vsprintf(str,ptrFormat,argList);
SBYTE4 ret = vsnprintf(str,1023,ptrFormat,argList);
str[1023]='\0';
if(ret > -1)
{
string dataStr = "[ERROR]####";
dataStr = dataStr +str+"\n";
if(cacheWriteString(dataStr))
{
if(chkFile() == DIM_PASS)
{
writeToFile();
}
else
{
cout<<"#### LOG_ERROR() Unable to Write Data To File: "<<_fileName <<endl;
}
}
}
else
{
cout<<"#### LOG_ERROR() Output Error Is Encountered: "<<_fileName <<endl;
}
}
va_end(argList);
}
核心转储详情如下:
Thread 1 (Thread 8426):
#0 0x00a2a402 in __kernel_vsyscall ()
#1 0x0072bdf0 in raise () from /lib/libc.so.6
#2 0x0072d701 in abort () from /lib/libc.so.6
#3 0x0545651a in ?? () from /usr/lib/libstdc++.so.6
#4 0x05456552 in std::terminate() () from /usr/lib/libstdc++.so.6
#5 0x0545668a in __cxa_throw () from /usr/lib/libstdc++.so.6
#6 0x053ed1ef in std::__throw_length_error(char const*) () from /usr/lib/libstdc++.so.6
#7 0x0543211d in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) () from /usr/lib/libstdc++.so.6
#8 0x05433e28 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_mutate(unsigned int, unsigned int, unsigned int) () from /usr/lib/libstdc++.so.6
#9 0x05433fca in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_replace_safe(unsigned int, unsigned int, char const*, unsigned int) () from /usr/lib/libstdc++.so.6
#10 0x05434065 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::assign(char const*, unsigned int) () from /usr/lib/libstdc++.so.6
#11 0x0815e9a8 in Debug::writeToFile() ()
#12 0x08161866 in Debug::LOG_PRINT_ERROR(char*, ...) ()
#13 0x0812bcc6 in DimInternalMsgHandler::handlePeerStatusIndication(DimPeerStatusInd*) ()
#14 0x0812c52a in DimInternalMsgHandler::handleInternalMessage(unsigned char*, int) ()
#15 0x0812aa05 in DimDanIfController::handleInMessage(NwPacket&) ()
#16 0x081ab28f in WorkerThreadPool::onEvent(int, nxs_util::EventMessage64*) ()
#17 0x0021dd94 in nxs_util::EventHandler64::workerProc(int) () from /home/nextgen/NXS/lib/libnxsutil.so
#18 0x001c193e in nxs_util::WorkerThread::run() () from /home/nextgen/NXS/lib/libnxsutil.so
#19 0x001c5b36 in nxs_util::Thread::__Thread_run(void*) () from /home/nextgen/NXS/lib/libnxsutil.so
#20 0x0087f832 in start_thread () from /lib/libpthread.so.0
#21 0x007d4e0e in clone () from /lib/libc.so.6
我们怀疑是否存在&lt; _cacheStr =“”;&gt;的问题我们在代码中使用的语句。我们正在考虑改为_cacheStr.clear();但我们现在无法重现这个核心。
如果有人对此有所了解或面对它,请告诉我们。
非常感谢您的投入。
答案 0 :(得分:1)
这看起来真的非常狡猾:
if(_ptrMutex == NULL)
_ptrMutex = new Mutex();
如果两个线程进入此块并动态创建自己的互斥锁怎么办?是否有任何理由不能在初始化时创建单个互斥锁并避免“创建互斥”竞争条件?
答案 1 :(得分:0)
如果任何其他线程无法访问_cacheStr
(即使只是检查它),而_ptrMutex
未被保留,则很容易导致此类崩溃。
答案 2 :(得分:0)
我看到函数writeToFile存在锁定,而cacheStr应该是一个全局变量,但是我没有看到函数cacheWriteString,所以我认为它是cacheStr变量的竞争条件,它不受保护函数cacheWriteString。 2个线程可以同时访问/修改字符串。