美文网首页PyQt
超实用技巧,代码跟踪器

超实用技巧,代码跟踪器

作者: 223480235e8e | 来源:发表于2019-05-19 20:56 被阅读3次

    在项目开发中,当程序崩溃时,如何快速的定位bug,一直是程序员最头疼的问题,为此,也有很多有经验的人士总结了很多办法。

    今天小豆君就来分享个我自己创立的代码跟踪器。

    1 打印开始和结束信息

    一般的,在每个调用接口的开始和结束处加入打印信息。当程序崩溃时,就能够快速判断是在哪个函数的调用中出了问题,从而快速缩小范围。

    像这样:

    void MyTest::createWidget()
    {
        qDebug() << "Enter createWidget";
        //代码段...
        qDebug() << "Leave createWidget";
    }
    

    但是,有一个缺点,不简洁,有时候我也很懒,不愿意加。

    好,那可以改进一下。

    对于一个类,在创建的时候会调用构造函数,在释放的时候会调用析构函数。所以我就可以将"Enter..."写在构造函数中,将"Leave..."写在析构函数中。在函数开始处创建这个局部对象(当然不要new),这时就会打印“Enter”,而当函数调用结束后,系统就会自动释放该对象,从而打印“Leave”。

    为此我们创建一个类,取名为Tracker(跟踪器)。

    class Tracker
    {
    public:
        Tracker(QString msg = "")
        {
            m_msg = msg;
            qDebug() << "Enter:" << m_msg;
        }
    
        ~Tracker()
        {
            qDebug() << "Leave:" << m_msg;
        }
    
    private:
        QString m_msg;
    };
    

    调用:

    void MyTest::createWidget()
    {
        Tracker tracker("createWidget");
    
        //代码段...
    }
    

    打印结果:

    image

    但是,我想在打印信息中加入更多的信息,例如行号,文件名,函数名等,这又该怎么做呢?

    2 使用Qt打印行号,文件名,函数名。

    在Qt中,qDebug还可以打印行号,文件名,函数名等信息。但先要使用

    qSetMessagePattern(const QString& pattern)来进行设置;

    例如:

    int main(int argc, char *argv[])
    {
        QString pattern("Debug:%{function}@%{line},%{file}");
        qSetMessagePattern(pattern);
        qDebug();
        return 0;
    }
    

    运行输出:

    image

    qSetMessagePattern具体的用法及语法很简单,大家可以直接在帮助文档中搜索该关键词即可。

    3 在函数首尾加入详细调试信息

    好,现在,我们可以为我们的程序添加详细的调试信息了。

    在main函数中首先调用qSetMessagePattern对qDebug进行输出格式设置。

    然后直接在函数开头创建Tracker对象即可,但是,这会有个问题,打印出的信息是Tracker中的调用信息。

    image

    所以,我们不能将qDebug写在Tracker的构造函数内部。

    而是这样写:

    void MyTest::createWidget()
    {
        Tracker tracker("createWidget");
        qDebug();
    
        //代码段...
    }
    

    但是,这又多了一句qDebug(),这还是有一点啰嗦,那如何把它变成一句话呢。

    办法当然有了,宏,宏就是可以把多句话变成一句话。

    下面,小豆君就给出这个代码跟踪器的完整版。

    新建tracker.h头文件

    #ifndef TRACKER_H
    #define TRACKER_H
    
    #include <QDebug>
    #include <iostream>
    
    //如果想要去掉打印,
    //把下一行注掉即可
    #define TRACKER_DEBUG
    #ifdef  TRACKER_DEBUG
    #define TRACKER \
    do { \
        Tracker tracker(__func__); \
        qDebug(); \
    }while(0);
    #else
    #define TRACKER
    #endif
    
    class Tracker
    {
    public:
        Tracker(const char msg[]):
            m_msg(msg)
        {
            fprintf(stderr, "Enter: ");
        }
    
        ~Tracker()
        {
            fprintf(stderr, "Leave: %s", m_msg);
        }
    
    private:
        const char* m_msg;
    };
    
    #endif // TRACKER_H
    

    测试:

    main.cpp

    #include <QString>
    #include "tracker.h"
    
    int main(int argc, char *argv[])
    {
        QString pattern("%{function}@%{line},%{file}");
        qSetMessagePattern(pattern);
        TRACKER
        return 0;
    }
    

    运行结果:

    image

    好啦,终于创建好了,结果正如我们想象,真是太棒了,它可以用在任何函数调用中,这里小豆君就偷个懒放在了main函数中啦。

    当然,这里主要是为了介绍下Qt的打印文件名,行号知识点,qDebug的打印完全可以更换成 func, FILE, LINE 之类的东东,这样就更具有适用性啦。

    好的,关于追踪器的分享就到这里啦。
    欢迎关注微信公众号"小豆君Qt分享",最新文章都会在公众号第一时间发布,或者你有不懂的问题,关注公众号后,可加好友或进Qt群获得答案。

    相关文章

      网友评论

        本文标题:超实用技巧,代码跟踪器

        本文链接:https://www.haomeiwen.com/subject/tztczqtx.html