瀏覽代碼

为程序增加崩溃检测,并生成奔溃文件!

lwk 18 小時之前
父節點
當前提交
914db37b20

+ 448 - 138
DrvProc/CcosProc/AutoDmp/AutoDmp.cpp

@@ -1,173 +1,483 @@
-#include "StdAfx.h"
 #include "AutoDmp.h"
-
-#include <string>
+#include <iostream>
 #include <sstream>
-
-//-----------------dmp文件生成相关--------------------------------------------
-using namespace std;
-
-#define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS        (0x00000004)
-#define MiniDumpWithThreadInfo 0x1000
-
-typedef BOOL(WINAPI *PGetModuleHandleEx)(DWORD dwFlags, LPCTSTR lpModuleName, HMODULE *phModule);
-
-string GetProcessDirectoryDump()
-{
-	string ret = "";
-	char szFilename[MAX_PATH] = { 0 };
-	DWORD res = GetModuleFileNameA(0, szFilename, MAX_PATH);
-	if (res == 0)
-	{
-		return ret;
-	}
-
-	string fullpath = szFilename;
-	string::size_type firstHit = fullpath.find_last_of('\\');
-	if (firstHit == string::npos || firstHit == 0)
-	{
-		return ret;
-	}
-
-	ret = fullpath.substr(0, firstHit);//kick last \
-
-	return ret;
+#include <fstream>
+#include <iomanip>
+#include <chrono>
+#include <algorithm>
+#include <vector>
+#include <cstring>
+#include <ctime>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <errno.h>
+#include <dlfcn.h>
+
+// 闈欐€佹垚鍛樺垵濮嬪寲
+AutoDmp* AutoDmp::instance_ = nullptr;
+
+// Linux 淇″彿澶勭悊鍒楄〃
+const int AutoDmp::handledSignals_[] = {
+    SIGSEGV,  // 娈甸敊璇�
+    SIGABRT,  // 寮傚父缁堟�
+    SIGFPE,   // 娴�偣寮傚父
+    SIGILL,   // 闈炴硶鎸囦护
+    SIGBUS,   // 鎬荤嚎閿欒�
+    SIGSYS,   // 绯荤粺璋冪敤閿欒�
+    SIGPIPE,  // 绠¢亾閿欒�
+    SIGQUIT   // 閫€鍑轰俊鍙�
+};
+
+const size_t AutoDmp::handledSignalCount_ = sizeof(handledSignals_) / sizeof(handledSignals_[0]);
+
+// 鏋勯€犲嚱鏁�
+AutoDmp::AutoDmp(const CrashConfig& config) : config_(config) {
+    if (instance_ == nullptr) {
+        instance_ = this;
+        if (initializeHandlers()) {
+            initialized_.store(true);
+        }
+    }
 }
 
+// 鏋愭瀯鍑芥暟
+AutoDmp::~AutoDmp() {
+    if (instance_ == this) {
+        cleanupHandlers();
+        instance_ = nullptr;
+        initialized_.store(false);
+    }
+}
 
-VOID CreateDump(struct _EXCEPTION_POINTERS *pExceptionPointers)
-{
-	//收集信息
-	string strBuild;
-
-	unsigned int ret1 = 0;
-
-	HANDLE hDumpFile;
-
-
-
-	std::stringstream strm;
-	strm << "Build: " << __DATE__ << " " << __TIME__;
-	strm >> strBuild;
-
-	//strBuild.Format(L"Build: %s %s", __DATE__, __TIME__);
-	string strError;
-	HMODULE hModule;
-	char szModuleName[MAX_PATH] = { 0 };
-
+// Linux 淇″彿澶勭悊鍣�
+void AutoDmp::signalHandler(int sig, siginfo_t* info, void* context) {
+    // 闃叉�閲嶅叆
+    static volatile sig_atomic_t handling = 0;
+    if (handling || !instance_ || instance_->crashInProgress_.exchange(true)) {
+        return;
+    }
+    handling = 1;
+
+    const CrashConfig* config = getInstanceConfig();
+    if (!config) {
+        // 鎭㈠�榛樿�澶勭悊骞堕噸鏂拌Е鍙�
+        signal(sig, SIG_DFL);
+        raise(sig);
+        return;
+    }
+
+    // 浣跨敤寮傛�瀹夊叏鐨勬柟寮忚緭鍑哄熀鏈�俊鎭�
+    if (config->enableConsoleOutput) {
+        safeWriteToFd(STDERR_FILENO, "\n*** LINUX CRASH DETECTED ***\n");
+        safeWriteToFd(STDERR_FILENO, "Signal: ");
+        safeWriteNumber(STDERR_FILENO, sig);
+        safeWriteToFd(STDERR_FILENO, " (");
+        safeWriteToFd(STDERR_FILENO, getSignalName(sig).c_str());
+        safeWriteToFd(STDERR_FILENO, ")\n");
+
+        if (info->si_addr) {
+            safeWriteToFd(STDERR_FILENO, "Fault Address: ");
+            safeWritePointer(STDERR_FILENO, info->si_addr);
+            safeWriteToFd(STDERR_FILENO, "\n");
+        }
+
+        safeWriteToFd(STDERR_FILENO, "Process ID: ");
+        safeWriteNumber(STDERR_FILENO, getpid());
+        safeWriteToFd(STDERR_FILENO, "\n");
+
+        safeWriteToFd(STDERR_FILENO, "Thread ID: ");
+        safeWriteNumber(STDERR_FILENO, syscall(SYS_gettid));
+        safeWriteToFd(STDERR_FILENO, "\n");
+
+        // 杈撳嚭璋冪敤鏍堝埌stderr锛堝紓姝ュ畨鍏�級
+        if (config->enableBacktrace) {
+            safeWriteToFd(STDERR_FILENO, "\nBacktrace:\n");
+            void* frames[128];
+            int numFrames = backtrace(frames, 128);
+            if (numFrames > 0) {
+                backtrace_symbols_fd(frames, numFrames, STDERR_FILENO);
+            }
+        }
+
+        safeWriteToFd(STDERR_FILENO, "****************************\n\n");
+    }
+
+    // 璁剧疆 core dump
+    if (config->enableCoreDump) {
+        setupCoreDump();
+    }
+
+    // 鎭㈠�榛樿�淇″彿澶勭悊骞堕噸鏂拌Е鍙�
+    struct sigaction sa;
+    sa.sa_handler = SIG_DFL;
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = 0;
+    sigaction(sig, &sa, nullptr);
+
+    // 濡傛灉涓嶆槸鍦ㄥ紓姝ュ畨鍏ㄦā寮忥紝灏濊瘯鍐欏叆璇︾粏鏃ュ織
+    if (!config->asyncSafeOnly) {
+        try {
+            // 鏀堕泦璇︾粏宕╂簝淇℃伅
+            CrashInfo crashInfo;
+            crashInfo.timestamp = getCurrentTimestamp();
+            crashInfo.processName = getProcessName();
+            crashInfo.processId = getpid();
+            crashInfo.threadId = syscall(SYS_gettid);
+            crashInfo.buildInfo = std::string(__DATE__) + " " + __TIME__;
+            crashInfo.signalNumber = sig;
+            crashInfo.signalName = getSignalName(sig);
+            crashInfo.faultAddress = info->si_addr;
+            crashInfo.signalDescription = getSignalDescription(sig, info);
+            crashInfo.backtrace = getBacktrace(context, config->maxBacktraceDepth);
+
+            // 纭�繚鐩�綍瀛樺湪
+            createDirectory(config->crashDirectory);
+
+            // 鍐欏叆璇︾粏鏃ュ織
+            if (config->enableLogFile) {
+                std::string logFileName = "crash_" + crashInfo.timestamp + ".log";
+                std::string logPath = config->crashDirectory + "/" + logFileName;
+                writeCrashLog(crashInfo, logPath);
+                cleanupOldFiles(config->crashDirectory, config->maxCrashFiles);
+            }
+
+            // 杈撳嚭璇︾粏淇℃伅鍒版帶鍒跺彴
+            if (config->enableDetailedInfo && config->enableConsoleOutput) {
+                outputDetailedInfo(crashInfo);
+            }
+        } catch (...) {
+            // 鍦ㄤ俊鍙峰�鐞嗗櫒涓�笉鎶涘嚭寮傚父
+            safeWriteToFd(STDERR_FILENO, "Warning: Failed to write detailed crash log\n");
+        }
+    }
+
+    // 瑙﹀彂榛樿�澶勭悊锛堢敓鎴恈ore dump骞剁粓姝㈣繘绋嬶級
+    raise(sig);
+}
 
-	GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)pExceptionPointers->ExceptionRecord->ExceptionAddress, &hModule);
-	GetModuleFileName(hModule, szModuleName, ARRAYSIZE(szModuleName));
+// 寮傛�瀹夊叏鐨勫啓鍏ュ嚱鏁�
+void AutoDmp::safeWriteToFd(int fd, const char* msg) {
+    if (msg) {
+        size_t len = strlen(msg);
+        write(fd, msg, len);
+    }
+}
 
