123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- #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;
- }
|