從組裝軟體中談談軟體發展
Wen Liao
請注意
● 歡迎
– 隨時中斷及提問題
– 糾正錯誤
– 防無聊
● 手機上網、打電動 ( 記得靜音 )
– 中途離席
範圍
● C 語言
● Linux
目標
分享開發軟體會遭遇
的問題
發展軟體
● 微觀角度
● 宏觀角度
編輯器
編譯器
載入器
組譯器
除錯器
連結器
原始碼
Binary
Hello World
Segmentation fault
http://en.wikipedia.org/wiki/File:CBP_checking_authenticity_of_a_travel_document.jpg
編輯器
編譯器
載入器
組譯器
除錯器
連結器
原始碼
Binary
Hello World
Segmentation fault
http://en.wikipedia.org/wiki/File:CBP_checking_authenticity_of_a_travel_document.jpg
編輯器
編譯器
載入器
組譯器
除錯器
連結器
原始碼
Binary
Hello World
Segmentation fault
http://en.wikipedia.org/wiki/File:CBP_checking_authenticity_of_a_travel_document.jpg
編輯器
編譯器
載入器
組譯器
除錯器
連結器
原始碼
Binary
Hello World
Segmentation fault
http://en.wikipedia.org/wiki/File:CBP_checking_authenticity_of_a_travel_document.jpg
編輯器
編譯器
載入器
組譯器
除錯器
連結器
原始碼
Binary
Hello World
Segmentation fault
http://en.wikipedia.org/wiki/File:CBP_checking_authenticity_of_a_travel_document.jpg
編輯器
編譯器
載入器
組譯器
除錯器
連結器
原始碼
Binary
Hello World
Segmentation fault
http://en.wikipedia.org/wiki/File:CBP_checking_authenticity_of_a_travel_document.jpg
編輯器
編譯器
載入器
組譯器
除錯器
連結器
原始碼
Binary
Hello World
Segmentation fault
http://en.wikipedia.org/wiki/File:CBP_checking_authenticity_of_a_travel_document.jpg
分頁
可以顯示 tab 字元 80 字元分界線
行號
括號邊界指示
折疊邊界
可以顯示空白字元
語法專用色彩
http://blog.vgod.tw/wp-content/uploads/2009/12/vim-cheat-sheet-full.png
有沒有空白字元,差很大
.
有沒有 tab 顯示,差很大
正規表示式
:%s/^/CCU_PLAYER_
:%s/[.*] //g
啊就用鍵盤手動更改
又沒差太多啊?
這是效率的問題
一個 log 30000 行,去掉有
規則但是不相同的字串。
有 50 個命令要加 8 個字元
的 prefix ,然後還要加
postfix
編輯器
編譯器
載入器
組譯器
除錯器
連結器
原始碼
Binary
Hello World
Segmentation fault
http://en.wikipedia.org/wiki/File:CBP_checking_authenticity_of_a_travel_document.jpg
原始碼
● 編寫
● 閱讀
“Programming is the art of telling
another human what one wants the
computer to do.”, Donald Knuth
高德納:「程式語言是
一種告訴別人你要教電
腦去做啥事的藝術。」
Hello World
http://www2.informatik.uni-halle.de/lehre/c/c_hello.html
http://www.ioccc.org/2011/akari/akari.c
main(int /**/n ...
fread(....) ...
程式就是作文 !
http://www.ptt.cc/bbs/CS_TEACHER/M.1238177596.A.796.html
http://zh.wikipedia.org/wiki/%E7%94%9F%E9%AD%9A%E7%89%87
v. s.
朋友
一致性
● POSIX 執行緒是線程的 POSIX 標準,定義了創
建和操縱 thread 的一套 API 。
● HTTP 通訊協定使用的預設埠為80,客戶端送
出要求給伺服器上面的 port 80。當然除了默認
接口外,使用其他的ポート番號也是 OK 的。
改編自 http://zh.wikipedia.org/zh-tw/POSIX_Threads
變
數
命
名
規
則
一
致
TAB
和
空
白
一
致
括
號
格
式
一
致
http://petdance.com/2012/04/the-worlds-two-worst-variable-names/
v. s.
名正言順:從學號找學生姓名
http://petdance.com/2012/04/the-worlds-two-worst-variable-names/
名正言順:捷運學生票扣款檢查
v. s.
深度區塊
巢
狀
前
置
處
理
反正作業 / 產品交出去就
收工了,幹嘛那麼認真?
這是效率的問題
想像一下
● 專案規模
– 上千個原始檔案
– 文件數十個,都是過期的
– 你處於星光 n 班,開發者早就離職
– 裏面充滿
● 變數用單個字元
● 變數意義和內容不符
● 意義不明的縮寫 prefix
● 巢狀前置處理
– 生死狀:出貨期限延後,每天公司被客戶罰錢
– 新增功能,老闆幫你畫押三天搞定
原始碼
● 編寫
● 閱讀
自動程式文件分析產出
編輯器專用的追蹤外掛
grep Auto.*Size * -r
超級比一比
編輯器
編譯器
載入器
組譯器
除錯器
連結器
原始碼
Binary
Hello World
Segmentation fault
http://en.wikipedia.org/wiki/File:CBP_checking_authenticity_of_a_travel_document.jpg
socket.c
zftp-srv
zftp-client
file.c
config.h
client_main.c
srv_main.c
作業:土炮 FTP
生檔案版本一
● zftp-srv
– gcc -c srv_main.c
– gcc -c file.c
– gcc -c socket.c
– gcc -o zftp-srv file.o socket.o srv_main.o
● zftp-client
– gcc -c clint_main.c
– gcc -c file.c
– gcc -c socket.c
– gcc -o zftp-client file.o socket.o client_main.o
生檔案版本二
● zftp-srv
– gcc -o zftp-srv file.c socket.c srv_main.c
● zftp-client
– gcc -o zftp-client file.c socket.c clint_main.c
手動下命令有什麼不好?
最多放在檔案編輯器剪貼
一下就好了。
先求有,再求好。
這是效率的問題
AOSP
● Note: The source download is approximately 8.5GB in
size. You will need over 30GB free to complete a
single build, and up to 100GB (or more) for a full set of
builds.
● 請注意:下載原始碼需要大約 8.5GB 硬碟
空間 。單獨編譯會再需要 30G 硬碟空間,
而全部編譯會需要 100GB 以上硬碟空間。
– 有很大量的程式原始碼
– 編一次要很久的時間
http://source.android.com/source/initializing.html
想像一下
● 假設編一次專案需要 4 個小時
● 每個檔案都編兩下的前提下,修掉上面的錯誤要
幾個小時?
● 算看看
– 第一次編:四小時
– 找錯誤:看運氣和能力
– 修正後重編:再四小時
三年之後又三年,三年之後又三
年,都快十年啦,老大!
需要更聰明的方式 !
● 自動產生程式或 binary
● 只去編上次改過的程式原始碼
● 提供不同設定
● 修改方便
Make
● 用途:讀取 Makefile ,產生 binary
– 執行檔
– Library
● 發明人
– Stuart Feldman, 1977
● 2003
– ACM Software System Award
http://en.wikipedia.org/wiki/Make_(software)
最簡單的規則
● 目標 : 目標需要參考的元件
<tab> 命令
– 範例
● file.o:file.c
gcc -c file.c
socket.c
zftp-srv
zftp-client
file.c
config.h
client_main.c
srv_main.c
樹狀結構
Show Time
第一次全部都編
沒改程式原始碼
所以不需要重編
Show Time (cont.)
只改 client_main.c
就只編 zftp-client
改了 config.h
全部砍掉重練
Make 只是編碼自動化
的選擇之一
編輯器
編譯器
載入器
組譯器
除錯器
連結器
原始碼
Binary
Hello World
Segmentation fault
http://en.wikipedia.org/wiki/File:CBP_checking_authenticity_of_a_travel_document.jpg
GNU Binutils
● 處理 binary 及產生 binary
– ld
– ar
– nm
– ...
喔
可以看到 Symbol ,
所以呢?
搬個家
找不到了
symbol 底家啦
恭迎歸位!
可以從 nm 找到
symbol 以解決 link 不
到 library 的問題
然後呢?
這是效率的問題
情境模擬
● deep_shit.c:(.text+0x7): undefined reference to
`this_is_ridiculous'
● 專案有幾千個檔案,數百個目錄
– 請找出 this_is_ridiculous 是放在那個 library?
不知道 binutil ,就慢慢找吧。
編輯器
編譯器
載入器
組譯器
除錯器
連結器
原始碼
Binary
Hello World
Segmentation fault
http://en.wikipedia.org/wiki/File:CBP_checking_authenticity_of_a_travel_document.jpg
printf 大法
抓蟲
寫東西到位址 0x0 ,嘿嘿
顯示出錯的 statement
列出呼叫順序
印變數內容
還可以直接呼叫函式
我用 printf 去夾,總有一
天夾到出錯的點吧?
有沒有遇過函數呼叫
到九十幾層的?
要 printf 到那一天?
有沒有看過單一個函
數三五百行的?
要塞幾個 printf?
抓漏
借了不還,嘿嘿
找到 1024 bytes 的浪費
連順序、行號都有
發展軟體
● 微觀角度
● 宏觀角度
作業:土炮 FTP
● 預想的規劃步驟:
1.做出 client 送出文字, server 印出來
2.做出 client 送出文字, server 印出來,再送回給
client
3.定義資料結構,最少有命令代碼, Buffer
4.使用自訂資料做 2
5.實作 server 檔案部份功能
6....
Q :要怎麼避免寫下
一個步驟時改壞,發
生砍掉重練的悲劇?
A : Save/Load 大法!
改爛了 ... 重來
千秋萬世直到永遠
情境模擬
長期開發
r133,465
http://nightly.webkit.org/
133,465 是存
133,465 份嗎?
別鬧了!
某專案
● 平台: Windows, MAC OS, Linux
● 新增功能,要怎麼管理?
– 寫一份,複製三份?
● 錯誤修正,要怎麼管理?
– 修一份,複製三份?
某專案 ++
● 團隊人數: 5 位
– 兩個人的功能會更動檔案 A
– 一個人更改了 API
● int iFoo(char *buf, int count);
● void *iFoo(void *buf, int count, int *whatever);
– 要怎麼合併程式?改爛了怎麼回去?
– 上星期三改的程式和現在的程式差別?
– 三個星期前到底改了什麼鬼東西?
– 可不可以拿兩個星期前的版本再增加新的功能?
正解:聰明的
Save/Load 大法
打電動時什麼時後會
想存檔?
解決謎題、打敗小魔王後
女神:「你掉的是金子做斧頭還是銀
子做的斧頭?」
砍掉重練
???
是 否
http://nvie.com/posts/a-successful-git-branching-model/
pcmanx 原始碼紀錄
作者更改時間 更動說明
詳細資料
更改檔案
更改比較
HASH
犯罪現場
兇手就是你! 可疑程式碼
結論
“Programming is a way of thinking, not a rote skill.
Learning about "for" loops is not learning to
program, any more than learning about pencils is
learning to draw.“, Victor Bret
Victor Bret :「程式設計是一
種思考的方式,而不是死記硬
背的能力。學會程式語言的
for loop 語法就以為會寫程
式,就像學會使用鉛筆就以為
會繪畫一樣天真。」http://worrydream.com/LearnableProgramming/
照樣造句
會使用輔助工具就以為精通軟
體開發,就像學會使用鉛筆就
以為會繪畫一樣天真。
Reference
● Google
● Google Image
● Wikipedia
Q & A

軟體組裝心得分享