這種問題的解法之一是 unit test,用充分的測試保護那個 module,就能確保之後的修改比較不會改壞原本好的東西。但是那個 project 還沒裝 unit test framework,我也不熟,而且有點時間壓力,我認為先做出一個堪用的版本比架起 unit test framework 重要。
$ gcc -shared foo.o -o foo.so /usr/bin/ld: foo.o: relocation R_X86_64_32S against `sum' can not be used when making a shared object; recompile with -fPIC
Relocation section '.rela.text' at offset 0x240 contains 2 entries: Offset Info Type Sym. Value Sym. Name + Addend 00000000000d 000300000002 R_X86_64_PC32 0000000000000000 .data - 8 000000000011 000a0000000b R_X86_64_32S 0000000000000000 sum + 0
Relocation section '.rela.eh_frame' at offset 0x270 contains 1 entries: Offset Info Type Sym. Value Sym. Name + Addend 000000000020 000200000002 R_X86_64_PC32 0000000000000000 .text + 0
$ readelf -r foo.o.pic
Relocation section '.rela.text' at offset 0x278 contains 2 entries: Offset Info Type Sym. Value Sym. Name + Addend 00000000000d 000b00000009 R_X86_64_GOTPCREL 0000000000000000 sum - 4 000000000014 000300000002 R_X86_64_PC32 0000000000000000 .data - 4
Relocation section '.rela.eh_frame' at offset 0x2a8 contains 1 entries: Offset Info Type Sym. Value Sym. Name + Addend 000000000020 000200000002 R_X86_64_PC32 0000000000000000 .text + 0
程式裡可能有很多 function 在執行過程中不會或很少被用到,例如錯誤處理跟少用的功能。一開始執行就 link 所有 library 裡的 function 顯然有點浪費,畢竟可能花時間 link 了卻沒用到。如果等到 function 第一次被使用時才 bind symbol(找 symbol、relocate 等等)可以加快程式啟動的速度,這個方法稱為 lazy binding。
static link 拆分了可執行檔,讓不同人或組織可以開發自己的 module,最後再 link 成執行檔。隨著系統變複雜,OS 裡有多個 process 在執行,當多個 process 以 static linking 連結相同的 library 時,例如擁有 printf() 的 standard library,memory 會有多份類似的 library 程式碼,造成浪費。
Symbol table '.dynsym' contains 13 entries: Num: Value Size Type Bind Vis Ndx Name ... 8: 0000000000000660 20 FUNC GLOBAL DEFAULT 11 foo ... Symbol table '.symtab' contains 53 entries: Num: Value Size Type Bind Vis Ndx Name ... 46: 0000000000000660 20 FUNC GLOBAL DEFAULT 11 foo ...
lib.so 的 symbol table 有給 dynamic link 用的 .dynsym section 跟一般的 .symtab section。
1 2 3 4 5 6 7 8 9 10
$ readelf -s main.dyn
Symbol table '.dynsym' contains 12 entries: Num: Value Size Type Bind Vis Ndx Name ... 4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND foo Symbol table '.symtab' contains 65 entries: Num: Value Size Type Bind Vis Ndx Name ... 56: 0000000000000000 0 FUNC GLOBAL DEFAULT UND foo
工程師很喜歡「找 general 的方法」跟「確認出清楚的邏輯」,畢竟這樣程式比較好寫。但是這東西不只原本的邏輯可能不清楚,還「一定會變動但無法預期會如何變動」,以至於後來我放棄找 general 的方法,而是把問題切得更細再組起來,其實就是 divide and conquer。 甚至稍微放寬對清晰邏輯的要求,改用擴充性比較好的做法。只要變動的時候可以用比較低風險──不會影響到其他部分──的方式因應就好,如此,無論是現在邏輯可能再修正或者之後增加目前沒有的東西都能處理。
./mcah run -d --debug gdb> r tests/html/about-mozilla.html ...blahblah
所以有在動啊……
./mach run -d tests/html/about-mozilla.html -o output.png 輸出圖檔,圖片也是一片白。
update 系統再 try 也不行。
用 VM LMDE 跑 pre-built 出現其他 error 0:1(10): error: GLSL 1.50 is not supported. Supported versions are 1.10, 1.20, 1.30, 1.00 ES, and 3.00 ES,可能跟 VM 沒 support OpenGL 有關,有點岔題所以不管。
最早遇到 MVC 是在網頁 framework,所以一直理解 model 為「資料」。後來發現 model 好像不只是資料,有文件說 model 包含商業邏輯,但我還是說不上來到底是什麼。現在的理解是絕大多數的程式都是 model,只是把 view 拆出去並且引進 controller 作為類似中介的角色。