2018年1月27日 星期六

在 MAC 平台使用 astyle

astyle 是一個幫忙程式碼排版的工作,本篇記錄在 MAC 平台上使用 astyle 的過程。

2018年1月14日 星期日

2017年12月28日 星期四

[QEMU] 模擬一個實際的 ARM Linux 嵌入式系統

本篇紀錄手動自行建置系統的過程。若想盡可能的自動化進行建置,請使用 yocto 或是 buildroot。

1. 安裝 qemu
$ sudo apt-get install qemu-system-arm

2. 建立測試目錄,下載 toochain 以及 kernel
$ mkdir qemu_test
$ cd qemu_test
$ wget https://releases.linaro.org/components/toolchain/binaries/6.4-2017.11/arm-linux-gnueabihf/ gcc-linaro-6.4.1-2017.11-i686_arm-linux-gnueabihf.tar.xz
$ tar xvf gcc-linaro-6.4.1-2017.11-i686_arm-linux-gnueabihf.tar.xz
$ wget https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.14.tar.xz
$ tar xvf ./linux-4.14.tar.xz

3. 修改環境變數
$ vi ~/.bashrc
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
export PATH=$PATH:/home/albert/qemu_test/gcc-linaro-6.4.1-2017.11-i686_arm-linux-gnueabihf/bin
$ source ~/.bashrc 