+void AutoDmp::safeWriteNumber(int fd, long number) {
+    char buffer[32];
+    char* p = buffer + sizeof(buffer) - 1;
+    *p = '\0';
 
-	strm.clear();
-	strm << szModuleName << ", " << pExceptionPointers->ExceptionRecord->ExceptionCode << ", " << pExceptionPointers->ExceptionRecord->ExceptionFlags << ", " << pExceptionPointers->ExceptionRecord->ExceptionAddress;
-	strm >> strError;
+    bool negative = number < 0;
+    if (negative) number = -number;
 
-	//生成 mini crash dump
-	BOOL bMiniDumpSuccessful;
+    if (number == 0) {
+        *--p = '0';
+    } else {
+        while (number > 0) {
+            *--p = '0' + (number % 10);
+            number /= 10;
+        }
+    }
 
-	DWORD dwBufferSize = MAX_PATH;
-	SYSTEMTIME stLocalTime;
-	MINIDUMP_EXCEPTION_INFORMATION ExpParam;
-	GetLocalTime(&stLocalTime);
+    if (negative) {
+        *--p = '-';
+    }
 
-	char szFileName[MAX_PATH] = { 0 };
-	sprintf_s(szFileName, MAX_PATH, "%04d%02d%02d-%02d%02d%02d-ProcessID[%ld]-ThreadID[%ld].dmp",
-		stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
-		stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond,
-		GetCurrentProcessId(), GetCurrentThreadId());
+    safeWriteToFd(fd, p);
+}
 
-	std::string strDmppath = GetProcessDirectoryDump();
-	strDmppath += string("\\");
-	strDmppath.append(szFileName);
+void AutoDmp::safeWritePointer(int fd, void* ptr) {
+    char buffer[32];
+    snprintf(buffer, sizeof(buffer), "%p", ptr);
+    safeWriteToFd(fd, buffer);
+}
 
-	hDumpFile = CreateFile(strDmppath.c_str(), GENERIC_READ | GENERIC_WRITE,
-		FILE_SHARE_WRITE | FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
+// 鑾峰彇璋冪敤鏍�
+std::string AutoDmp::getBacktrace(void* context, size_t maxDepth) {
+    void* frames[maxDepth];
+    int numFrames = backtrace(frames, maxDepth);
+
+    if (numFrames <= 0) {
+        return "Unable to get backtrace";
+    }
+
+    // 鑾峰彇绗﹀彿淇℃伅
+    char** symbols = backtrace_symbols(frames, numFrames);
+    if (!symbols) {
+        return "Unable to get symbol information";
+    }
+
+    std::ostringstream oss;
+    for (int i = 0; i < numFrames; ++i) {
+        oss << "#" << std::setw(2) << std::setfill('0') << i
+            << ": " << symbols[i] << "\n";
+    }
+
+    free(symbols);
+    return oss.str();
+}
 
-	MINIDUMP_USER_STREAM UserStream[2];
-	MINIDUMP_USER_STREAM_INFORMATION UserInfo;
-	UserInfo.UserStreamCount = 1;
-	UserInfo.UserStreamArray = UserStream;
-	UserStream[0].Type = CommentStreamA;
-	UserStream[0].BufferSize = strBuild.size();
-	UserStream[0].Buffer = (PVOID)strBuild.c_str();
-	UserStream[1].Type = CommentStreamA;
-	UserStream[1].BufferSize = strError.size();
-	UserStream[1].Buffer = (PVOID)strError.c_str();
+// 璁剧疆 core dump
+bool AutoDmp::setupCoreDump() {
+    struct rlimit coreLimit;
+    coreLimit.rlim_cur = RLIM_INFINITY;
+    coreLimit.rlim_max = RLIM_INFINITY;
 
-	ExpParam.ThreadId = GetCurrentThreadId();
-	ExpParam.ExceptionPointers = pExceptionPointers;
-	ExpParam.ClientPointers = TRUE;
+    return setrlimit(RLIMIT_CORE, &coreLimit) == 0;
+}
 
-	MINIDUMP_TYPE MiniDumpWithDataSegs = (MINIDUMP_TYPE)(MiniDumpNormal
-		| MiniDumpWithHandleData
-		| MiniDumpWithUnloadedModules
-		| MiniDumpWithIndirectlyReferencedMemory
-		| MiniDumpScanMemory
-		| MiniDumpWithProcessThreadData
-		| MiniDumpWithThreadInfo);
+// 鑾峰彇淇″彿鍚�
+std::string AutoDmp::getSignalName(int sig) {
+    switch (sig) {
+        case SIGSEGV: return "SIGSEGV";
+        case SIGABRT: return "SIGABRT";
+        case SIGFPE:  return "SIGFPE";
+        case SIGILL:  return "SIGILL";
+        case SIGBUS:  return "SIGBUS";
+        case SIGSYS:  return "SIGSYS";
+        case SIGPIPE: return "SIGPIPE";
+        case SIGQUIT: return "SIGQUIT";
+        default:      return "UNKNOWN";
+    }
+}
 
-	bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
-		hDumpFile, MiniDumpWithDataSegs, &ExpParam, &UserInfo, NULL);
+// 鑾峰彇淇″彿鎻忚堪
+std::string AutoDmp::getSignalDescription(int sig, siginfo_t* info) {
+    std::ostringstream oss;
+    oss << getSignalName(sig) << " - ";
+
+    switch (sig) {
+        case SIGSEGV:
+            oss << "Segmentation fault";
+            if (info) {
+                switch (info->si_code) {
+                    case SEGV_MAPERR: oss << " (address not mapped)"; break;
+                    case SEGV_ACCERR: oss << " (invalid permissions)"; break;
+                    default: break;
+                }
+            }
+            break;
+        case SIGABRT:
+            oss << "Abort signal";
+            break;
+        case SIGFPE:
+            oss << "Floating point exception";
+            if (info) {
+                switch (info->si_code) {
+                    case FPE_INTDIV: oss << " (integer divide by zero)"; break;
+                    case FPE_INTOVF: oss << " (integer overflow)"; break;
+                    case FPE_FLTDIV: oss << " (floating point divide by zero)"; break;
+                    case FPE_FLTOVF: oss << " (floating point overflow)"; break;
+                    case FPE_FLTUND: oss << " (floating point underflow)"; break;
+                    case FPE_FLTRES: oss << " (floating point inexact result)"; break;
+                    case FPE_FLTINV: oss << " (floating point invalid operation)"; break;
+                    default: break;
+                }
+            }
+            break;
+        case SIGILL:
+            oss << "Illegal instruction";
+            if (info) {
+                switch (info->si_code) {
+                    case ILL_ILLOPC: oss << " (illegal opcode)"; break;
+                    case ILL_ILLOPN: oss << " (illegal operand)"; break;
+                    case ILL_ILLADR: oss << " (illegal addressing mode)"; break;
+                    case ILL_ILLTRP: oss << " (illegal trap)"; break;
+                    default: break;
+                }
+            }
+            break;
+        case SIGBUS:
+            oss << "Bus error";
+            if (info) {
+                switch (info->si_code) {
+                    case BUS_ADRALN: oss << " (invalid address alignment)"; break;
+                    case BUS_ADRERR: oss << " (non-existent physical address)"; break;
+                    case BUS_OBJERR: oss << " (object specific hardware error)"; break;
+                    default: break;
+                }
+            }
+            break;
+        case SIGSYS:
+            oss << "Bad system call";
+            break;
+        case SIGPIPE:
+            oss << "Broken pipe";
+            break;
+        case SIGQUIT:
+            oss << "Quit signal";
+            break;
+        default:
+            oss << "Unknown signal (" << sig << ")";
+            break;
+    }
+
+    return oss.str();
+}
 
