背景
在工作中調試sqlite3相關代碼的時候,調用printf()打印sqlite3_exec()的執行日志;因為sqlite3_exec()保存日志的參數傳入時為NULL,且沒有執行錯誤,所以再傳入printf()時仍然為NULL;如果判斷日志不為空時才打印,則無段錯誤。
分析
Core was generated by `./hello.cgi'. Program terminated with signal SIGSEGV, Segmentation fault. #0 strlen () at ../sysdeps/x86_64/strlen.S:106 106 ../sysdeps/x86_64/strlen.S: 沒有那個文件或目錄. (gdb) bt #0 strlen () at ../sysdeps/x86_64/strlen.S:106 #1 0x00007f2c160d4fa2 in _IO_puts (str=0x0) at ioputs.c:35 #2 0x000055b86da5ba4b in sqlite_mytest () at hello.cc:239 #3 0x000055b86da5b1f9 in main () at hello.cc:67 (gdb) quit
根據gdb調試信息,定位到 :
#0 strlen () at ../sysdeps/x86_64/strlen.S:106
錯誤產生的原因,就是在hello.c的239行調用printf()時入參為NULL,printf()內部調用最終將其傳遞到strlen()
關於printf()入參NULL的分析,可以再作了解。
總結
對prinf()的入參作非空判斷
strlen()在glibc內部沒有作非空判斷,不可傳NULL。