顯示具有 programming tool 標籤的文章。 顯示所有文章
顯示具有 programming tool 標籤的文章。 顯示所有文章

2013年1月22日 星期二

code formatter

有些code從網路下載下來格式凌亂不堪,手邊有個code formatter美化一下,容易閱讀的多
http://astyle.sourceforge.net/

跟vim整合
http://www.jukie.net/bart/blog/vim-and-linux-coding-style

2013年1月16日 星期三

GDB指令筆記

留一下備忘錄
  • break/b : 設定break point,break main, break 10, break test.C:10
  • run/r : 執行
  • backtrace/bt : 列印出stack frame, bt 10, bt full 10
  • print/p : 列印出變數數值
  • info register : 列印出regiseter內容
  • next/n : step by step
  • step/s : step into
  • continue/c : 繼續執行
  • watch expression : 監視變數
  • delete # : 刪除break point或者 watch point
  • set variable var=expression : 設定變數內容
  • generate-core-file
  • info proc : 印出在/proc內容
  • break #breakpoint if condition : 設定中斷點條件
  • condition #breakpoint condtion : 為中斷點設定條件
  • condition #breakpoint : 取消中斷點的條件
  • clear : 清除所有中斷點
  • disable : 暫停使用所有中斷點
  • enable : 啟用中斷點
  • info b : 列出所有中斷點
  • set history/show history : 顯示出使用過的指令
  • set history save/show history save : 儲存使用過的指令
  • source file_name : 載入設定檔案

commands #breakpoint
...
...
end
在中斷點中斷時執行的指令
define #command
...
...
end
document
...
...
end
可以用來設定指令,比方說
define li
  x/10i $pc
end
document li
  list machine instruction
end

help li則是印出指令說明

使用core file當作gdb的輸出的時候,必須加上-s exec_file或者在進入gdb後file exec_file,才可以載入symbol table

attach pid將某個process加入gdb模式,使用detach離開

參考資料:
http://www.study-area.org/cyril/opentools/opentools/debug.html

2013年1月14日 星期一

你一天寫多少source code?

LOC(lines of codes)雖然是一個非常不精準的指標,卻也是一個非常好用的指標,我大概計算過,我每天只能產出100行程是,跟大多數的人差不多,就是第一天就可以生產五百到一千行,然後開始debug,一個星期大概只有一天拿來寫code,跟著有兩三天用來檢視設計跟重新規劃code(我不大喜歡看到兩個同樣的code blocks),有兩三天用來debug,結果平均下來就只有一百行勉強算是bug-free(畢竟現實專案沒有人可以宣稱他的code是bug-free的)

講了一堆,如何計算code?簡單的方式有

find . \( -name '*.h' -or -name '*.c' \) -exec cat "{}" ";" | wc -l

其實更廣泛的工具有,他支援多種語言
http://cloc.sourceforge.net/

2012年3月4日 星期日

toolchain安裝工具

http://elinux.org/Toolchains
建立toolchain有時候是浩大工程,或者說如果需要開發很多projects,如何建置適合的toolchain很花費功夫,有人開發出了buildroot之類的工具,但是版本也很多,特色各有差異,剛好爬文爬到,就記錄一下人家的說法

2012年2月14日 星期二

有趣的ELF觀察

如果要寫個印出"Hello World!"字串的程式,大概很多人都會,簡單的用printf就可以達成,不消幾行codes,那麼大小呢?

  • a.out是使用一般編譯(gcc test.c這樣),因為library放在外面,所以大小大約7kB
  • b.out跟著使用-static引入所有lib,可怕的大啊,變成了570kB左右的大小,請比較一下busybox,就可以感受到busybox的威力,小小印個"Hello World!"就要這樣的size,busybox可是支援數十道指令阿!!
  • 最後是tinytest.c所編譯出來的,他刪除了呼叫glibc.lib的必要性,並且使用了組合語言,整體大小就小了很多


tinytest.c內容如下
編譯指令如下
gcc -c -fno-builtin tinytest.c
ld -static -e mymain -o tinytest tinytest.o
可以注意到整個程式沒有main(),我們使用ld指令來指定entry function,exit()這個function其實可以從include/unistd.h內拷貝出來,對於組合語言有興趣的可以參考參考資料的連結

