Moved crashcatcher to a component and also use it in CS

Reworked debugger detection (failed on gdb 7.11), it now uses /proc to detect the debugger
pull/457/head
Doc West 7 years ago committed by Alexander Stillich
parent 8834396cdd
commit 467989cdd5

@ -5,6 +5,9 @@
#include <QLocalSocket> #include <QLocalSocket>
#include <QMessageBox> #include <QMessageBox>
#include <components/crashcatcher/crashcatcher.hpp>
#include <components/fallback/validate.hpp> #include <components/fallback/validate.hpp>
#include <components/nifosg/nifloader.hpp> #include <components/nifosg/nifloader.hpp>
@ -18,12 +21,16 @@
using namespace Fallback; using namespace Fallback;
CS::Editor::Editor () CS::Editor::Editor (int argc, char **argv)
: mSettingsState (mCfgMgr), mDocumentManager (mCfgMgr), : mSettingsState (mCfgMgr), mDocumentManager (mCfgMgr),
mViewManager (mDocumentManager), mPid(""), mViewManager (mDocumentManager), mPid(""),
mLock(), mMerge (mDocumentManager), mLock(), mMerge (mDocumentManager),
mIpcServerName ("org.openmw.OpenCS"), mServer(NULL), mClientSocket(NULL) mIpcServerName ("org.openmw.OpenCS"), mServer(NULL), mClientSocket(NULL)
{ {
// install the crash handler as soon as possible. note that the log path
// does not depend on config being read.
cc_install(argc, argv, (mCfgMgr.getLogPath() / "openmw-cs-crash.log").string());
std::pair<Files::PathContainer, std::vector<std::string> > config = readConfig(); std::pair<Files::PathContainer, std::vector<std::string> > config = readConfig();
setupDataFiles (config.first); setupDataFiles (config.first);

@ -66,7 +66,7 @@ namespace CS
public: public:
Editor (); Editor (int argc, char **argv);
~Editor (); ~Editor ();
bool makeIPCServer(); bool makeIPCServer();

@ -48,7 +48,7 @@ int main(int argc, char *argv[])
#endif #endif
try try
{ {
// To allow background thread drawing in OSG // To allow background thread drawing in OSG
QApplication::setAttribute(Qt::AA_X11InitThreads, true); QApplication::setAttribute(Qt::AA_X11InitThreads, true);
@ -67,7 +67,7 @@ int main(int argc, char *argv[])
application.setWindowIcon (QIcon (":./openmw-cs.png")); application.setWindowIcon (QIcon (":./openmw-cs.png"));
CS::Editor editor; CS::Editor editor(argc, argv);
if(!editor.makeIPCServer()) if(!editor.makeIPCServer())
{ {

@ -11,12 +11,10 @@ if (ANDROID)
set(GAME ${GAME} android_main.c) set(GAME ${GAME} android_main.c)
endif() endif()
if(NOT WIN32 AND NOT ANDROID)
set(GAME ${GAME} crashcatcher.cpp)
endif()
set(GAME_HEADER set(GAME_HEADER
engine.hpp engine.hpp
) )
source_group(game FILES ${GAME} ${GAME_HEADER}) source_group(game FILES ${GAME} ${GAME_HEADER})
add_openmw_dir (mwrender add_openmw_dir (mwrender

@ -1,6 +1,7 @@
#include <iostream> #include <iostream>
#include <components/version/version.hpp> #include <components/version/version.hpp>
#include <components/crashcatcher/crashcatcher.hpp>
#include <components/files/configurationmanager.hpp> #include <components/files/configurationmanager.hpp>
#include <components/files/escape.hpp> #include <components/files/escape.hpp>
#include <components/fallback/validate.hpp> #include <components/fallback/validate.hpp>
@ -24,18 +25,6 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
#if (defined(__APPLE__) || (defined(__linux) && !defined(ANDROID)) || (defined(__unix) && !defined(ANDROID)) || defined(__posix))
#define USE_CRASH_CATCHER 1
#else
#define USE_CRASH_CATCHER 0
#endif
#if USE_CRASH_CATCHER
#include <csignal>
extern int cc_install_handlers(int argc, char **argv, int num_signals, int *sigs, const char *logfile, int (*user_info)(char*, char*));
extern int is_debugger_attached(void);
#endif
/** /**
* Workaround for problems with whitespaces in paths in older versions of Boost library * Workaround for problems with whitespaces in paths in older versions of Boost library
*/ */
@ -339,18 +328,7 @@ int main(int argc, char**argv)
std::cerr.rdbuf (&cerrsb); std::cerr.rdbuf (&cerrsb);
#endif #endif
cc_install(argc, argv, (cfgMgr.getLogPath() / "crash.log").string());
#if USE_CRASH_CATCHER
// Unix crash catcher
if ((argc == 2 && strcmp(argv[1], "--cc-handle-crash") == 0) || !is_debugger_attached())
{
int s[5] = { SIGSEGV, SIGILL, SIGFPE, SIGBUS, SIGABRT };
cc_install_handlers(argc, argv, 5, s, (cfgMgr.getLogPath() / "crash.log").string().c_str(), NULL);
std::cout << "Installing crash catcher" << std::endl;
}
else
std::cout << "Running in a debugger, not installing crash catcher" << std::endl;
#endif
#ifdef __APPLE__ #ifdef __APPLE__
boost::filesystem::path binary_path = boost::filesystem::system_complete(boost::filesystem::path(argv[0])); boost::filesystem::path binary_path = boost::filesystem::system_complete(boost::filesystem::path(argv[0]));

@ -204,4 +204,4 @@ macro (copy_all_resource_files source_dir destination_dir_base destination_dir_r
get_filename_component(filename ${f} NAME) get_filename_component(filename ${f} NAME)
copy_resource_file("${source_dir}/${f}" "${destination_dir_base}" "${destination_dir_relative}/${filename}") copy_resource_file("${source_dir}/${f}" "${destination_dir_base}" "${destination_dir_relative}/${filename}")
endforeach (f) endforeach (f)
endmacro (copy_all_resource_files) endmacro (copy_all_resource_files)

@ -145,6 +145,12 @@ add_component_dir (fallback
fallback validate fallback validate
) )
if(NOT WIN32 AND NOT ANDROID)
add_component_dir (crashcatcher
crashcatcher
)
endif()
set (ESM_UI ${CMAKE_SOURCE_DIR}/files/ui/contentselector.ui set (ESM_UI ${CMAKE_SOURCE_DIR}/files/ui/contentselector.ui
) )

@ -14,7 +14,11 @@
#include <stdbool.h> #include <stdbool.h>
#include <sys/ptrace.h> #include <sys/ptrace.h>
#include <string> #include <iostream>
#include <boost/filesystem/fstream.hpp>
namespace bfs = boost::filesystem;
#include <SDL_messagebox.h> #include <SDL_messagebox.h>
@ -454,19 +458,31 @@ int cc_install_handlers(int argc, char **argv, int num_signals, int *signals, co
return retval; return retval;
} }
static bool is_debugger_present()
// gdb apparently opens FD(s) 3,4,5 (whereas a typical prog uses only stdin=0, stdout=1,stderr=2)
bool
is_debugger_attached(void)
{ {
bool rc = false; bfs::ifstream file((bfs::path("/proc/self/status")));
FILE *fd = fopen("/tmp", "r"); while (!file.eof())
if (fileno(fd) > 5)
{ {
rc = true; std::string word;
file >> word;
if (word == "TracerPid:")
{
file >> word;
return word != "0";
}
} }
return false;
}
fclose(fd); void cc_install(int argc, char **argv, const std::string &crashLogPath)
return rc; {
if ((argc == 2 && strcmp(argv[1], "--cc-handle-crash") == 0) || !is_debugger_present())
{
int s[5] = { SIGSEGV, SIGILL, SIGFPE, SIGBUS, SIGABRT };
if (cc_install_handlers(argc, argv, 5, s, crashLogPath.c_str(), NULL) == -1)
{
std::cerr << "Installing crash handler failed" << std::endl;
} else
std::cout << "Crash handler installed" << std::endl;
}
} }

@ -0,0 +1,18 @@
#ifndef CRASHCATCHER_H
#define CRASHCATCHER_H
#include <string>
#if (defined(__APPLE__) || (defined(__linux) && !defined(ANDROID)) || (defined(__unix) && !defined(ANDROID)) || defined(__posix))
#define USE_CRASH_CATCHER 1
#else
#define USE_CRASH_CATCHER 0
#endif
#if USE_CRASH_CATCHER
extern void cc_install(int argc, char **argv, const std::string &crashLogPath);
#else
inline void cc_install(int, char **) { return 0; }
#endif
#endif
Loading…
Cancel
Save