Category Archives: Tips

debug tips

最近在協助debug一個crash的問題,紀錄一下debug的思路。 它的現象是當發soap https request時,在ssl handshake階段就出問題(出現有問題的封包內容或是程式crash) crash問題比較麻煩的是有時候發生,有時候正常,但一般情況,如果能夠經常重現,比較能夠快一點界定問題。常見的C/C++程式crash出現是在multithread lock問題導致資料的內部結構不一致或毀損。 crash在openssl內部,觀察comp_methods的值,發現內容怪怪的 ssl compression相關的資訊是在初始化就會做完的,第一個合理的猜測:在初始化的時候,可能有多thread同時做ssl init,導致global object的內部結構race condition,所以先在SSL_library_init裡面插printf看看。 這個版本使用的openssl是1.0.2,參考 https://www.openssl.org/docs/man1.0.2/man3/SSL_library_init.html 發現有多個thread呼叫此init函式多次,理論上init只需要一次就好,因此先確定是哪些地方直接或間接呼叫到。這邊用thread來找,當然在環境許可下,也可以直接設breakpoint看callstack 透過callstack先找到解決呼叫多次的問題, 發現ssl init多次是有個lib內部多次呼叫curl_global_init (當然也多次呼叫了curl_global_cleanup) https://curl.haxx.se/libcurl/c/curl_global_init.html 但事實上SSL_library_init被設計成可以呼叫多次(只是不能reentrant,或是thread同時呼叫),參考: https://libwebsockets.org/pipermail/libwebsockets/2016-May/002366.html 所以以上的狀況看起來不是crash問題的原因 SSL_library_init的開始和結尾地方加上printf,觀察thread id,發現其實 SSL_library_init 執行沒有overlap,也就是造成內部結構的問題不在這 前面提到有lib多次呼叫curl global cleanup看起來很可疑,curl_global_cleanup應該只被呼叫一次,而且是在程式最後結束時。因此第二個合理的猜測,應該是在cleanup處將openssl內部global object destroy。 果然看到在curl global cleanup裡面呼叫到了SSL_COMP_free_compression_methods,因此前面提到有個lib多次呼叫 curl_global_cleanup ,導致其他地方要使openssl function時因為compression methods內容有問題而crash。 … Continue reading

Posted in Tips | Leave a comment

vim

在vim預設會在檔案尾加上 例如 用hexdump工具看 hexdump -C 代表的是該行結束,接下來的內容會出現在新的一行。 在檔尾的EOL在使用unix工具filter時很重要, 像是多個檔案cat 如果沒有完整行,則下一個檔案的內容會直接接上來 或是計算字數行數的wc: 只會計算完整行 如下面的範例 但有時候可能因為某些原因編輯時需要刻意不加上檔案尾的 要關掉可以下 :set noendofline binary 注意: 只有noendofline還不夠,需要設定成binary 參考: https://stackoverflow.com/questions/16222530/why-do-i-need-vim-in-binary-mode-for-noeol-to-work

Posted in Tips | Leave a comment

make整理

makefile: makefile, Makefile, GNUMakefile 一般結構採用top-down,從general寫到details make -n 只印不執行,適合用在debug make規則整理: 第一條rule為default rule (以cmake為例,第一條是 default_target: all) rule分成target, prerequisite, command target: prerequisites command prerequisite定義target的相依項目,command定義生成target make解析順序: 對prerequsites recursive更新檢查,再對target更新檢查(如果prerequsites時間較新,則要重新生成target) target因為是後生成,除非prerequsites有更新,不然一般要比prerequsites新 prerequisite: 除了檔案或是target,也可以是-lNAME (會搜索 libNAME.so => libNAME.a) 但一般不建議利用make來搜尋library是否存在,原因是通常在compiler選項會設定其他的library search path target跟prerequisite比更新時間, 如果沒有prerequisite時,只有不存在target才會生成 同樣的target可以分開寫,會依序執行檢查 libname.a(module.o) lib target: … Continue reading

Posted in Tips | Leave a comment

link -l tips