簡單從sections觀察一下



也是依序從a.out, b.out, tinytest,可以看到a.out sections最多,然後b.out的一些.data等最大,顯然引入很多"不必要"的資訊,最後tinytest相對section跟section size小很多,如果有興趣可以再去研究symbol table可以得到更多的答案,但就此打住吧。
我想有人會想問,還可以更小嗎?答案是可以的,至少把.comment這個section去除,就可以省下不少空間,也可以把.strtab ...等的section除去,還可以進步縮小,但這些大多只有在小程式有用,或者在極度記憶體限制下才來的必須。畢竟現在開發時間、移植性以及電腦速度大多遠大於我們對於performance以及optimization的過度追求,但也不表示程式能放棄品質於不顧,隨意寫出O(n^k)這樣的code(k>=2)

參考資料
http://c9s.blogspot.com/2008/06/linux-gnu-as-1.html

elf中的header跟section header

從wikipedia借來一張圖
整個elf檔案包裝大致上類似這樣,如果稍微寫過一些解析圖片或者特定檔案格式的人都知道,file header就是用來儲存跟這個檔案有關的資訊,比方說jpg裡面就會有些圖片大小,壓縮方式跟比例等等的資訊。上圖片中ELF header存有的資訊可以用elfread -h來觀察
很多資訊網路上可以找到,在/usr/include/elf.h上也有定義相對應的結構(c struct),在此就不說了,先提到program header table是optional,在圖片中248 (bytes into files)上,可以看到它是0 bytes。

  • 第一個紅色框框得知section header table相對於檔案的位移(offset),方便直接移動到那處讀取每個section的section header,因為section header是包含許多重要屬性,因為知道有那些section對ld是很重要的
  • 第二個紅色框框可以看到這個檔案包含了多少個sectioin


接著用readelf -S來讀取每個section的資訊
這部分的資料可以從header section table裡面取得,有興趣一樣可以在/usr/include/elf.h上找到對應的結構,其中也包含了各種重要的屬性

參考資料:
http://blog.chinaunix.net/space.php?uid=20547746&do=blog&id=1647100
http://beye.sourceforge.net/en/beye.html

用objdump指令觀察ELF檔案

objdump是個用來觀察object code的好幫手,雖然readelf可以取代他大部分的工作,首先先有個code

很簡單的code,基本學過C望文生義

程式大致上可以分為兩部分,執行的資料跟處理資料的程式碼。obdump參數h表示要列出sections,object code由許多sections所組成,其中.txt這個section是處理資料的程式碼,.data與.bss是資料的section,還有其他給ld用的區段 size指令可以看出各個section的大小

s這個參數表示要使用16進位表示法顯示出object code中的各個區段,可以看到一些read only的資料室蠻明顯的,但是.txt基本上不是人看得,最後可以觀察到.comment這個section是可以省略掉的資訊

d這個參數讓object code可以反組譯成assemble code,方便我們觀察程式,有些時候只能拿到library的時候,就只能從這裡挖到一些資料了,雖然可讀性沒有C好,但是至少比binary code強

最後x參數可以所是列出了所有資訊,不只包含了h這個參數,還列出了許多symbol table跟一些需要重新定位label資訊
這裡觀察到兩個有趣的地方,兩個變數被寫進了不同的區段,有初始化的m被寫入了.data內,沒有的則被寫入了.bss,printf不見了,其實被取代成了puts,這是compiler優化的結果,puts在處理只有字串的資訊比printf有效率,UND表示尚未定義在這個object code中

參考資料:
http://www.jollen.org/EmbeddedLinux/Executable_Linking_Format.html
http://www.jollen.org/blog/2007/03/elf_program_loading_1_segment.html
http://www.jollen.org/blog/2007/03/elf_program_loading_2_pht.html
http://www.study-area.org/cyril/opentools/opentools/x909.html

2012年2月9日 星期四

開發工具