4. 編譯 kernel
$ cd linux-4.14
$ vi arch/arm/configs/vexpress_defconfig
參考此篇 http://awe31402-blog.logdown.com/posts/528593 
$ make vexpress_defconfig
$ make clean;make
$ ls -al arch/arm/boot/dts/*.dtb
此時應該會出現 vexpress-v2p-ca9.dtb
$ ls -al ./arch/arm/boot/
此處應該會出現 zImage

5. 建立虛擬網卡介面
$ sudo apt-get install uml-utilities
$ sudo tunctl -t tap0 -u albert
$ sudo ifconfig tap0 192.168.7.1 netmask 255.255.255.0 promisc

6. 建立 nfs 使用的 rootfs (之前已經透過 yocto 建立,此步驟省略)

7. 執行程式
$ cd ~/qemu_test
$ QEMU_AUDIO_DRV=none qemu-system-arm -kernel ./linux-4.14/arch/arm/boot/zImage  -M vexpress-a9 -m 512 \
-dtb ./linux-4.14/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \
-append "/dev/nfs nfsroot=192.168.7.1:/srv/nfs/qemuarm rw ip=192.168.7.2:192.168.7.1:255.255.255.0 console=ttyAMA0,115200" \
-smp 1 -net nic,vlan=0 -net tap,vlan=0,ifname=tap0,script=no -nographic

參考資料:
http://awe31402-blog.logdown.com/posts/528593
http://daydreamer.idv.tw/rewrite.php/read-42.html




2017年7月9日 星期日

mp3 檔案移除封面資訊

現在網路上取得的 mp3 檔案,大多已經幫忙作了封面圖片。
但是在比較舊的車用多媒體機器上(例如:舊款的 skoda),其實是無法辨識此資訊的。因此需要先將此資訊移除才能在車機上播放。

以下提供一個 script,可以批次移除所有 mp3 檔案的封面圖片。

#!/bin/bash 
for i in *.mp3 
do ffmpeg -i "$i" -vn -codec:a copy -map_metadata -1 "../${i%mp3}mp3" 
done


2017年5月14日 星期日

mtrace 與 libmemleak

本篇參考 https://en.wikibooks.org/wiki/Linux_Applications_Debugging_Techniques/Leaks
測試文中兩個偵測 memory leakage 的方法,分別是 mtrace 與 libmemleak,並且紀錄測試過程。

1. 使用 mtrace
a. 針對單一程式: 
a1. 在程式碼中 #include  ,並且在需要檢視 leakage 的區間分別加入 mtrace(),muntrace(),程式碼範例可參考此連結。 
a2. 編譯以及偵測方法
$ gcc -g dleaker.c -o dleaker
$ MALLOC_TRACE=test1/mtrace.plain.log  ./dleaker
$ mtrace  ./dleaker  test1/mtrace.plain.log  > test1/mtrace.plain.leaks.log 
a3. 原理簡介
mtrace() 執行之後,會將後續所有 malloc 相關函數全部置換。並且記錄 malloc/free 使用過程。每次配置記憶體使用 "+" 紀錄,釋放記憶體使用 "-" 紀錄,最後統計沒有被釋放的記憶體,就是 memory leakage
如下: 
$ cat  mtrace.plain.log
= Start
@ ./dleaker:[0x80484cb] + 0x9dde378 0xa
@ ./dleaker:[0x80484db] + 0x9dde388 0x14
@ ./dleaker:[0x80484ec] - 0x9dde378
= End 
$ cat mtrace.plain.leaks.log
Memory not freed:
-----------------
Address     Size     Caller
0x09dde388     0x14  at /home/albert/test/libtrace/dleaker.c:13 
a4. 注意:編譯時要加入 "-g" ,這樣 mtrace 才能夠顯示出正確的檔案名稱與行號。 
b. 有時候僅知道行號,還是無法確認問題,最好是有上 backtrace,提供更清楚的呼叫流程,實驗過程如下:
b1. 替換原本的 malloc,在記憶體配置之後,打印 backtrace。
extern void *__libc_malloc(size_t size);
extern void *malloc(size_t size)
{
    void *ptr = __libc_malloc(size);
    fprintf(stderr,"%s\n", __func__);
    _ShowBacktrace();
    return ptr;
b2. 一開始使用下列方法實作 _ShowBacktrace()
#include
static void _ShowBacktrace(void)
{
    void *bt[1024];
    int bt_size;
    char **bt_syms;
    int i;
    bt_size = backtrace(bt, 1024);
    bt_syms = backtrace_symbols(bt, bt_size);
    for (i = 1; i < bt_size; i++)
    {
printf("%s", bt_syms[i]);
    }
    free(bt_syms);
結果程式會掛掉,因為 backtrace() 會再一次呼叫 malloc,因此此項修改會不斷的呼叫 malloc,最後導致 stack overflow。所以需要加上 flag 避免此無限迴圈。相關討論可參考 https://patchwork.ozlabs.org/patch/442890/
若對 mtrace 內部實作有興趣,可以直接參考此檔案 http://code.metager.de/source/xref/gnu/glibc/malloc/mtrace.c


2. 使用 libmemleak.so
a. 首先自行編譯 libmemleak.so (實驗時使用 ubuntu 16.04)
$ sudo apt-get update
$ sudo apt-get install binutils-dev libiberty-dev libreadline-dev doxygen
$ wget https://github.com/CarloWood/libmemleak/releases/download/v0.1.1/libmemleak-0.1.1.tar.gz
$ tar zxvf libmemleak-0.1.1.tar.gz
$ cd libmemleak-0.1.1
$ ./configure
$ make
$ sudo make install 
b. 編譯測試範例
$ git clone https://github.com/alb423/memory_leakage.git
$ cd memory_leakage
$ make  
c. 執行測試程式,動態偵測記憶體資訊
$ export LIBMEMLEAK_SOCKNAME=./memleak_sock
$ cd ~/libmemleak-0.1.1
$ LD_PRELOAD='/usr/local/lib/libmemleak.so' ./hello
$ memleak_control 
d. 若要讓程式一開始就偵測記憶體,需加入 MEMLEAK_CONFIG 定義
$ export MEMLEAK_CONFIG=mtraceinit
$ cd ~/memory_leakage
$ LD_PRELOAD='/usr/local/lib/libmemleak.so' ./dleaker3
$ memleak_control
e.執行結果畫面截圖如下:







3. 編譯 ARM 平台上面的 libmemleak.so
先安裝 arm tool chain 
$ sudp apt-get update
$ sudp apt-get upgrade
$ sudo apt-get install gcc-arm-linux-gnueabihf 
編譯 libcurses.a
$ wget http://ftp.gnu.org/pub/gnu/ncurses/ncurses-5.9.tar.gz
$ tar -pxzf ncurses-5.9.tar.gz
$ ./configure --host=arm-linux-gnueabihf --without-debug --without-ada --without-shared --enable-widec CPPFLAGS="-P"
$ sudo make install DESTDIR=$HOME/
註:此處編譯 library 成功,但是編譯測試程式仍然有誤,上述步驟應該有需要改善。
編譯 libreadline.so 
直接參考此篇即可,最後再安裝到相同目錄 (也許此處可以直接使用靜態編譯)  
$ sudo make install DESTDIR=$HOME/ 
編譯 libmemleak
$ CC=arm-linux-gnueabihf-gcc ./configure --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf LDFLAGS="-L$HOME/usr/local/lib -L$HOME/usr/lib -lreadline -lncursesw"
$ make
$ sudo make install DESTDIR=$HOME/


Reference:
  1. https://how-to-build-for-arm.wikispaces.com/readline
  2. http://www.plunk.org/~hatch/goodies/backtracefilt.C
  3. https://github.com/CarloWood/libmemleak
  4. http://stackoverflow.com/questions/34732/how-do-i-list-the-symbols-in-a-so-file
  5. https://en.wikibooks.org/wiki/Linux_Applications_Debugging_Techniques/Leaks

2017年4月1日 星期六

TDD(Test Driven Development)

www.throwtheswitch.org 設計了一套用來作單元測試的工具。對於使用 TDD(Test Driven Development)開發流程的人員,挺方便的,其中共包含四套工具,分別是 Unity,CMock,CExpection,Ceedling。

摘錄官方說明如下:
  • Unity - Curiously Powerful Unit Testing in C for C.
  • CMock - Automagical generation of stubs and mocks for Unity Tests.
  • CException - Lightweight exception handling for C.
  • Ceedling - Test build management.
以下將針對這幾個工具稍做介紹。