發表文章

讀出 gcc/g++ 編譯的參數

這裡看來的,官方文件說 -grecord-gcc-switches 預設有開,所以滿可靠的。使用例子: $ g++ f.cpp -std=c++11 -g -o f $ readelf --debug-dump f | grep DW_AT_producer DW_AT_producer : (indirect string, offset: 0xded): \ GNU C++11 5.4.0 20160609 -mtune=generic -march=x86-64 -g -std=c++11 -fstack-protector-strong DW_AT_producer DW_FORM_strp 但用 clang 編的資訊就沒存完整: $ clang++ f.cpp -std=c++11 -g -o f $ readelf --debug-dump f | grep DW_AT_producer DW_AT_producer : \ (indirect string, offset: 0x0): clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final) DW_AT_producer DW_FORM_strp

(C/C++ ) 如何在 Linux 上使用自行編譯的第三方函式庫

以使用 LevelDB 為例。 抓好並編好相關檔案,編譯方式見第三方函式庫附的說明:$ ls include/ # header files leveldb/ $ ls out-shared/libleveldb.so* # shared library out-shared/libleveldb.so@ out-shared/libleveldb.so.1@ out-shared/libleveldb.so.1.20* 下面的例子用 clang++ 編譯,這裡用到的參數和 g++ 一樣。 問題一:找不到 header$ clang++ sample.cpp sample.cpp:5:10: fatal error: 'leveldb/db.h' file not found #include "leveldb/db.h" ^ 1 error generated. 解法:用 -I 指定 header 位置 問題二:找不到 shared library$ clang++ sample.cpp -I include/ /tmp/sample-2e7dd8.o: In function `main': sample.cpp:(.text+0x1e): undefined reference to `leveldb::Options::Options()' sample.cpp:(.text+0x6f): undefined reference to `leveldb::DB::Open(leveldb::Options const&, std::string const&, leveldb::DB**)' sample.cpp:(.text+0x10c): undefined reference to `leveldb::Status::ToString() const' sample.cpp:(.text+0x7d0): undefined reference to `leveldb::Status::ToString() const' clang: error: linker command failed with exit code 1 (u…

除錯技巧:在 Ubuntu 上找出第三方函式庫的程式碼

這篇藉由一個小例子說明如何使用 gdb, locate, apt-file, apt-get 找出問題原因。藉由取得第三方函式庫的程式碼,可以減少瞎猜的時間。 問題我發現某個程式會不預期的結束。但它不是 crash,沒有 core dump 可看。 用 gdb 找出怎麼結束的先用 gdb attach 程式,繼續操作。程式結束時 gdb 顯示是呼叫 exit() 結束的。 於是再執行一次,這次用 gdb 在 exit 設中斷點再繼續執行。取得的 backtrace 如下: #0 __GI_exit (...) at exit.c:104 #1 0x00007fdd27f60408 in _XDefaultError (...) at ../../src/XlibInt.c:1414 #2 0x00007fdd27f6054b in _XError (...) at ../../src/XlibInt.c:1463 #3 0x00007fdd27f5d5e7 in handle_error ...) at ../../src/xcb_io.c:213 #4 0x00007fdd27f5e687 in _XReply (...) at ../../src/xcb_io.c:699 #5 0x00007fdd27f45346 in XGetWindowProperty (...) at ../../src/GetProp.c:69 #6 0x00007fdd2825db30 in XmuClientWindow () from /usr/lib/x86_64-linux-gnu/libXmu.so.6 ... 看 backtrace 沒什麼頭緒,都是第三方函式庫的程式。照 XmuClientWindow() 的說明,它可能會失敗,但它不該直接呼叫 exit()。先找 XmuClientWindow 的原始碼,看看有什麼線索。 用 Ubuntu 的 package 系統找出原始碼首先用 apt-file 找出 libXmu.so.6 在那個套件 (第一次執行需先跑 apt-file update 更新索引): $ apt-file search /usr/lib/x86_64-linux-gnu/libXmu.so.6 libxmu6: /usr/lib…

NAT64 和 DNS 64

參考資料NAT64 and DNS64 in 30 minutesDNS64與NAT64的網路佈署圖 IPv4 要用完了 (喊了十幾年, 最近是玩真的了), 在骨幹和 server 都轉成 IPv6 的過渡期, 用戶端也要轉換, 不然 server 是轉心酸的。但是大量 server 還是用 IPv4, 所以要讓 client 能同時支援 IPv4 和 IPv6才行。如果你是網管, 希望讓用戶可以同時連 IPv4 和 IPv6 的位置, 一個可能的作法是建置「純 IPv6 環境」, 永遠拿到 IPv6 位置, 永遠連 IPv6 的位置。但要讓 IPv6 client 也能連 IPv4 位置, 需要 NAT64+DNS64 幫忙處理。 原理是 DNS64 會同時查 IPv6 和 IPv4 的位置, 有 IPv6 就用 IPv6, 沒有就轉換 IPv4 為 IPv6, prefix 配合 NAT64 的設定, 讓 client 連往該 IP 的封包會先經過 NAT64 router。第二份 slide 有詳細的流程圖。 然後 NAT64 會再轉換 IPv6 的封包成 IPv4 出去, 無縫接上用 IPv4 位置的 server。至於 client 收到 DNS64 回應的正常 IPv6 位置, 就透過一般 router 直接出去, 不用經過 NAT 64。 對設計後端 server 的人來說, 有愈多用戶可以連 IPv6 位置, 有愈高的機會考慮用 IPv6 位置。對 app 開發者來說, 了解有些用戶的網路環境會用 DNS64+NAT64 的配置, 所以要用 domain name 連上自家 server, 這樣自家 server 用 IPv4 或 IPv6 都會通。

查詢 Web 標準是否有支援

如何 git merge 更改檔名的檔案

參考資料:http://stackoverflow.com/questions/4722423/how-to-merge-two-branches-with-different-directory-hierarchies-in-git 如果在 branch 裡有 rename file X 為 Y, 並且 master 和 branch 都有改 X ( Y ) 的內容。那麼, merge master 的時候, git 可能會回報 master 的 X 被刪除了, 造成 merge conflict (deleted in ... and modified in ...)。 解法是提高 merge.renameLimit, 比方說 git config merge.renameLimit 999999999。merge 時間會久一點, 但 git 會找出 X 在 branch 裡已被 rename 成 Y。

用 vimdiff 作 git merge

參考文章http://www.rosipov.com/blog/use-vimdiff-as-git-mergetool/http://yodalee.blogspot.tw/2013/03/vimdiffgit-merge-conflict_28.html 以前我用 kdiff3, 後來需要在 terminal merge, 改試 vimdiff, 也很好用。 設定:$ git config --global merge.tool vimdiff 執行 (在 git merge 有 unsolved conflict 後):$ git mergetool UI 顯示: 左上: LOCAL 中上: BASE 右上: REMOTE 下面: 編輯區 vim 指令:[c, ]c: 在 hunk 間移動, 和 vim-gitgutter 一樣 搜 "<<<<" 找 conflict:diffget LOCAL: 目前的 hunk 選用 LOCAL:diffget REMOTE: 目前的 hunk 選用 REMOTE:diffupdate: 更新 diff 畫面 修改後存檔離開, 會自動 resolved conflict。無修改離開會跳過 merge, 維持原本狀態。 其它查看 merge 狀態:$ git status 如果整份檔案都要選用 LOCAL, 改用 git 指令:$ git checkout --ours 全用 REMOTE:$ git checkout --theirs