星期五, 6月 27, 2008

找出程式出現segmentation fault的方法

寫程式出現segmentation fault是常有的事。如果這個bug是固定會出現的,那還算幸運,因為你已經知道發生segmentation fault的地方在哪哩,只要好好看source code應該就可以解決了。但是,如果segmentation fault是三不五時才出現,而且沒有一定的規則會使這個錯誤出現,那就很麻煩了。不過,我們其實可以利用signal handler的方式,攔截segmentation fault發生時的錯誤處理方式,就可以輕鬆的找到錯誤發生的那行程式碼了。

原理是這樣的,原本程式如果發生segmentation fault,作業系統在印出錯誤訊息之後就會將該程式結束。可是,這種處理方式對我們並沒有多大的幫助,因為該程式的process都已經從記憶體中一除了。所以,我們要做的就是,改變發生segmentation fault時處理process的方式。改變的方法就是利用signal()這個系統function。其使用方式很簡單,就是指定要攔截的signal以及處理該signal的handler就可以了。

在下面的程式碼中,我們寫了一個超級簡單的signal handler來代替原來系統預設的segmentation fault handler。就是寫一個無窮迴圈將程式停住,這樣我們就可以用gdb來看看到底是哪一行程式碼觸發segmentation fault了。

#include <signal.h>
#include <stdio.h>

void sighandler(int sig)
{
    while(1)
        ;
}

void error_func()
{
    char *msg = NULL;
    printf("%s\n", msg);  // 這裡會發生segmentation fault
}

int main()
{
    signal(SIGSEGV, sighandler);
    error_func();
    return 0;
}

glib的message logging utility

glib提供了一個message logging utility可以讓我們可以在程式執行時輸出一些訊息,顯示程式目前的狀況或是遇到的錯誤。跟printf比起來,glib提供的message logging utility更加多樣化,可以根據不同的執行狀況設定不同等級的訊息。以下列出一個簡單的範例:

#include <glib.h>

int main()
{
    g_debug("%s", "this is a debug message");
    g_log("mytest", G_LOG_LEVEL_CRITICAL, "%s", "This is a critical message");
    g_log("mytest", G_LOG_LEVEL_INFO, "%s", "This is an info message");
    g_log("mytest", G_LOG_LEVEL_DEBUG, "%s", "This is another debug message");
    g_log("mytest", G_LOG_LEVEL_ERROR, "%s", "This is an error message");
    return 0;
}

編譯時記得要加上glib的header file所在位置(用-I)以及library的所在位置(用-L),在我的系統上是以下列方式編譯的:

gcc -g -o test_glog test_glog.c -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include  -lglib-2.0

執行結果如下所示:

** (process:24480): DEBUG: this is a debug message

(process:24480): mytest-CRITICAL **: This is a critical message
mytest-INFO: This is an info message
(process:24480): mytest-DEBUG: This is another debug message

mytest-ERROR **: This is an error message
aborting...
已經終止 (core dumped)

星期三, 6月 25, 2008

強迫使用舊版本的Firefox擴充套件

更新完Firefox後,有時候會遇到套件不支援新版本Firefox的問題。如果不能用的套件剛好又是自己常常使用的套件,心情一定會大受影響。

其實有一個套件叫做Nightly Tester Tools可以幫我們解決這個問題,這個套件可以強迫使用舊版本的套建在新版本的Firefox上。一般來說,如果差異不大用這種方式應該都還可以撐一陣子,等到新的套件版本發行。當然如果新舊版本差異實在是太大,還是會出現套件運作不太正常的現象。

安裝完畢後,重新開啟Firefox就可以看到如下的視窗。其中有些套件前面會出現紅色驚嘆號,那就是原本不能使用的套件。

另外,在畫面的右下方出現了一個非常重要的按鈕Override all compatibility,這就是拯救我們的重要按鈕。

image

按下Override all compatibility之後,會出現Make Compatibile的視窗,如下所示。按下Force Install按鈕之後,就會來硬的了,硬把目前不相容的套件給安裝起來,再次重新開啟Firefox就大功告成了。

image

星期二, 6月 24, 2008

將網址轉成圖片的小工具

這陣子因為比較忙,所以已經有好久沒有寫部落格了。現在事情暫時告一段落了,心情比較輕鬆愉快,剛好今天找到一個不錯的小工具,就順便跟大家介紹一下,做一下業績囉。

利用url2jepg這個小工具,可以讓我們指定一個網址,並將該網址所包含的內容轉存為一張圖片,非常適合用來分享自己所看到的一些資訊。

url2jpeg

使用方式很簡單,只要在上圖上方的空白列中輸入網址,按下右邊Go按鈕後,視窗下方的空白處就會出現輸入網址的網頁內容,如下圖。

url2jpeg_url

接著點選螢幕右邊的Capture bitmap按鈕後,畫面左邊會有一些變化。按下Save image之後就可以將畫面輕鬆地存起來了,而且所存的畫面可以超過整個螢幕一次所能看見的內容,絕對比PrintScreen好用多了。

以下這張就是用url2jpeg所存下的雅虎奇摩首頁喔。

url2jpeg_demo

對了,url2jpeg是還是一個open source的project喔,對寫類似小工具有興趣的人可以下載程式碼好好研讀一下喔。