ld -l namespec搜尋 libnamespec.so => libnamespec.a -l :filename搜尋 filename 另外注意 -l ordering link library需要的dependeny會往後找而不是往前找,如果有前後循環相依的問題可用–start-group archives –end-group來處理 -static or -Bdynamic: it affects library searching for -l options which follow it. 參考: https://sourceware.org/binutils/docs/ld/Options.html

Posted in Tips | Leave a comment

gcc rpath

linux環境在執行程式時,為了將.so library統一放在特定地方而不想更動LD_LIBRARY_PATH或是/etc/ld.so.conf時,可透過在gcc編譯選項加上 -Wl,-rpath=.-Wl,-rpath=./lib 這樣會搜尋執行檔當前目錄的相對路徑(. 即是當前目錄, ./lib 即是當前目錄/lib)但注意當前目錄不等同執行檔所在位置的目錄(也就是從其他目錄執行程式),所以如果.so是放在執行檔所在目錄下的lib,而從其他目錄執行時,一樣會報錯。一般情況預期的相對目錄是相對於執行檔的目錄,這時候就需要加入$ORIGIN 標示。 -Wl,-rpath,’$$ORIGIN/.’ 注意Makefile裡以上是兩個dollar sign確認是否正確可用readelf debug: readelf -d executable|grep PATH 少一個$ ‘$ORIGIN/.’0x000000000000000f (RPATH) Library rpath: [RIGIN/.] 這邊rpath描述的是執行時的,另外有一個rpath-link是編譯時期的參考:https://linux.die.net/man/1/ldhttps://stackoverflow.com/questions/24573732/difference-between-relative-path-and-using-origin-as-rpathhttps://stackoverflow.com/questions/38058041/correct-usage-of-rpath-relative-vs-absolute chrpath

Posted in Tips | Leave a comment

chromium os tips

下載 https://chromium.arnoldthebat.co.uk/?dir=daily 參考此篇安裝 How to Run Google Chrome OS From a USB Drive 其他 進console: Ctrl+Alt+F2 預設帳號: chronos 有些指令是要sudo 例如fdisk 預設是boot from usb 安裝寫入hard disk: root權限 chromeos-install –dst /dev/mmcblk0 (裝置路徑 如/dev/sda) Ctrl+Alt+/ => hot key tips Ctrl + F5 print … Continue reading

Posted in Tips | Leave a comment

版本號convention

Microsoft .NET Assembly major.minor[.build[.revision]] major, minor一般做法都差不多 使用API compatibility, feature來分別(major不同則可能破壞backward compatibility) Build: A difference in build number represents a recompilation of the same source. Different build numbers might be used when the processor, platform, or compiler changes. Revision: Assemblies with the … Continue reading

Posted in Tips | Leave a comment

windows git bash

with VC2015 support 先透過command line 執行 “C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat” amd64 再進入git bash “C:\Program Files\Git\bin\bash.exe” BAT檔呼叫shell script “c:\Program Files\Git\bin\bash.exe” –login -i -c “COMMAND” 需要注意的地方 一般command line需要傳 forward slash參數時 eg. /help 需要加上 forward slash來escape 例如 //help 參考: https://stackoverflow.com/questions/34647591/passing-windows-slash-based-parameters-to-a-program-from-bash-script

Posted in Tips | Leave a comment

std::getline

std::getline時會等待斷行符,但需要注意的是 在使用pipe redirect時,會有flush的問題 boost::process::ipstream child_stdout; boost::process::opstream child_stdin; boost::process::child child_process; child_process = boost::process::child(exe_path, boost::process::std_out > child_stdout, boost::process::std_err > child_stdout, boost::process::std_in < child_stdin); //... child_stdin

Posted in Tips | Leave a comment

comment tips

多行註解時 有時候只是暫時不需要 /* int x; // blah blah */ 要取消掉,最簡單的方式是直接加上// ///* int x; // blah blah //*/ 這樣可以方便以後加回來,因為如果是直接刪掉/*, */ 加回來時常常會忘記要在哪裡開始結束當然 #if 0, #if 1這樣也是一種常見的方式 或是 if(0) {}

Posted in Tips | Leave a comment