這裡簡單紀錄一下我所看到的開發工具

  • gdb : 不用多說了,這根本是一定會提到的
  • strace : 用來追蹤system call
  • ltrace : 用來追蹤library的function call
  • mtrace : 追蹤記憶體配置,如malloc()、realloc()、free()
  • dmalloc : 比上面更強大,但是更複雜的工具
  • readelf : 了解執行檔案組成,跟裡面更種section的部分
  • objdump : 跟readelf有些功能從跌,但是有個好處是可以反組譯object code
  • objcopy : 格式或者轉換一個binary object code,如塞入一個section到elf
  • strip : 刪除binary內的symbol跟debug information
  • ldd : 顯示lib相關性
  • nm : 顯示object code的symbols,如function call names等


2012年2月7日 星期二

cmake入門(2)

主要參考wiki教科書上面,wiki教科書上的cmake入門是一個非常好的參考
首先先看架構
先開一個專案目錄,假設叫做hello好了,底下目錄架構如下
  • src
    1. app
      1. hello.c
      2. CMakeLists.txt
    2. display
      1. display.c
      2. CMakeLists.txt
    3. CMakeLists.txt
  • build

hello.c跟display.c就如我之前寫的,只是個示範用的,這裡重點是三個CMakeLists.txt檔案內容

src/app/CMakeLists.txt

  cmake_minimum_required(VERSION 2.6)
  project(hello)
  include_directories(${CMAKE_SOURCE_DIR})
  add_executable(app hello.c)
  target_link_libraries(app display)

src/display/CMakeLists.txt
  cmake_minimum_required(VERSION 2.6)
  project(display)
  add_library(display display.c)

src/CMakeLists.txt
  cmake_minimum_required(VERSION 2.6)
  add_subdirectory(display)
  add_subdirectory(app)

app目錄底下的CMakeLists.txt可以看到add_executable表示我們主要建立執行檔案所必須編譯的檔案,後面看到target_link_libraries表示需要連結的library
display目錄CMakeLists.txt的add_library表示要建立library,望文生義,至於要建立是static lib, dynamic lib or module請參考wiki文件,以後有機會再談,這裡建立的是static lib
src目錄下CMakeLists.txt很簡單的表示有兩個必須建立的項目

跟著回到build目錄底下,執行cmake ../src,cmake會讀取src目錄下的CMakeLists.txt去執行子項目,要在src底下執行cmake .也是可以,但是缺點是,所有編譯過程的檔案跟cmake產生的檔案會跑到src目錄底下,這樣某種程度"汙染"了src目錄的整潔度,應該讓src儘量保持乾淨,就放source code就好

2012年2月4日 星期六

cmake入門(1)

簡單的說,要先安裝cmake這工具才能開始,這東西主要幫主程式設計師產生Makefile,Makefile是一堆編譯步驟的集合,從source code到binary過程很簡單,但是程式愈寫愈多的時候,過程就會有點繁瑣,所以Makefile就衍生出來,不過Makefile其實也有點痛苦,另外一開始是有平台相關性的,有人就想把這工作在簡化,衍生出cmake這工具

介紹結束,首先準備一個目錄,來存放source code與cmake需要的檔案,分別就是helloworld.c跟CMakeLists.txt這兩個,所以這目錄底下就只有這兩個檔案
底下是CMakeLists.txt的內容,至於helloworld.c這程式碼自己寫吧,裡面其實只是印出hello world字串

接著如果說你一切都沒有寫錯,就是跟著兩個指令
cmake .(注意有個點)
make

結果類似這樣囉,跟著就可以執行./helloworld
可以參考舊有工具automake跟autoconf,http://os.51cto.com/art/201003/185711.htm,有點小複雜
如果專案不大,最佳的方式還是直接gcc helloworld.c -o helloworld

FILE(GLOB Mac_CPP “*_Mac.cpp”) FILE(GLOB Mac_H “*_Mac.h”) LIST(APPEND Mac_Sources ${Mac_CPP} ${Mac_H}) 上次討論到的. 怎麼把file list抓下來,然後不用一個file一個file加入的方式


參考:
http://andescore.blogspot.com/2009/07/cmake.html
http://zh.wikibooks.org/wiki/CMake_%E5%85%A5%E9%96%80
http://blog.csdn.net/dbzhang800/article/details/6314073