一、编译环境
编译依赖库:依赖库均支持gcc 4.8.2
编译器版本:gcc version 4.8.2 (GCC),使用gcc4.8.2安装目录下的gcc、g++
二、运行环境
OS版本:Linux version 2.6.32_1-17 (gcc version 4.4.4 (Red Hat 4.4.4-13) (GCC) ) #1 SMP CentOS release 4.3 (Final)
默认gcc:/usr/bin/gcc gcc version 3.4.5
默认gdb:/usr/bin/gdb GNU gdb Red Hat Linux (6.3.0.0-1.96rh)
gcc4.8.2: /xx/yy/gcc-4.8.2/ 该目录bin下包含相应版本的gcc4.8.2和gdb(GNU gdb (GDB) 7.6.1)
三、部署方式
把通过gcc4.8.2编译的bin程序运行在以上所列的运行环境中,这种情况下会有些问题需要注意。
(1) 通过nohup后台运行时,必须指定使用gcc4.8.2安装目录下的nohup运行,而不能使用默认版本的nohup,否则会导致bin程序异常退出。
(2)若bin程序因自身bug产生了core文件,则该core文件使用gcc4.8.2安装目录下的gdb方可调试,默认的gdb由于版本不匹配,不能进行调试。
(3)若程序正常运行,这时希望通过gcc4.8.2安装目录下的gdb进行attach来观察程序的执行情况,则会发现系统库均加载异常,地址显示一片 “ ??? () ”,
看不到任何有用的信息(见图一)。这时会发现gdb给出以下提示,提示设置两个变量,这时直接在gdb下执行 set solib-search-path gcc4.8.2/lib 会触发
该gdb重新加载系统库符号表,这时可以正常调试了(见图二)。感叹gdb的强大和了解gdb重要参数的必要性。
warning: Could not load shared library symbols for 20 libraries, e.g. linux-vdso.so.1.
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"?
(4)若程序正常执行,这时想产生core_dump保留现场,经过测试图三中所列的信号均不能产生正常的core文件,还会造成程序退出,对线上造成异常影响。
那么直接通过gcore执行产生core_dump时会产生异常提示(见图四)而实际生成的core文件也是不正常的无法用于调试。
(5)core_dump的正常生成过程:gcc4.8.2/bin/gdb attach $pid,接着在gdb执行gcore,接着在gdb执行detach,这时就产生了正常的core_dump也未造成线上
bin程序运行异常。这种方式生成的core_dump时特别需要注意$pid一定是希望观察的pid,可以是子进程的pid,那么core_dump记录的就是子进程的状态。调试
生成的core时需要使用以上(3)中提到的方法,否则会造成无法调试。
通过ps mp $pid可以观察所有进程的运行状态,pstree -p $pid可以指定待观察进程的所有子进程。
图一:gcc4.8.2版本对应的gdb无法加载任何正常的符号表,原因是加载的是默认的各种库,而不是gcc4.8.2对应的库。
图二:gcc4.8.2版本对应的gdb在 set solib-search-path执行后,可以正常加载符号表,这时加载了该版本安装目录下lib库。
图三:常见的可以触发bin程序产生core的信号。
图四:直接使用gcore会导致异常提示,生成的core_dump同样也是无法调试的。(原因是生成调试信息的gdb和调试core的gdb版本不一致。见解释http://ju.outofmemory.cn/entry/94917)