添加信号处理函数debug程序异常退出

最近在debug rust写的程序异常退出问题,没有任何log。猜测可能是被kill掉。通过手动添加signal handle来尝试打印出出错信息发现了问题所在。

signal处理的几种现有的工具,主流的signal_hook感觉有点复杂,不太适合我的需求。我希望得到一个类似于c中sigaction的东西。rust也是提供了的。参考了这个是示例:https://gist.github.com/takaswie/ded48047759dd25fe4c9308583fa074ds

这个例子中,你首先要知道给哪个signal安装handle。为此我找到了另外一个工具,可以简单的获取信号类型。

use simple_signal::{self, Signal};
simple_signal::set_handler(&[Signal::Int, Signal::Term], |signals| println!("Caught: {:?}", signals));

 一旦我们得到信号类型,我们就可以据此安装相应的handler。

extern "C" fn handle(sig: libc::c_int, info: *mut libc::siginfo_t,
                     _: *mut libc::c_void) {
    println!("caugh signal {}", sig);
    unsafe {
        println!("address: {:?} caugh error", (*info).si_addr());
    }
    std::process::exit(1);
}

fn install_signal_handler() {
    unsafe {
        let sig_action = signal::SigAction::new(
                                    signal::SigHandler::SigAction(handle),
                                    signal::SaFlags::empty(),
                                    signal::SigSet::empty());
        signal::sigaction(signal::SIGSEGV, &sig_action)
    };
}

//test to get a segment fault signal
fn main() {
    unsafe {
        let p = 0x10000;
        let point = p as *const i32;
        let v = *point;
    }
}

在 Qt 程序使用 `qDebug()` 输出时程序异常退出,可能由多种原因造成。以下是一些常见的原因及相应的解决方法: ### 1. **程序运行时未正确初始化 Qt 环境** 在某些情况下,如果程序没有正确初始化 Qt 的核心组件,调用 `qDebug()` 会导致程序崩溃。确保程序的 `main()` 函数中正确创建了 `QApplication` 或 `QCoreApplication` 实例。 ```cpp #include <QApplication> #include <QDebug> int main(int argc, char *argv[]) { QApplication app(argc, argv); qDebug() << "This is a debug message."; return app.exec(); } ``` ### 2. **多线程环境下未正确处理 Qt 日志输出** 如果在非主线程中使用 `qDebug()`,而没有确保线程安全,可能导致程序崩溃。Qt 的日志系统默认是线程安全的,但如果自定义了消息处理函数(通过 `qInstallMessageHandler`),需要确保其支持多线程环境。 ```cpp #include <QtGlobal> #include <QDebug> #include <QThread> void customMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) { // 确保线程安全 Q_UNUSED(type); Q_UNUSED(context); QByteArray localMsg = msg.toLocal8Bit(); printf("%s\n", localMsg.constData()); } int main(int argc, char *argv[]) { qInstallMessageHandler(customMessageHandler); QThread thread; thread.start(); QMetaObject::invokeMethod(&thread, [](){ qDebug() << "Debug message from thread."; }, Qt::QueuedConnection); thread.quit(); thread.wait(); return 0; } ``` ### 3. **qDebug() 输出的数据类型未正确处理** 如果 `qDebug()` 输出了未定义流操作符(`<<`)的自定义类型,可能导致程序崩溃。确保自定义类型实现了 `QDebug` 的流操作符重载。 ```cpp #include <QDebug> class MyClass { public: MyClass(int value) : data(value) {} int data; }; QDebug operator<<(QDebug debug, const MyClass &obj) { debug << "MyClass(" << obj.data << ")"; return debug; } int main() { MyClass obj(42); qDebug() << obj; // 正确输出自定义类型 return 0; } ``` ### 4. **qDebug() 被重定向到不可用的输出设备** 在某些嵌入式系统或无控制台的环境中,`qDebug()` 默认输出到控制台,如果没有可用的控制台设备,可能导致程序异常退出。可以通过 `qInstallMessageHandler` 自定义输出路径。 ```cpp #include <QtGlobal> #include <QDebug> #include <QFile> #include <QTextStream> void customMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) { Q_UNUSED(type); Q_UNUSED(context); QFile file("debug.log"); if (file.open(QIODevice::WriteOnly | QIODevice::Append)) { QTextStream stream(&file); stream << msg << endl; file.close(); } } int main(int argc, char *argv[]) { qInstallMessageHandler(customMessageHandler); qDebug() << "This debug message will be written to a file."; return 0; } ``` ### 5. **程序中存在未初始化的指针或非法内存访问** 如果 `qDebug()` 输出了未初始化的指针或已经释放的内存,可能导致程序崩溃。检查程序中是否有非法内存访问或悬空指针。 ```cpp #include <QDebug> int main() { int *ptr = nullptr; qDebug() << "Pointer value:" << ptr; // 合法,输出为 0 int value = 42; ptr = &value; qDebug() << "Pointer value after assignment:" << ptr; return 0; } ``` ### 6. **Qt 库版本不兼容或 DLL 缺失** 如果程序依赖的 Qt 库版本不兼容或缺少必要的 DLL 文件,可能导致 `qDebug()` 异常退出。检查构建环境是否包含所有必要的 Qt 库文件,并确保运行时路径正确配置[^1]。 ### 7. **关闭窗口时未正确释放资源** 在窗口程序中,如果在 `closeEvent()` 或析构函数中未正确释放资源,可能导致程序异常退出。确保所有资源(如 `QTcpSocket`)在关闭时已正确释放,并将对象设置为父对象以自动管理生命周期[^2]。 ```cpp #include <QMainWindow> #include <QTcpSocket> #include <QDebug> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) { socket = new QTcpSocket(this); // 设置父对象,自动管理生命周期 } protected: void closeEvent(QCloseEvent *event) override { qDebug() << "Closing main window."; if (socket) { socket->close(); } QMainWindow::closeEvent(event); } private: QTcpSocket *socket; }; ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值