在linux平台下的程式寫了很多,但是調試感覺不是很熟悉。這幾天專門去學習了一把,搞了一下so的調試。首先給出兩個源檔案,即調用程式和被調用動態庫程式的原始碼。調用程式原始碼:main.cpp
#include <stdio.h>#include <dlfcn.h>#include <link.h>#include <stdlib.h>int main(){ void *dlh=NULL; int (*printmsg)(char *pMsg); int result; printf("load library!/r/n"); dlh=dlopen("./libprint.so",RTLD_LAZY); if(dlh==NULL) { printf("load library fail!"); return -1; } printf("search function!/r/n"); printmsg=(int (*)(char *))dlsym(dlh,"dj_print"); if(printmsg==NULL) { printf("search function fail!"); dlclose(dlh); dlh=NULL; return -2; } printf("call function.../r/n"); result=printmsg("libarcomm succeed!/r/n"); printf("call result %d./r/n",result); dlclose(dlh); return 0;}
被調用動態庫程式原始碼:libprint.cpp
#ifdef __cplusplusextern "C"{#endif#include <stdio.h>int dj_print(char *pBuffer){ if(pBuffer==NULL) { return -1; } return printf("%s",pBuffer);} #ifdef __cplusplus} #endif
然後編譯他們。這裡就不用寫makefile檔案的。下次再寫一下怎麼寫makefile檔案。
g++ -ggdb3 ./loadso.cpp -ldl -shared
g++ -ldl -Wall -shared -ggdb3 -fPIC -o libprint.so ./libprint.cpp
編譯好了以後會產生一個a.out和libprint.so檔案。然後運行
[dj@dj_linux sodemo]$ gdb ./a.out
輸入l將會列出當前位置的原始碼如下:
(gdb) l1 #include <stdio.h>2 #include <dlfcn.h>3 #include <link.h>4 #include <stdlib.h>56 int main()7 {8 void *dlh=NULL;9 int (*printmsg)(char *pMsg);10 int result;
如果你想在so中的dj_print函數暫停一下,可以輸入如下命令:
(gdb) break dj_print
Function "dj_print" not defined.Make breakpoint pending on future shared library load? (y or [n]) yBreakpoint 1 (dj_print) pending.
後面的提示是說是否在調用動態庫的時候設定斷點。選擇y就可以了。然後輸入run
(gdb) runStarting program: /home/dj/work/src/sodemo/a.out load library!Breakpoint 2 at 0xe085e7: file ./libprint.cpp, line 11.Pending breakpoint "dj_print" resolvedsearch function!call function...Breakpoint 2, dj_print (pBuffer=0x804876e "libarcomm succeed!/r/n") at ./libprint.cpp:1111 if(pBuffer==NULL)
這個時候就會在設用dj_print的時候暫停了。你也可以用list命令看一下將要執行的代碼
(gdb) l6 #include <stdio.h>7 #include "libprint.h"89 int dj_print(char *pBuffer)10 {11 if(pBuffer==NULL)12 {13 return -1;14 }15 return printf("%s",pBuffer);
然後可以一步一步調試了。別外要說明的是當原始碼跟可執行程式不在同一個目錄的時候可以將原始碼的目錄加入到gdb尋找的目錄中。具體命令如下:
show dir顯示現在查以的目錄
dir <來源程式目錄>上面的命令就是將來源程式目錄加入到當前的尋找目錄中去。你可以多次運行這個命令,加入多個尋找目錄。具體如下
(gdb) dir .Source directories searched: /home/dj/work/src/sodemo:$cdir:$cwd
如果你直接輸入dir斷行符號的話,那就是清除你之前加入的尋找目錄。