原创 Linux:利用內核日誌記錄系統啓動時產生的進程樹

前言 之前項目中遇到過一個bug,bug產生的原因是某個程序在兩個不同的啓動腳本中被同時啓動了兩次,系統中出現了兩個實例。這個程序在代碼內部沒有保證單實例,靠shell腳本的pidof(1)命令保證單實例,然而因爲兩個啓動腳本的啓

原创 QString和QByteArray

QString有一個未標記爲explicit的構造函數QString(const QByteArray &ba),導致許多形參爲QString的函數可以接受類型爲QByteArray的實參,時間久了會會以爲這兩個類可以隨意混用,但

原创 Linux C/C++調試之五:程序運行耗時的組成

分析程序出現的啓動緩慢、響應緩慢和操作卡頓等性能問題時,第一步不該是打開代碼編輯器瀏覽我們的代碼,而是首先確定問題是否發生在我們的代碼中,簡單點的方法就是打開top做一個大致的判斷,看一看各CPU的us、sy、id耗時的佔比都是多

原创 利用libclang提取C++中enum值與名的映射

之前的一篇文章中,有思考過如何將enum的值與名進行映射,其中一種方法是利用工具進行預處理生成。最近由於項目中有類似的需求,所以學習了libclang,寫了一個小工具實現映射。 整體流程非常簡單: 匹配enum聲明的AST節點。

原创 Linux C/C++調試之一:利用LD_PRELOAD機制監控程序IO操作

#引言 有時,我們爲了分析程序的某些問題(例如性能問題),需要對程序的IO操作的頻率耗時等數據進行監控。就以經常調用的read和write函數爲例,如何監控程序中所有上述兩種操作,同時進行計時呢?使用gdb打斷點自然是個方法,這樣

原创 C++:shared_ptr的隱式轉換

最近遇到這樣一個編譯問題,代碼是這樣的: #include <memory> #include <iostream> class Base { public: virtual ~Base() {} }; class D

原创 四種迷宮生成算法的實現和可視化

(上圖是使用隨機化Prim算法生成一個200x200的迷宮的過程) Github項目地址:maze 前言 本文中的迷宮指的是最常見的那種迷宮:迷宮整體輪廓是二維矩形,迷宮裏的格子是正方形的,格子上下左右各相鄰另外一個格子(邊和角

原创 使用bash和graphviz分析並可視化C/C++源文件依賴關係

流程 流程並不複雜: 使用find命令搜索指定目錄所有C/C++源文件 掃描所有源文件,使用cpp(The C Preprocessor)過濾掉註釋後,使用sed提取#include,生成依賴條目 將所有依賴條目拼成.dot文件

原创 clang:FunctionDecl::isOutOfLine()和FunctionDecl::isInlined()能同時返回true嗎?

最近讀clang源碼時發現這麼一段代碼: FunctionDecl *FD = ...... ...... if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) { ......

原创 Qt:爲什麼QGraphicsView設置Antialiasing/SmoothPixmapTransform沒生效?

QGraphicsView::setRenderHint有兩個常用的選項:QPainter::Antialiasing和QPainter::SmoothPixmapTransform,前者是用來打開反走樣功能,後者用來在對圖片進行

原创 bash的幾種特別的I/O重定向語法

下面這幾種重定向語法都很簡單,容易記住: ls > stdout.tx # 用標準輸出覆蓋stdout.txt ls not-exist-file 2> stderr.txt # 用標準錯誤覆蓋st

原创 條件變量爲什麼要和互斥量一起使用?

一個簡單的使用條件變量的場景:主線程從stdin讀取一個字符串,然後由echo線程打印這個字符串,正確的代碼是這樣的: #include <iostream> #include <condition_variable> #incl

原创 當std::bind遇到非靜態類成員函數

之前看項目代碼在實現表驅動方法時,經常會遇到這樣的代碼: // enum { ID0, ID1, ID2 }; // std::map<int, std::function<void()>> Foo::m; // void Foo

原创 Linux C/C++調試之四:callgrind的侷限

在上篇文章中我介紹了callgrind的大致用法,可以看出來,callgrind是一個非侵入式的,使用起來也很傻瓜的調優工具。初用時感覺這個工具非常趁手,是個程序都想用callgrind去分析一下。但深入使用後發現,callgri

原创 Linux C/C++調試之三:性能分析工具callgrind的使用

callgrind是valgrind工具套件中用於分析程序性能的一個工具,它能夠得到粒度爲函數、代碼行和指令級別的性能數據,具體來說,我們可以得到某個函數、某行代碼、某條指令處累計執行了多少條指令。 我們看一個實例: // foo