void CMainFrame::OnSaveListLog() { CString szFilter = "日志文件(*.txt)|*.txt|"; CFileDialog m_filedialog(FALSE,NULL,"pslog.txt", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter,this); if(m_filedialog.DoModal()!=IDOK) return; CFile m_File(m_filedialog.GetPathName(), CFile::modeCreate|CFile::modeWrite); int nCount = pEventView->GetListCtrl().GetSelectedCount(); for(int i = 0; i < pEventView-> GetListCtrl().GetItemCount(); i++) { char m_Text[512] = {0}; sprintf(m_Text,"发生时间:%s 事件内容:%s\r\n", pEventView->GetListCtrl().GetItemText(i,0), pEventView->GetListCtrl().GetItemText(i,1)); m_File.Write(m_Text,strlen(m_Text)); } m_File.Close(); }
/*! * \brief Obtain a backtrace and print it to stdout. * * If GDB can be used to get a backtrace then we use it, otherwise and only * if TA3D_BUILTIN_BACKTRACE_SUPPORT is defined, a backtrace is obtained * then writen into a log file. It will be displayed in stdout when gdb is missing. * After this call, the program will exit with a exit status code equals * to `-1`. * * \param signum Which signal was received */ void backtrace_handler (int signum) { // Some functions called at exit may crash, so we must disable signals in order // to prevent overwriting a useful log clear_signals(); // Get TA3D's PID pid_t mypid = getpid(); // Try to get a stack trace from GDB String::Vector threads; TA3D::System::run_command(String("gdb --pid=") << mypid << " -ex \"info threads\" --batch").split(threads, "\n"); if (!threads.empty()) { String cmd; cmd << "gdb --pid=" << mypid << " -ex \"info threads\""; for(size_t i = 0 ; i < threads.size() ; ++i) { String &line = threads[i]; if (line.startsWith('[') || line.startsWith("0x") || line.startsWith('#')) continue; if (line.startsWith('*')) { line[0] = ' '; line.trimLeft(' '); } const int id = line.to<int>(); if (id <= 0) continue; cmd << " -ex \"thread " << id << "\" -ex bt"; } cmd << " --batch"; const String trace = TA3D::System::run_command(cmd); if (!trace.empty()) { bug_reporter(trace); exit(-1); } } // If GDB is not available or returned an error we must find another way ... this is now platform dependent # ifdef TA3D_BUILTIN_BACKTRACE_SUPPORT // Retrieving a backtrace void *array[400]; int size = backtrace (array, 400); char** strings = backtrace_symbols(array, size); // Try to log it Yuni::Core::IO::File::Stream m_File(String(TA3D::Paths::Logs) << "backtrace.txt", Yuni::Core::IO::OpenMode::write); if(m_File.opened()) { m_File << "received signal " << strsignal( signum ) << "\n"; m_File << "Obtained " << size << " stack frames.\n"; for (int i = 0; i < size; ++i) m_File << strings[i] << "\n"; m_File.flush(); m_File.close(); printf("received signal %s\n", strsignal( signum )); printf ("Obtained %d stack frames.\n", static_cast<int>(size)); for (int i = 0; i < size; ++i) printf ("%s\n", strings[i]); String szErrReport; szErrReport << "An error has occured.\nDebugging information have been logged to:\n" << TA3D::Paths::Logs << "backtrace.txt\nPlease report to our forums (http://www.ta3d.org/)\nand keep this file, it'll help us debugging.\n"; criticalMessage(szErrReport); } else { // The file is not opened // The backtrace will be directly to stdout instead. printf("received signal %s\n", strsignal(signum)); printf("couldn't open file for writing!!\n"); printf ("Obtained %d stack frames.\n", static_cast<int>(size)); for (int i = 0; i < size; ++i) printf ("%s\n", strings[i]); } free(strings); # else // ifdef TA3D_BUILTIN_BACKTRACE_SUPPORT // The backtrace support is disabled: warns the user String szErrReport = "An error has occured.\nDebugging information could not be logged.\nPlease report to our forums (http://www.ta3d.org/) so we can fix it."; criticalMessage(szErrReport); # endif // ifdef TA3D_BUILTIN_BACKTRACE_SUPPORT exit(-1); }