-	return;
+// 鑾峰彇褰撳墠鏃堕棿鎴�
+std::string AutoDmp::getCurrentTimestamp() {
+    auto now = std::chrono::system_clock::now();
+    auto time_t = std::chrono::system_clock::to_time_t(now);
+    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
+        now.time_since_epoch()) % 1000;
+
+    std::tm* tm = std::localtime(&time_t);
+    std::ostringstream oss;
+    oss << std::put_time(tm, "%Y%m%d-%H%M%S")
+        << "." << std::setfill('0') << std::setw(3) << ms.count();
+    return oss.str();
 }
 
+// 鑾峰彇杩涚▼鍚�
+std::string AutoDmp::getProcessName() {
+    std::string processName = "Unknown";
+    char buffer[PATH_MAX];
+    ssize_t len = readlink("/proc/self/exe", buffer, sizeof(buffer) - 1);
+    if (len > 0) {
+        buffer[len] = '\0';
+        std::string fullPath = buffer;
+        size_t pos = fullPath.find_last_of('/');
+        if (pos != std::string::npos) {
+            processName = fullPath.substr(pos + 1);
+        }
+    }
+    return processName;
+}
 
-LONG WINAPI AutoDmp::NewUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *lpExceptionInfo)
-{
-	CreateDump(lpExceptionInfo);
-	return EXCEPTION_EXECUTE_HANDLER;
+// 鍒涘缓鐩�綍
+bool AutoDmp::createDirectory(const std::string& path) {
+    if (path.empty()) return false;
+    return (mkdir(path.c_str(), 0755) == 0) || (errno == EEXIST);
 }
 
-AutoDmp::AutoDmp()
-{
-	SetUnhandledExceptionFilter(NewUnhandledExceptionFilter);
+// 娓呯悊鏃ф枃浠�
+void AutoDmp::cleanupOldFiles(const std::string& directory, size_t maxFiles) {
+    if (maxFiles == 0) return;
+
+    std::vector<std::pair<std::string, std::time_t>> files;
+
+    DIR* dir = opendir(directory.c_str());
+    if (dir) {
+        struct dirent* entry;
+        while ((entry = readdir(dir)) != nullptr) {
+            std::string filename = entry->d_name;
+            if (filename.find("crash_") == 0 && filename.find(".log") != std::string::npos) {
+                std::string fullPath = directory + "/" + filename;
+                struct stat fileStat;
+                if (stat(fullPath.c_str(), &fileStat) == 0) {
+                    files.emplace_back(fullPath, fileStat.st_mtime);
+                }
+            }
+        }
+        closedir(dir);
+    }
+
+    // 鎸夋椂闂存帓搴忥紝鏈€鏂扮殑鍦ㄥ墠
+    std::sort(files.begin(), files.end(),
+              [](const auto& a, const auto& b) { return a.second > b.second; });
+
+    // 鍒犻櫎瓒呰繃闄愬埗鐨勬枃浠�
+    for (size_t i = maxFiles; i < files.size(); ++i) {
+        std::remove(files[i].first.c_str());
+    }
 }
 
-AutoDmp::~AutoDmp()
-{
+// 鍐欏叆宕╂簝鏃ュ織
+void AutoDmp::writeCrashLog(const CrashInfo& crashInfo, const std::string& filePath) {
+    std::ofstream logFile(filePath, std::ios::app);
+    if (!logFile.is_open()) return;
+
+    logFile << "==================== LINUX CRASH REPORT ====================\n";
+    logFile << "Timestamp: " << crashInfo.timestamp << "\n";
+    logFile << "Process: " << crashInfo.processName << " (PID: " << crashInfo.processId << ")\n";
+    logFile << "Thread ID: " << crashInfo.threadId << "\n";
+    logFile << "Build Info: " << crashInfo.buildInfo << "\n";
+    logFile << "Signal: " << crashInfo.signalName << " (" << crashInfo.signalNumber << ")\n";
+    logFile << "Signal Description: " << crashInfo.signalDescription << "\n";
+    logFile << "Fault Address: " << crashInfo.faultAddress << "\n";
+    logFile << "\nDetailed Backtrace:\n";
+    logFile << crashInfo.backtrace << "\n";
+    logFile << "============================================================\n\n";
+    logFile.close();
+}
 
+// 杈撳嚭璇︾粏淇℃伅
+void AutoDmp::outputDetailedInfo(const CrashInfo& crashInfo) {
+    std::cerr << "\n========== DETAILED CRASH INFORMATION ==========\n";
+    std::cerr << "Timestamp: " << crashInfo.timestamp << "\n";
+    std::cerr << "Process: " << crashInfo.processName << " (PID: " << crashInfo.processId << ")\n";
+    std::cerr << "Thread: " << crashInfo.threadId << "\n";
+    std::cerr << "Build: " << crashInfo.buildInfo << "\n";
+    std::cerr << "Signal: " << crashInfo.signalDescription << "\n";
+    std::cerr << "Address: " << crashInfo.faultAddress << "\n";
+    std::cerr << "\nBacktrace:\n" << crashInfo.backtrace;
+    std::cerr << "===============================================\n\n";
 }
 
-//dmp生成参考资料
-//http://www.sjsjw.com/kf_other/article/031086ABA018049.asp
+// 鍒濆�鍖栧�鐞嗗櫒
+bool AutoDmp::initializeHandlers() {
+    if (!createDirectory(config_.crashDirectory)) {
+        return false;
+    }
+
+    // 璁剧疆 core dump
+    if (config_.enableCoreDump) {
+        setupCoreDump();
+    }
+
+    // 瀹夎�淇″彿澶勭悊鍣�
+    struct sigaction sa;
+    sa.sa_sigaction = signalHandler;
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = SA_SIGINFO | SA_RESTART;
+
+    bool success = true;
+    for (size_t i = 0; i < handledSignalCount_; ++i) {
+        if (sigaction(handledSignals_[i], &sa, &oldActions_[i]) != 0) {
+            success = false;
+        }
+    }
+
+    return success;
+}
 
+// 娓呯悊澶勭悊鍣�
+void AutoDmp::cleanupHandlers() {
+    for (size_t i = 0; i < handledSignalCount_; ++i) {
+        sigaction(handledSignals_[i], &oldActions_[i], nullptr);
+    }
+}
 
-//在win7 64bit + vs2008 + sdk v7.0的环境下编译Detours
-//http://blog.csdn.net/genesisbible/article/details/6771988
+// 鑾峰彇瀹炰緥閰嶇疆
+const CrashConfig* AutoDmp::getInstanceConfig() {
+    return instance_ ? &instance_->config_ : nullptr;
+}
 
-//下载编译好的Detours
-//http://download.csdn.net/download/staver102/7648875
+// 鐢熸垚娴嬭瘯宕╂簝
+bool AutoDmp::generateTestCrash() const {
+    if (!initialized_.load()) {
+        return false;
+    }
 
+    // 瑙﹀彂涓€涓�畨鍏ㄧ殑娴嬭瘯淇″彿
+    raise(SIGUSR1);
+    return true;
+}
 
-//DMP文件的使用:
-//把dmp文件和exe, pdb文件放在同一目录下, 然后用编译器(如vc)打开, 然后开始调试就会中断到刚才中断的地方.
+// 鏇存柊閰嶇疆
+void AutoDmp::updateConfig(const CrashConfig& newConfig) {
+    config_ = newConfig;
+    createDirectory(config_.crashDirectory);
+}
 
-//使用符号服务器
-//您可以使用符号服务器自动下载用于调试 Visual Studio .NET 项目的正确符号。
-//Microsoft 在 http://msdl.microsoft.com/download/symbols 上为开发人员维护了一个公共符号服务器。
-//此服务器为各种操作系统(Windows NT 4.0、Windows 2000、Windows XP 和 Windows Server 2003)、MDAC、IIS、ISA 和 .NET Framework 提供符号。
-//
-//另外,您也可以将本地符号服务器安装在 Intranet 上或本地计算机上。
-//要使用符号服务器,必须在项目中指定正确的服务器路径。
-//
-//设置符号服务器的路径 
-//1.在 Visual Studio 中打开该项目。
-//2.在“解决方案资源管理器”视图中选择解决方案的名称。
-//3.从“项目”菜单中选择“设置启动项目”。
-//4.在“解决方案 <项目> 属性页”对话框中,打开“通用属性”文件夹,单击“调试符号文件”。
-//5.在“在这些路径中搜索符号文件”框中创建新的行,方法是双击空的新行或单击“新建行”按钮。
-//6.在新行中输入符号服务器的路径。 
-//若要使用 Microsoft 公共符号服务器,请输入: 
-//srv*c:\cache*http://msdl.microsoft.com/download/symbols; 
-//若要使用 Intranet 符号服务器,请输入: 
-//srv*\\server\path\symbols;
-//若要使用本地计算机上的符号服务器,请输入:
-//c:\path\symbols;
-//7.不要单击“检查项”按钮。
-//8.单击“确定”按钮。
-//9.将 symsrv.dll 从 Visual Studio .NET 安装盘复制到 C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE。
+// 鑾峰彇鏀�寔鐨勪俊鍙峰垪琛�
+const int* AutoDmp::getSupportedSignals() {
+    return handledSignals_;
+}
 
-//-----------------dmp文件生成相关--------------------------------------------
+size_t AutoDmp::getSupportedSignalCount() {
+    return handledSignalCount_;
+}

+ 118 - 16
DrvProc/CcosProc/AutoDmp/AutoDmp.h

@@ -1,28 +1,130 @@
-
 #ifndef _AUTODMP_H_
 #define _AUTODMP_H_
 
-//-----------------dmp文件生成与使用--------------------------------------------
-#include <stdio.h>
-#include <windows.h>
-#include <dbghelp.h>
-#pragma comment(lib, "Dbghelp.lib")
+#include <string>
+#include <atomic>
+#include <csignal>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <execinfo.h>
+#include <sys/resource.h>
+#include <sys/ucontext.h>
 
-typedef LONG(*UnhandledExceptionFilterPoint)(struct _EXCEPTION_POINTERS *lpExceptionInfo);
+// Linux宕╂簝淇℃伅缁撴瀯浣�
+struct CrashInfo {
+    std::string timestamp;
+    std::string processName;
+    pid_t processId;
+    pid_t threadId;
+    std::string buildInfo;
+    int signalNumber;
+    std::string signalName;
+    void* faultAddress;
+    std::string backtrace;
+    std::string signalDescription;
+};
 
+// Linux宕╂簝閰嶇疆閫夐」
+struct CrashConfig {
+    bool enableCoreDump = true;          // 鏄�惁鐢熸垚core dump
+    bool enableConsoleOutput = true;     // 鏄�惁杈撳嚭鍒版帶鍒跺彴
+    bool enableLogFile = true;           // 鏄�惁鐢熸垚鏃ュ織鏂囦欢
+    bool enableBacktrace = true;         // 鏄�惁鐢熸垚璋冪敤鏍�
+    std::string crashDirectory = "./crashes";  // 宕╂簝鏂囦欢鐩�綍
+    size_t maxCrashFiles = 10;          // 鏈€澶т繚鐣欏穿婧冩枃浠舵暟
+    size_t maxBacktraceDepth = 128;     // 鏈€澶ц皟鐢ㄦ爤娣卞害
+    bool enableSymbols = true;          // 鏄�惁鍚�敤绗﹀彿瑙f瀽
+    bool enableDetailedInfo = true;     // 鏄�惁鍚�敤璇︾粏淇℃伅
+    bool asyncSafeOnly = true;          // 鏄�惁鍙�娇鐢ㄥ紓姝ュ畨鍏ㄥ嚱鏁�
+};
 
-class AutoDmp
-{
+class AutoDmp {
 public:
-	AutoDmp();
-	~AutoDmp();
+    explicit AutoDmp(const CrashConfig& config = CrashConfig{});
+    ~AutoDmp();
+
+    // 绂佹�鎷疯礉鍜岃祴鍊�
+    AutoDmp(const AutoDmp&) = delete;
+    AutoDmp& operator=(const AutoDmp&) = delete;
+
+    // 鎵嬪姩瑙﹀彂宕╂簝澶勭悊锛堢敤浜庢祴璇曪級
+    bool generateTestCrash() const;
+
+    // 鑾峰彇閰嶇疆
+    const CrashConfig& getConfig() const { return config_; }
+
+    // 鏇存柊閰嶇疆
+    void updateConfig(const CrashConfig& newConfig);
+
+    // 妫€鏌ユ槸鍚﹀凡鍒濆�鍖�
+    bool isInitialized() const { return initialized_.load(); }
+
+    // 鑾峰彇鏀�寔鐨勪俊鍙峰垪琛�
+    static const int* getSupportedSignals();
+    static size_t getSupportedSignalCount();
+
 private:
-	PVOID m_lpUnhandledExceptionFilter;
-	static LONG WINAPI NewUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *lpExceptionInfo);
+    CrashConfig config_;
+    std::atomic<bool> initialized_{false};
+    std::atomic<bool> crashInProgress_{false};
+
+    // 淇″彿澶勭悊鐩稿叧
+    static void signalHandler(int sig, siginfo_t* info, void* context);
+    struct sigaction oldActions_[8];  // 淇濆瓨鍘熷�淇″彿澶勭悊
+    static const int handledSignals_[];
+    static const size_t handledSignalCount_;
+
+    // 鏍稿績鍔熻兘鍑芥暟
+    static std::string getBacktrace(void* context, size_t maxDepth = 128);
+    static bool setupCoreDump();
+    static std::string getSignalName(int sig);
+    static std::string getSignalDescription(int sig, siginfo_t* info);
+
+    // 杈呭姪鍑芥暟 - 寮傛�瀹夊叏
+    static void safeWriteToFd(int fd, const char* msg);
+    static void safeWriteNumber(int fd, long number);
+    static void safeWritePointer(int fd, void* ptr);
+
+    // 杈呭姪鍑芥暟 - 闈炲紓姝ュ畨鍏�紙浠呭湪瀹夊叏涓婁笅鏂囦娇鐢�級
+    static std::string getCurrentTimestamp();
+    static std::string getProcessName();
+    static bool createDirectory(const std::string& path);
+    static void cleanupOldFiles(const std::string& directory, size_t maxFiles);
+    static void writeCrashLog(const CrashInfo& crashInfo, const std::string& filePath);
+    static void outputDetailedInfo(const CrashInfo& crashInfo);
+
+    // 鍒濆�鍖栧拰娓呯悊
+    bool initializeHandlers();
+    void cleanupHandlers();
+
+    // 鑾峰彇鍗曚緥閰嶇疆锛堢敤浜庨潤鎬佸�鐞嗗嚱鏁帮級
+    static const CrashConfig* getInstanceConfig();
+    static AutoDmp* instance_;
 };
-//DMP文件的使用:
-//把dmp文件和exe, pdb文件放在同一目录下, 然后用编译器(如vc)打开, 然后开始调试就会中断到刚才中断的地方.
-//-----------------dmp文件生成与使用--------------------------------------------
 
+// 渚垮埄瀹忥細鐢ㄤ簬蹇�€熼儴缃插穿婧冩�娴�
+#define ENABLE_CRASH_HANDLER() \
+    do { \
+        static AutoDmp crashHandler; \
+        (void)crashHandler; \
+    } while(0)
+
+#define ENABLE_CRASH_HANDLER_WITH_CONFIG(config) \
+    do { \
+        static AutoDmp crashHandler(config); \
+        (void)crashHandler; \
+    } while(0)
+
+// 璋冭瘯瀹忥細杈撳嚭璋冭瘯淇℃伅
+#ifndef NDEBUG
+    #define CRASH_DEBUG(msg) \
+        do { \
+            write(STDERR_FILENO, "[CRASH_DEBUG] ", 15); \
+            write(STDERR_FILENO, msg, strlen(msg)); \
+            write(STDERR_FILENO, "\n", 1); \
+        } while(0)
+#else
+    #define CRASH_DEBUG(msg) do {} while(0)
 #endif
 
+#endif // _AUTODMP_H_

+ 275 - 0
DrvProc/CcosProc/AutoDmp/README.md

@@ -0,0 +1,275 @@
+# AutoDmp - Linux专用崩溃检测与转储工具
+
+AutoDmp 是一个针对 Linux 系统优化的崩溃检测和转储生成工具,专门处理 Linux 信号和 core dump。
+
+## ✨ 主要特性
+
+### 🛡️ Linux专用安全机制
+- **异步安全**: 信号处理器只使用异步安全函数
+- **线程安全**: 使用原子操作防止竞争条件
+- **防重入保护**: 避免信号处理器递归调用
+- **双重输出**: 异步安全的即时输出 + 详细的崩溃日志
+
+### 🔧 Linux系统集成
+- **Core Dump**: 自动设置 ulimit 并生成标准 core dump
+- **详细调用栈**: 使用 `backtrace()` 获取完整调用链
+- **信号详解**: 详细解析各种 Linux 信号和错误代码
+- **进程信息**: PID、TID、进程名、构建信息等
+
+### 📊 多种输出模式
+- **即时输出**: 异步安全的 stderr 输出(崩溃时立即可见)
+- **详细日志**: 完整的崩溃报告文件
+- **Core Dump**: 标准的 Linux core dump 文件
+- **自动清理**: 限制保留文件数量
+
+## 🚀 快速开始
+
+### 最简单的使用方式
+```cpp
+#include \"AutoDmp.h\"
+
+int main() {
+    // 一行代码启用Linux崩溃检测
+    ENABLE_CRASH_HANDLER();
+
+    // 你的程序代码...
+
+    return 0;
+}
+```
+
+### Linux专用配置
+```cpp
+#include \"AutoDmp.h\"
+
+int main() {
+    // Linux专用配置
+    CrashConfig config;
+    config.enableCoreDump = true;           // 启用core dump
+    config.enableConsoleOutput = true;      // 启用控制台输出
+    config.enableLogFile = true;            // 启用详细日志
+    config.enableBacktrace = true;          // 启用调用栈
+    config.crashDirectory = \"./crashes\";   // 崩溃文件目录
+    config.maxCrashFiles = 10;              // 最大保留文件数
+    config.maxBacktraceDepth = 128;         // 调用栈最大深度
+    config.enableDetailedInfo = true;       // 启用详细信息
+    config.asyncSafeOnly = false;           // 允许非异步安全操作
+
+    // 使用配置启用
+    ENABLE_CRASH_HANDLER_WITH_CONFIG(config);
+
+    // 你的程序代码...
+
+    return 0;
+}
+```
+
+### 面向对象方式
+```cpp
+#include \"AutoDmp.h\"
+
+int main() {
+    // 创建Linux崩溃处理器
+    CrashConfig config;
+    config.crashDirectory = \"./my_crashes\";
+    config.enableCoreDump = true;
+
+    AutoDmp crashHandler(config);
+
+    if (crashHandler.isInitialized()) {
+        std::cout << \"Linux崩溃检测已启用\" << std::endl;
+
+        // 查看支持的信号
+        const int* signals = AutoDmp::getSupportedSignals();
+        size_t count = AutoDmp::getSupportedSignalCount();
+
+        std::cout << \"监控 \" << count << \" 种Linux信号\" << std::endl;
+    }
+
+    // 你的程序代码...
+
+    return 0;  // 析构时自动清理
+}
+```
+
+## 📁 输出文件
+
+### Core Dump 文件
+- **位置**: 当前目录或系统配置的位置
+- **名称**: `core` 或 `core.PID`
+- **用途**: 使用 GDB 进行详细调试
+
+### 崩溃日志文件
+- **位置**: `./crashes/crash_YYYYMMDD-HHMMSS.xxx.log`
+- **格式**: 详细的文本报告
+
+### 日志内容示例
+```
+==================== LINUX CRASH REPORT ====================
+Timestamp: 20231215-143022.456
+Process: MyApp (PID: 1234)
+Thread ID: 5678
+Build Info: Dec 15 2023 14:29:30
+Signal: SIGSEGV (11)
+Signal Description: SIGSEGV - Segmentation fault (address not mapped)
+Fault Address: 0x0
+
+Detailed Backtrace:
+#00: ./MyApp(_Z18testSegFaultv+0x12)[0x401234]
+#01: ./MyApp(main+0x45)[0x401156]
+#02: /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x7f8b2c0230b3]
+#03: ./MyApp(_start+0x2e)[0x40105e]
+============================================================
+```
+
+## 🔧 Linux配置选项
+
+| 选项 | 类型 | 默认值 | 说明 |
+|------|------|--------|------|
+| `enableCoreDump` | bool | true | 是否生成 core dump |
+| `enableConsoleOutput` | bool | true | 是否异步安全输出到 stderr |
+| `enableLogFile` | bool | true | 是否生成详细日志文件 |
+| `enableBacktrace` | bool | true | 是否生成调用栈 |
+| `crashDirectory` | string | \"./crashes\" | 崩溃文件目录 |
+| `maxCrashFiles` | size_t | 10 | 最大保留文件数 |
+| `maxBacktraceDepth` | size_t | 128 | 调用栈最大深度 |
+| `enableSymbols` | bool | true | 是否启用符号解析 |
+| `enableDetailedInfo` | bool | true | 是否启用详细信息输出 |
+| `asyncSafeOnly` | bool | true | 是否只使用异步安全函数 |
+
+## 🧪 测试
+
+### 编译
+```bash
+# GCC编译
+g++ -std=c++11 -g -O0 -o test_crash test_crash.cpp AutoDmp.cpp -ldl -lpthread
+
+# 确保能生成core dump
+ulimit -c unlimited
+
+# 运行测试
+./test_crash
+```
+
+### 支持的测试场景
+1. **段错误** (SIGSEGV) - 空指针解引用
+2. **浮点异常** (SIGFPE) - 除零错误
+3. **栈溢出** (SIGSEGV) - 无限递归
+4. **异常终止** (SIGABRT) - abort() 调用
+5. **非法指令** (SIGILL) - 未定义指令
+6. **总线错误** (SIGBUS) - 内存对齐错误
+7. **数组越界** (SIGSEGV) - 大量越界访问
+8. **多线程崩溃** (SIGSEGV) - 子线程崩溃
+9. **管道错误** (SIGPIPE) - 向关闭的管道写入
+10. **用户信号** (SIGUSR1) - 安全测试
+
+## 📋 支持的Linux信号
+
+| 信号 | 数值 | 描述 | 常见原因 |
+|------|------|------|----------|
+| `SIGSEGV` | 11 | 段错误 | 空指针、越界访问 |
+| `SIGABRT` | 6 | 异常终止 | abort()、断言失败 |
+| `SIGFPE` | 8 | 浮点异常 | 除零、溢出 |
+| `SIGILL` | 4 | 非法指令 | 损坏的代码、架构不匹配 |
+| `SIGBUS` | 7 | 总线错误 | 内存对齐、硬件错误 |
+| `SIGSYS` | 31 | 系统调用错误 | 无效系统调用 |
+| `SIGPIPE` | 13 | 管道错误 | 向关闭的管道写入 |
+| `SIGQUIT` | 3 | 退出信号 | Ctrl+\\ |
+
+## 🔍 使用Core Dump调试
+
+### 基本调试流程
+```bash
+# 1. 编译时包含调试信息
+g++ -g -O0 -o myapp main.cpp AutoDmp.cpp -ldl
+
+# 2. 运行程序(崩溃后会生成core文件)
+./myapp
+
+# 3. 使用GDB分析core dump
+gdb ./myapp core
+
+# 4. GDB常用命令
+(gdb) bt           # 查看调用栈
+(gdb) bt full      # 查看详细调用栈(含变量)
+(gdb) info locals  # 查看局部变量
+(gdb) print var    # 打印变量值
+(gdb) list         # 查看源代码
+(gdb) frame 0      # 切换到栈帧0
+(gdb) info threads # 查看所有线程
+(gdb) thread 1     # 切换到线程1
+```
+
+### 高级调试技巧
+```bash
+# 查看内存映射
+(gdb) info proc mappings
+
+# 查看寄存器状态
+(gdb) info registers
+
+# 查看汇编代码
+(gdb) disassemble
+
+# 查看共享库
+(gdb) info sharedlibrary
+
+# 设置断点重现问题
+(gdb) break main
+(gdb) run
+```
+
+## ⚠️ Linux特有注意事项
+
+### 1. Core Dump 设置
+```bash
+# 检查core dump设置
+ulimit -c
+
+# 启用core dump(无限制)
+ulimit -c unlimited
+
+# 设置core文件命名规则
+echo 'core.%p.%t' | sudo tee /proc/sys/kernel/core_pattern
+```
+
+### 2. 权限要求
+- 进程需要有写入崩溃目录的权限
+- Core dump 需要有足够的磁盘空间
+- 某些安全模块(如SELinux)可能限制core dump
+
+### 3. 符号信息
+```bash
+# 安装调试符号(Ubuntu/Debian)
+sudo apt-get install libc6-dbg
+
+# 设置符号路径
+export DEBUGINFOD_URLS=\"https://debuginfod.ubuntu.com\"
+```
+
+### 4. 多线程注意事项
+- 崩溃处理在任意线程中都能正确工作
+- 调用栈会显示崩溃时的具体线程
+- 可以使用 `info threads` 查看所有线程状态
+
+### 5. 性能考虑
+- 异步安全输出几乎无性能损失
+- 详细日志记录会有轻微开销
+- Core dump 大小取决于进程内存使用
+
+### 编译要求
+- Linux 系统(已测试:Ubuntu 18.04+, CentOS 7+)
+- GCC 4.8+ 或 Clang 3.8+
+- C++11 支持
+- glibc 2.17+
+
+### 依赖库
+- `libdl` - 动态链接
+- `libpthread` - 多线程支持
+- `libc` - 标准C库(backtrace支持)
+
+如有问题或建议,请联系项目维护团队。
+
+## 📄 许可证
+
+本项目采用内部使用许可,仅供内部开发使用。

+ 289 - 0
DrvProc/CcosProc/AutoDmp/test_crash.cpp

@@ -0,0 +1,289 @@
+#include "AutoDmp.h"
+#include <iostream>
+#include <thread>
+#include <chrono>
+#include <vector>
+#include <memory>
+#include <cstdlib>
+#include <unistd.h>
+
+// Linux崩溃测试用例类
+class LinuxCrashTest {
+public:
+    // 段错误测试
+    static void testSegmentationFault() {
+        std::cout << "Testing segmentation fault (SIGSEGV)...\n";
+        int* nullPtr = nullptr;
+        *nullPtr = 42; // 触发段错误
+    }
+
+    // 除零错误测试
+    static void testDivisionByZero() {
+        std::cout << "Testing division by zero (SIGFPE)...\n";
+        volatile int zero = 0;
+        volatile int result = 100 / zero; // 触发浮点异常
+        (void)result; // 避免未使用变量警告
+    }
+
+    // 栈溢出测试
+    static void testStackOverflow() {
+        std::cout << "Testing stack overflow (SIGSEGV)...\n";
+        testStackOverflow(); // 无限递归导致栈溢出
+    }
+
+    // 异常终止测试
+    static void testAbort() {
+        std::cout << "Testing abort signal (SIGABRT)...\n";
+        std::abort(); // 触发 SIGABRT
+    }
+
+    // 非法指令测试
+    static void testIllegalInstruction() {
+        std::cout << "Testing illegal instruction (SIGILL)...\n";
+        // 内联汇编触发非法指令(x86_64)
+        __asm__("ud2"); // 未定义指令
+    }
+
+    // 总线错误测试
+    static void testBusError() {
+        std::cout << "Testing bus error (SIGBUS)...\n";
+        // 创建一个不对齐的指针访问
+        char buffer[16];
+        char* misaligned = buffer + 1;
+        long* longPtr = reinterpret_cast<long*>(misaligned);
+        *longPtr = 0x1234567890ABCDEF; // 可能触发总线错误
+    }
+
+    // 数组越界测试
+    static void testArrayOutOfBounds() {
+        std::cout << "Testing array out of bounds (SIGSEGV)...\n";
+        int arr[5] = {1, 2, 3, 4, 5};
+        // 大量越界访问,最终会触发段错误
+        for (int i = 0; i < 1000000; ++i) {
+            arr[i] = i; // 最终会访问到未分配的内存
+        }
+    }
+
+    // 多线程崩溃测试
+    static void testMultiThreadCrash() {
+        std::cout << "Testing multi-thread crash (SIGSEGV)...\n";
+        auto crashFunc = []() {
+            std::this_thread::sleep_for(std::chrono::milliseconds(100));
+            std::cout << "  Thread " << std::this_thread::get_id() << " about to crash...\n";
+            int* p = nullptr;
+            *p = 123; // 在子线程中崩溃
+        };
+
+        std::thread t(crashFunc);
+        t.join();
+    }
+
+    // 管道错误测试
+    static void testPipeError() {
+        std::cout << "Testing pipe error (SIGPIPE)...\n";
+        int pipefd[2];
+        if (pipe(pipefd) == 0) {
+            close(pipefd[0]); // 关闭读端
+
+            // 向已关闭的管道写入数据会触发 SIGPIPE
+            char data[] = "This will trigger SIGPIPE";
+            write(pipefd[1], data, sizeof(data));
+
+            close(pipefd[1]);
+        }
+    }
+
+    // 用户信号测试(不会崩溃程序)
+    static void testUserSignal() {
+        std::cout << "Testing user signal (SIGUSR1) - safe test...\n";
+        raise(SIGUSR1); // 这不会终止程序
+    }
+};
+
+void printUsage() {
+    std::cout << "\nLinux崩溃测试程序使用说明:\n";
+    std::cout << "test_crash [选项]\n";
+    std::cout << "选项:\n";
+    std::cout << "  1 - 段错误 (SIGSEGV - Segmentation Fault)\n";
+    std::cout << "  2 - 除零错误 (SIGFPE - Floating Point Exception)\n";
+    std::cout << "  3 - 栈溢出 (SIGSEGV - Stack Overflow)\n";
+    std::cout << "  4 - 异常终止 (SIGABRT - Abort)\n";
+    std::cout << "  5 - 非法指令 (SIGILL - Illegal Instruction)\n";
+    std::cout << "  6 - 总线错误 (SIGBUS - Bus Error)\n";
+    std::cout << "  7 - 数组越界 (SIGSEGV - Array Out of Bounds)\n";
+    std::cout << "  8 - 多线程崩溃 (SIGSEGV - Multi-thread Crash)\n";
+    std::cout << "  9 - 管道错误 (SIGPIPE - Pipe Error)\n";
+    std::cout << "  0 - 用户信号测试 (SIGUSR1 - 不会崩溃)\n";
+    std::cout << "  h - 显示此帮助\n";
+}
+
+void showConfiguration() {
+    std::cout << "\n=== Linux崩溃处理配置演示 ===\n";
+
+    // 创建自定义配置
+    CrashConfig config;
+    config.enableCoreDump = true;
+    config.enableConsoleOutput = true;
+    config.enableLogFile = true;
+    config.enableBacktrace = true;
+    config.crashDirectory = "./crashes";
+    config.maxCrashFiles = 5;
+    config.maxBacktraceDepth = 64;
+    config.enableSymbols = true;
+    config.enableDetailedInfo = true;
+    config.asyncSafeOnly = false; // 允许详细日志
+
+    std::cout << "崩溃处理器配置:\n";
+    std::cout << "- 启用core dump: " << (config.enableCoreDump ? "是" : "否") << "\n";
+    std::cout << "- 启用控制台输出: " << (config.enableConsoleOutput ? "是" : "否") << "\n";
+    std::cout << "- 启用日志文件: " << (config.enableLogFile ? "是" : "否") << "\n";
+    std::cout << "- 启用调用栈: " << (config.enableBacktrace ? "是" : "否") << "\n";
+    std::cout << "- 崩溃目录: " << config.crashDirectory << "\n";
+    std::cout << "- 最大文件数: " << config.maxCrashFiles << "\n";
+    std::cout << "- 调用栈深度: " << config.maxBacktraceDepth << "\n";
+    std::cout << "- 详细信息: " << (config.enableDetailedInfo ? "是" : "否") << "\n";
+
+    return;
+}
+
+void showSupportedSignals() {
+    std::cout << "\n=== 支持的Linux信号 ===\n";
+
+    const int* signals = AutoDmp::getSupportedSignals();
+    size_t count = AutoDmp::getSupportedSignalCount();
+
+    for (size_t i = 0; i < count; ++i) {
+        std::cout << "- " << signals[i] << ": ";
+        switch (signals[i]) {
+            case SIGSEGV: std::cout << "SIGSEGV (段错误)"; break;
+            case SIGABRT: std::cout << "SIGABRT (异常终止)"; break;
+            case SIGFPE:  std::cout << "SIGFPE (浮点异常)"; break;
+            case SIGILL:  std::cout << "SIGILL (非法指令)"; break;
+            case SIGBUS:  std::cout << "SIGBUS (总线错误)"; break;
+            case SIGSYS:  std::cout << "SIGSYS (系统调用错误)"; break;
+            case SIGPIPE: std::cout << "SIGPIPE (管道错误)"; break;
+            case SIGQUIT: std::cout << "SIGQUIT (退出信号)"; break;
+            default:      std::cout << "Unknown"; break;
+        }
+        std::cout << "\n";
+    }
+}
+
+void interactiveMode() {
+    showConfiguration();
+    showSupportedSignals();
+
+    std::cout << "\n请选择测试类型:\n";
+    printUsage();
+
+    int choice;
+    std::cout << "\n请输入选择: ";
+    std::cin >> choice;
+
+    if (choice < 0 || choice > 9) {
+        std::cout << "无效选择\n";
+        return;
+    }
+
+    std::cout << "\n正在执行测试,3秒后开始...\n";
+    for (int i = 3; i > 0; --i) {
+        std::cout << i << "... " << std::flush;
+        std::this_thread::sleep_for(std::chrono::seconds(1));
+    }
+    std::cout << "\n开始测试!\n";
+
+    try {
+        switch (choice) {
+        case 0:
+            LinuxCrashTest::testUserSignal();
+            break;
+        case 1:
+            LinuxCrashTest::testSegmentationFault();
+            break;
+        case 2:
+            LinuxCrashTest::testDivisionByZero();
+            break;
+        case 3:
+            LinuxCrashTest::testStackOverflow();
+            break;
+        case 4:
+            LinuxCrashTest::testAbort();
+            break;
+        case 5:
+            LinuxCrashTest::testIllegalInstruction();
+            break;
+        case 6:
+            LinuxCrashTest::testBusError();
+            break;
+        case 7:
+            LinuxCrashTest::testArrayOutOfBounds();
+            break;
+        case 8:
+            LinuxCrashTest::testMultiThreadCrash();
+            break;
+        case 9:
+            LinuxCrashTest::testPipeError();
+            break;
+        }
+    } catch (const std::exception& e) {
+        std::cout << "捕获到异常: " << e.what() << "\n";
+    }
+
+    std::cout << "\n如果程序能执行到这里,说明测试没有触发预期的崩溃\n";
+}
+
+int main(int argc, char* argv[]) {
+    std::cout << "AutoDmp Linux崩溃检测测试程序\n";
+    std::cout << "================================\n";
+
+    // 创建Linux专用配置
+    CrashConfig config;
+    config.enableCoreDump = true;
+    config.enableConsoleOutput = true;
+    config.enableLogFile = true;
+    config.enableBacktrace = true;
+    config.enableDetailedInfo = true;
+    config.crashDirectory = "./crashes";
+    config.maxCrashFiles = 10;
+    config.maxBacktraceDepth = 128;
+    config.asyncSafeOnly = false; // 允许详细日志记录
+
+    std::cout << "\n=== 启用Linux崩溃处理 ===\n";
+    std::cout << "使用自定义配置启用崩溃检测...\n";
+
+    // 使用配置启用崩溃处理
+    ENABLE_CRASH_HANDLER_WITH_CONFIG(config);
+
+    std::cout << "✓ Linux崩溃处理器已启用\n";
+    std::cout << "✓ Core dump已启用 (ulimit -c unlimited)\n";
+    std::cout << "✓ 调用栈跟踪已启用\n";
+    std::cout << "✓ 异步安全输出已启用\n";
+
+    if (argc > 1) {
+        // 命令行模式
+        int testType = std::atoi(argv[1]);
+        std::cout << "\n命令行模式: 测试类型 " << testType << "\n";
+
+        switch (testType) {
+        case 0: LinuxCrashTest::testUserSignal(); break;
+        case 1: LinuxCrashTest::testSegmentationFault(); break;
+        case 2: LinuxCrashTest::testDivisionByZero(); break;
+        case 3: LinuxCrashTest::testStackOverflow(); break;
+        case 4: LinuxCrashTest::testAbort(); break;
+        case 5: LinuxCrashTest::testIllegalInstruction(); break;
+        case 6: LinuxCrashTest::testBusError(); break;
+        case 7: LinuxCrashTest::testArrayOutOfBounds(); break;
+        case 8: LinuxCrashTest::testMultiThreadCrash(); break;
+        case 9: LinuxCrashTest::testPipeError(); break;
+        default:
+            std::cout << "无效的测试类型\n";
+            printUsage();
+            return 1;
+        }
+    } else {
+        // 交互模式
+        interactiveMode();
+    }
+
+    return 0;
+}

+ 21 - 5
DrvProc/libCcosProc/DriverManager.cpp

@@ -9,7 +9,7 @@
 #include "common_api.h"
 #include "PacketAnalizer.h"
 
-//#include "AutoDmp.h"
+#include "AutoDmp.h"
 
 
 #define CRTDBG_MAP_ALLOC
@@ -25,10 +25,6 @@ int totalDeviceNum = 0;
 LogicDevice* g_AllDevice[maxDeviceNum];
 
 using namespace std;
-
-//AutoDmp atdmp;
-
-
 static std::mutex g_device_mutex;
 
 LDM_API const char* add_driver(char* driverName)
@@ -53,6 +49,26 @@ const char* pszAllDevice = "";
 /// <returns>以;分割的可以Open的设备URI列表字符串</returns>
 LDM_API const char* get_all_device(int rpcPort, int httpPort)
 {
+    // 启用崩溃处理
+    // 创建Linux专用配置
+    static bool crashHandlerInitialized = false;
+    if (!crashHandlerInitialized) {
+        CrashConfig config;
+        config.enableCoreDump = true;
+        config.enableConsoleOutput = true;
+        config.enableLogFile = true;
+        config.enableBacktrace = true;
+        config.enableDetailedInfo = true;
+        config.crashDirectory = "/userdata/Devicelogs/crashes";
+        config.maxCrashFiles = 10;
+        config.maxBacktraceDepth = 128;
+        config.asyncSafeOnly = false; // 允许详细日志记录
+
+        // 使用配置启用崩溃处理
+        ENABLE_CRASH_HANDLER_WITH_CONFIG(config);
+        crashHandlerInitialized = true;
+    }
+
     std::lock_guard<std::mutex> lock(g_device_mutex); // 添加互斥锁
 
     try {