使用GDB 追踪依赖poco的so程序,core dump文件分析.

前言

在windows 下 系统核心态程序蓝屏,会产生dump文件. 用户级程序在设置后,程序崩溃也会产生dump文件.以方便开发者用windbg进行分析.

so,linux 系统也有一套这样的东东----->Linux Core Dump

Linux Core Dump

  引用 文章 <Linux Core Dump>  http://www.cnblogs.com/hazir/p/linxu_core_dump.html

  的话:

    

当程序运行的过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在一个文件中,这种行为就叫做Core Dump(中文有的翻译成“核心转储”)。我们可以认为 core dump 是“内存快照”,但实际上,除了内存信息之外,还有些关键的程序运行状态也会同时 dump 下来,例如寄存器信息(包括程序指针、栈指针等)、内存管理信息、其他处理器和操作系统状态和信息。core dump 对于编程人员诊断和调试程序是非常有帮助的,因为对于有些程序错误是很难重现的,例如指针异常,而 core dump 文件可以再现程序出错时的情景。

  其实 <Linux Core Dump>介绍core dump 很详细,唯一缺的就是设置 只能当前有效,重启后失效.

  重启后的设置有所残缺.

  这儿就重点说下重启生生效的设置 .

为什么在 /proc/sys/kernel/core_pattern,/proc/sys/kernel/core_uses_pid  以及 ulimit -c unlimited 中的设置会失败.

关于/proc目录

Linux 内核提供了一种通过 /proc 文件系统,在运行时访问内核内部数据结构、改变内核设置的机制。proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为访问系统内核数据的操作提供接口。
用户和应用程序可以通过proc得到系统的信息,并可以改变内核的某些参数。由于系统的信息,如进程,是动态改变的,所以用户或应用程序读取proc文件时,proc文件系统是动态从系统内核读出所需信息并提交的。下面列出的这些文件或子文件夹,并不是都是在你的系统中存在,这取决于你的内核配置和装载的模块。另外,在/proc下还有三个很重要的目录:net,scsi和sys。 Sys目录是可写的,可以通过它来访问或修改内核的参数,而net和scsi则依赖于内核配置。例如,如果系统不支持scsi,则scsi 目录不存在。
除了以上介绍的这些,还有的是一些以数字命名的目录,它们是进程目录。系统中当前运行的每一个进程都有对应的一个目录在/proc下,以进程的 PID号为目录名,它们是读取进程信息的接口。而self目录则是读取进程本身的信息接口,是一个link。 /proc --- 一个虚拟文件系统
 
/proc 文件系统是一种内核和内核模块用来向进程(process) 发送信息的机制(所以叫做/proc)。这个伪文件系统让你可以和内核内部数据结构进行交互,获取 有关进程的有用信息,在运行中(on the fly) 改变设置(通过改变内核参数)。 与其他文件系统不同,/proc 存在于内存之中而不是硬盘上。如果你察看文件/proc/mounts (和mount 命令一样列出所有已经加载的文件系统),你会看到其中 一行是这样的:
 
grep proc /proc/mounts
/proc /proc proc rw 0 0
 
/proc 由内核控制,没有承载/proc 的设备。因为/proc 主要存放由内核控制的状态信息,所以大部分这些信息的逻辑位置位于内核控制的内存。对/proc 进行一次'ls -l' 可以看到大部分文件都是0 字节大的;不过察看这些文件的时候,确实可以看到一些信息。这怎么可能?这是因为/proc 文件系统和其他常规的文件系统一样把自己注册到虚拟文件系统层(VFS) 了。然而,直到当VFS 调用它,请求文件、目录的i-node 的时候,/proc 文件系统才根据内核中的信息建立相应的文件和目录。 通过/proc 与内核交互
 
上面讨论的大部分/proc 的文件是只读的。而实际上/proc 文件系统通过/proc 中可读写的文件提供了对内核的交互机制。写这些文件可以改变内核的状态,因而要慎重改动这些文件。/proc/sys 目录存放所有可读写的文件的目录,可以被用于改变内核行为。
 
/proc/sys/kernel - 这个目录包含反通用内核行为的信息。/proc/sys/kernel/{domainname, hostname} 存放着机器/网络的域名和主机名。这些文件可以用于修改这些名字。

  注意上面标红的文字

永久修改

  ulimit -c filesize #这儿大小是以kb为单位的

  ulimit -c unlimited 

  --->改为

  永久设置, 修改/etc/security/limits.conf文件:

  

root@iZ233or8cn2Z:~# cat  /etc/security/limits.conf
# /etc/security/limits.conf
#
#Each line describes a limit for a user in the form:
#
#<domain> <type> <item> <value>
#
#Where:
#<domain> can be:
# - an user name
# - a group name, with @group syntax
# - the wildcard *, for default entry
# - the wildcard %, can be also used with %group syntax,
# for maxlogin limit
# - NOTE: group and wildcard limits are not applied to root.
# To apply a limit to the root user, <domain> must be
# the literal username root.
#
#<type> can have the two values:
# - "soft" for enforcing the soft limits
# - "hard" for enforcing hard limits
#
#<item> can be one of the following:
# - core - limits the core file size (KB)
# - data - max data size (KB)
# - fsize - maximum filesize (KB)
# - memlock - max locked-in-memory address space (KB)
# - nofile - max number of open files
# - rss - max resident set size (KB)
# - stack - max stack size (KB)
# - cpu - max CPU time (MIN)
# - nproc - max number of processes
# - as - address space limit (KB)
# - maxlogins - max number of logins for this user
# - maxsyslogins - max number of logins on the system
# - priority - the priority to run user process with
# - locks - max number of file locks the user can hold
# - sigpending - max number of pending signals
# - msgqueue - max memory used by POSIX message queues (bytes)
# - nice - max nice priority allowed to raise to values: [-, ]
# - rtprio - max realtime priority
# - chroot - change root to directory (Debian-specific)
#
#<domain> <type> <item> <value>
# #* soft core
#root hard core
#* hard rss
#@student hard nproc
#@faculty soft nproc
#@faculty hard nproc
#ftp hard nproc
#ftp - chroot /ftp
#@student - maxlogins # End of file root soft core unlimited
root@iZ233or8cn2Z:~#

  根据上面的意思当设置为

  "* soft core unlimited" 时是对所有用户 生效,然而在debian下没有生效.

  改成"root soft unlimited" 时 root 用户 能生效.这个问题一直没想明白.

在服务器上一直使用,如果有cored ump之后自动拉起的机制,比较容易发生core文件堆满磁盘的情况,需要注意。我采用的是一个进程名只会生效一个dump的办法.

core文件的格式和路径: 修改/proc/sys/kernel/core_pattern

echo '%e.core.%p' > /proc/sys/kernel/core_pattern

永久设置

/etc/sysctl.conf配置文件

最后添加一行:

kernel.core_pattern = /dump/core-%e

  这样一个进程名,只会有一个dump生产.

  
  core文件是否带pid: 修改/proc/sys/kernel/core_uses_pid

  这个就省掉了,否则后面 dump文件太多...

  

在poco项目中用gdb 测试 core dump

前面有篇文章<linux 下cmake 编译 ,调用,调试 poco 1.6.0 小记>

http://www.cnblogs.com/bleachli/p/4363485.html

中有提到过poco项目的编译.

当已经有了so后.

root@iZ233or8cn2Z:~# ls -l /disk1/d1/evn/poco-1.6.-all/lib/Linux/x86_64/
total
lrwxrwxrwx root root Aug : libCppUnitd.so -> libCppUnitd.so.
-rwxr-xr-x root root Aug : libCppUnitd.so.
lrwxrwxrwx root root Aug : libCppUnit.so -> libCppUnit.so.
-rwxr-xr-x root root Aug : libCppUnit.so.
lrwxrwxrwx root root Aug : libPocoDatad.so -> libPocoDatad.so.
-rwxr-xr-x root root Aug : libPocoDatad.so.
lrwxrwxrwx root root Aug : libPocoData.so -> libPocoData.so.
-rwxr-xr-x root root Aug : libPocoData.so.
lrwxrwxrwx root root Aug : libPocoDataSQLited.so -> libPocoDataSQLited.so.
-rwxr-xr-x root root Aug : libPocoDataSQLited.so.
lrwxrwxrwx root root Aug : libPocoDataSQLite.so -> libPocoDataSQLite.so.
-rwxr-xr-x root root Aug : libPocoDataSQLite.so.
lrwxrwxrwx root root Aug : libPocoFoundationd.so -> libPocoFoundationd.so.
-rwxr-xr-x root root Aug : libPocoFoundationd.so.
lrwxrwxrwx root root Aug : libPocoFoundation.so -> libPocoFoundation.so.
-rwxr-xr-x root root Aug : libPocoFoundation.so.
lrwxrwxrwx root root Aug : libPocoJSONd.so -> libPocoJSONd.so.
-rwxr-xr-x root root Aug : libPocoJSONd.so.
lrwxrwxrwx root root Aug : libPocoJSON.so -> libPocoJSON.so.
-rwxr-xr-x root root Aug : libPocoJSON.so.
lrwxrwxrwx root root Aug : libPocoMongoDBd.so -> libPocoMongoDBd.so.
-rwxr-xr-x root root Aug : libPocoMongoDBd.so.
lrwxrwxrwx root root Aug : libPocoMongoDB.so -> libPocoMongoDB.so.
-rwxr-xr-x root root Aug : libPocoMongoDB.so.
lrwxrwxrwx root root Aug : libPocoNetd.so -> libPocoNetd.so.
-rwxr-xr-x root root Aug : libPocoNetd.so.
lrwxrwxrwx root root Aug : libPocoNet.so -> libPocoNet.so.
-rwxr-xr-x root root Aug : libPocoNet.so.
lrwxrwxrwx root root Aug : libPocoUtild.so -> libPocoUtild.so.
-rwxr-xr-x root root Aug : libPocoUtild.so.
lrwxrwxrwx root root Aug : libPocoUtil.so -> libPocoUtil.so.
-rwxr-xr-x root root Aug : libPocoUtil.so.
lrwxrwxrwx root root Aug : libPocoXMLd.so -> libPocoXMLd.so.
-rwxr-xr-x root root Aug : libPocoXMLd.so.
lrwxrwxrwx root root Aug : libPocoXML.so -> libPocoXML.so.
-rwxr-xr-x root root Aug : libPocoXML.so.
lrwxrwxrwx root root Aug : libPocoZipd.so -> libPocoZipd.so.
-rwxr-xr-x root root Aug : libPocoZipd.so.
lrwxrwxrwx root root Aug : libPocoZip.so -> libPocoZip.so.
-rwxr-xr-x root root Aug : libPocoZip.so.

  

测试项目结构如下:

使用GDB 追踪依赖poco的so程序,core dump文件分析.  

src中是TestTimeServer.cpp

//
// TimeServer.cpp
//
// $Id: //poco/1.4/Net/samples/TimeServer/src/TimeServer.cpp#1 $
//
// This sample demonstrates the TCPServer and ServerSocket classes.
//
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
// #include "Poco/Net/TCPServer.h"
#include "Poco/Net/TCPServerConnection.h"
#include "Poco/Net/TCPServerConnectionFactory.h"
#include "Poco/Net/TCPServerParams.h"
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/ServerSocket.h"
#include "Poco/Timestamp.h"
#include "Poco/DateTimeFormatter.h"
#include "Poco/DateTimeFormat.h"
#include "Poco/Exception.h"
#include "Poco/Util/ServerApplication.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionSet.h"
#include "Poco/Util/HelpFormatter.h"
#include <iostream> using Poco::Net::ServerSocket;
using Poco::Net::StreamSocket;
using Poco::Net::TCPServerConnection;
using Poco::Net::TCPServerConnectionFactory;
using Poco::Net::TCPServer;
using Poco::Timestamp;
using Poco::DateTimeFormatter;
using Poco::DateTimeFormat;
using Poco::Util::ServerApplication;
using Poco::Util::Application;
using Poco::Util::Option;
using Poco::Util::OptionSet;
using Poco::Util::HelpFormatter; class TimeServerConnection: public TCPServerConnection
/// This class handles all client connections.
///
/// A string with the current date and time is sent back to the client.
{
public:
TimeServerConnection(const StreamSocket& s, const std::string& format):
TCPServerConnection(s),
_format(format)
{
} void run()
{
Application& app = Application::instance();
app.logger().information("Request from " + this->socket().peerAddress().toString());
try
{
Timestamp now;
std::string dt(DateTimeFormatter::format(now, _format));
dt.append("\r\n");
socket().sendBytes(dt.data(), (int) dt.length());
}
catch (Poco::Exception& exc)
{
app.logger().log(exc);
}
} private:
std::string _format;
}; class TimeServerConnectionFactory: public TCPServerConnectionFactory
/// A factory for TimeServerConnection.
{
public:
TimeServerConnectionFactory(const std::string& format):
_format(format)
{
} TCPServerConnection* createConnection(const StreamSocket& socket)
{
return new TimeServerConnection(socket, _format);
} private:
std::string _format;
}; class TimeServer: public Poco::Util::ServerApplication
/// The main application class.
///
/// This class handles command-line arguments and
/// configuration files.
/// Start the TimeServer executable with the help
/// option (/help on Windows, --help on Unix) for
/// the available command line options.
///
/// To use the sample configuration file (TimeServer.properties),
/// copy the file to the directory where the TimeServer executable
/// resides. If you start the debug version of the TimeServer
/// (TimeServerd[.exe]), you must also create a copy of the configuration
/// file named TimeServerd.properties. In the configuration file, you
/// can specify the port on which the server is listening (default
/// 9911) and the format of the date/time string sent back to the client.
///
/// To test the TimeServer you can use any telnet client (telnet localhost 9911).
{
public:
TimeServer(): _helpRequested(false)
{
} ~TimeServer()
{
} protected:
void initialize(Application& self)
{
loadConfiguration(); // load default configuration files, if present
ServerApplication::initialize(self);
} void uninitialize()
{
ServerApplication::uninitialize();
} void defineOptions(OptionSet& options)
{
ServerApplication::defineOptions(options); options.addOption(
Option("help", "h", "display help information on command line arguments")
.required(false)
.repeatable(false));
} void handleOption(const std::string& name, const std::string& value)
{
ServerApplication::handleOption(name, value); if (name == "help")
_helpRequested = true;
} void displayHelp()
{
HelpFormatter helpFormatter(options());
helpFormatter.setCommand(commandName());
helpFormatter.setUsage("OPTIONS");
helpFormatter.setHeader("A server application that serves the current date and time.");
helpFormatter.format(std::cout);
} int main(const std::vector<std::string>& args)
{
if (_helpRequested)
{
displayHelp();
}
else
{
//带参数就在 TimeServer::main 中崩溃... int * pTest=NULL;
*pTest=0x1234;
// get parameters from configuration file
unsigned short port = (unsigned short) config().getInt("TimeServer.port", );
std::string format(config().getString("TimeServer.format", DateTimeFormat::ISO8601_FORMAT)); // set-up a server socket
ServerSocket svs(port);
// set-up a TCPServer instance
TCPServer srv(new TimeServerConnectionFactory(format), svs);
// start the TCPServer
srv.start();
// wait for CTRL-C or kill
waitForTerminationRequest();
// Stop the TCPServer
srv.stop();
}
return Application::EXIT_OK;
} private:
bool _helpRequested;
}; int main(int argc, char** argv)
{
if(argc==1)//不带参数就在 main 中崩溃
{
int * pTest=NULL;
*pTest=0x1233;
} TimeServer app;
return app.run(argc, argv);
}

  注意上面已经说了:

  

if(argc==1)//不带参数就在 main 中崩溃
{
int * pTest=NULL;
*pTest=0x1233;
}

  

//带参数就在 TimeServer::main 中崩溃...

int * pTest=NULL;
*pTest=0x1234;

  CMakeList.txt:

  

#定义最低版本.
#cmake_minimum_required(VERSION 3.0.0) #
set(SAMPLE_NAME "TimeServer") #SET(CMAKE_BUILE_TYPE Debug) #指定编译类型 设置编译类型debug 或者release。 debug 版会生成相关调试信息,可以使用GDB 进行 set(myExeSuffix "") if (CMAKE_BUILE_TYPE STREQUAL Debug) add_definitions( -D_DEBUG ) add_definitions(-DDEBUG) add_definitions("$ENV{CXXFLAGS} -O0 -Wall -g -ggdb") set(myExeSuffix "d")
set(SAMPLE_NAME "TimeServer${myExeSuffix}")
#SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb") MESSAGE(STATUS "my build is debug...") else()
add_definitions("$ENV{CXXFLAGS} -O3 -Wall")
#SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall") MESSAGE(STATUS "my build is release...")
endif () PROJECT(${SAMPLE_NAME}) #定义工程名称 #ADD_SUBDIRECTORY(utility) #添加要编译的子目录 为工程主目录下的存放源代码的子目录使用该命令,各子目录出现的顺序随意。
# set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${path_root_dir}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${path_root_dir}/lib)
# Windows DLLs are "runtime" for CMake. Output them to "bin" like the Visual Studio projects do.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "")
#设置程序exe输出位置
SET(EXECUTABLE_OUTPUT_PATH "") #
set(LOCAL_SRCS "") # aux_source_directory 作用是发现一个目录下所有的源代码文件并将列表存储在一个变量中,这个指令临时被用来
# 自动构建源文件列表。因为目前cmake还不能自动发现新添加的源文件。
aux_source_directory(src LOCAL_SRCS) # 生成exe 名字为 ${SAMPLE_NAME} 的值
add_executable(${SAMPLE_NAME} ${LOCAL_SRCS} )
# 这个指令可以用来为target添加需要链接的共享库
target_link_libraries( ${SAMPLE_NAME} PocoNet${myExeSuffix} PocoUtil${myExeSuffix} PocoJSON${myExeSuffix} PocoXML${myExeSuffix} PocoFoundation${myExeSuffix} libmyodbc5a.so)

  

在linux 中执行 以release版本生成

 

root@iZ233or8cn2Z:/disk1/d1/evn/mytest# cmake .
-- my build is release...
-- The C compiler identification is GNU 4.7.
-- The CXX compiler identification is GNU 4.7.
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Warning (dev) in CMakeLists.txt:
No cmake_minimum_required command is present. A line of code such as cmake_minimum_required(VERSION 3.3) should be added at the top of the file. The version specified may be lower
if you wish to support older CMake versions for this project. For more
information run "cmake --help-policy CMP0000".
This warning is for project developers. Use -Wno-dev to suppress it. -- Configuring done
-- Generating done
-- Build files have been written to: /disk1/d1/evn/mytest
root@iZ233or8cn2Z:/disk1/d1/evn/mytest# make
Scanning dependencies of target TimeServer
[ %] Building CXX object CMakeFiles/TimeServer.dir/src/TestTimeServer.o
[%] Linking CXX executable TimeServer
[%] Built target TimeServer
root@iZ233or8cn2Z:/disk1/d1/evn/mytest# ./TimeServer
Segmentation fault (core dumped)

  上面(core dumped) 代表已经生成了dump文件.

  

root@iZ233or8cn2Z:/disk1/d1/evn/mytest# ls -lh /dump 

-rw-------  root root 1.7M Aug   : core-TimeServer

  

  使用gdb 进行调试.

  

  

root@iZ233or8cn2Z:/disk1/d1/evn/mytest# gdb ./TimeServer  /mydump/core-TimeServer
GNU gdb (GDB) 7.4.-debian
Copyright (C) Free Software Foundation, Inc.
License GPLv3+: GNU GPL version or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /disk1/d1/evn/mytest/TimeServer...(no debugging symbols found)...done.
[New LWP ] warning: Can't read pathname for load map: Input/output error.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./TimeServer'.
Program terminated with signal , Segmentation fault.
# 0x0000000000403dd9 in main ()
(gdb) where
# 0x0000000000403dd9 in main ()
(gdb) info share
From To Syms Read Shared Object Library
0x00007f184ce19cb0 0x00007f184ce8e83c Yes (*) /usr/local/lib/libPocoNet.so.
0x00007f184cb5c9d0 0x00007f184cb8a838 Yes (*) /usr/local/lib/libPocoUtil.so.
0x00007f184c8f88f0 0x00007f184c91b9ec Yes (*) /usr/local/lib/libPocoJSON.so.
0x00007f184c67fb50 0x00007f184c6bc0bc Yes (*) /usr/local/lib/libPocoXML.so.
0x00007f184c2fbcd0 0x00007f184c3dcc74 Yes (*) /usr/local/lib/libPocoFoundation.so.
0x00007f184bc8b230 0x00007f184bd45c98 Yes /usr/local/lib/libmyodbc5a.so
0x00007f184b99c640 0x00007f184ba0071b Yes (*) /usr/lib/x86_64-linux-gnu/libstdc++.so.
0x00007f184b6bdef0 0x00007f184b6fd6f8 Yes (*) /lib/x86_64-linux-gnu/libm.so.
0x00007f184b4a6e70 0x00007f184b4b65d8 Yes (*) /lib/x86_64-linux-gnu/libgcc_s.so.
0x00007f184b137b80 0x00007f184b24fc2c Yes (*) /lib/x86_64-linux-gnu/libc.so.
0x00007f184af02690 0x00007f184af0dce8 Yes (*) /lib/x86_64-linux-gnu/libpthread.so.
0x00007f184acf9de0 0x00007f184acfa8f8 Yes (*) /lib/x86_64-linux-gnu/libdl.so.
0x00007f184aaf3190 0x00007f184aaf64f8 Yes (*) /lib/x86_64-linux-gnu/librt.so.
0x00007f184a8dcdf0 0x00007f184a8eb1f4 Yes /usr/local/lib/libodbcinst.so.
0x00007f184d0c7af0 0x00007f184d0dfc83 Yes (*) /lib64/ld-linux-x86-.so.
(*): Shared library is missing debugging information.
(gdb)

  

  注意上面标红的 "(no debugging symbols found)"  "(*): Shared library is missing debugging information."

  程序没有调试信息..加载的so 也没有调试信息.

  所以我们只能见

  "

(gdb) where
#0 0x0000000000403dd9 in main ()

"

在这儿出错,但具体原因不知.

我们再看看进入so 文件内容崩溃的结果呢!

root@iZ233or8cn2Z:/disk1/d1/evn/mytest# ./TimeServer
Aborted (core dumped)
root@iZ233or8cn2Z:/disk1/d1/evn/mytest# gdb ./TimeServer /mydump/core-TimeServer
GNU gdb (GDB) 7.4.-debian
Copyright (C) Free Software Foundation, Inc.
License GPLv3+: GNU GPL version or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /disk1/d1/evn/mytest/TimeServer...(no debugging symbols found)...done.
[New LWP ] warning: Can't read pathname for load map: Input/output error.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./TimeServer '.
Program terminated with signal 6, Aborted.
#0 0x00007f0c4e389165 in raise () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) where
# 0x00007f0c4e389165 in raise () from /lib/x86_64-linux-gnu/libc.so.
# 0x00007f0c4e38c3e0 in abort () from /lib/x86_64-linux-gnu/libc.so.
# 0x00007f0c4f5a8da5 in Poco::SignalHandler::handleSignal(int) () from /usr/local/lib/libPocoFoundation.so.
# <signal handler called>
# 0x0000000000403e58 in TimeServer::main(std::vector<std::string, std::allocator<std::string> > const&) ()
# 0x00007f0c4fda6407 in Poco::Util::Application::run() () from /usr/local/lib/libPocoUtil.so.
# 0x0000000000403dbd in main ()
(gdb)

  还是没有找到具体原因.

在linux 中以debug版本生成

root@iZ233or8cn2Z:/disk1/d1/evn/mytest# cmake -DCMAKE_BUILE_TYPE=Debug  .
-- my build is debug...
-- The C compiler identification is GNU 4.7.
-- The CXX compiler identification is GNU 4.7.
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Warning (dev) in CMakeLists.txt:
No cmake_minimum_required command is present. A line of code such as cmake_minimum_required(VERSION 3.3) should be added at the top of the file. The version specified may be lower
if you wish to support older CMake versions for this project. For more
information run "cmake --help-policy CMP0000".
This warning is for project developers. Use -Wno-dev to suppress it. -- Configuring done
-- Generating done
-- Build files have been written to: /disk1/d1/evn/mytest
root@iZ233or8cn2Z:/disk1/d1/evn/mytest# make
Scanning dependencies of target TimeServerd
[ %] Building CXX object CMakeFiles/TimeServerd.dir/src/TestTimeServer.o
[%] Linking CXX executable TimeServerd
[%] Built target TimeServerd
root@iZ233or8cn2Z:/disk1/d1/evn/mytest# ls
CMakeCache.txt CMakeFiles cmake_install.cmake CMakeLists.txt Makefile src TimeServerd TimeServer.progen TimeServer.properties
root@iZ233or8cn2Z:/disk1/d1/evn/mytest# ./TimeServerd
Segmentation fault (core dumped)

  使用gdb查看

root@iZ233or8cn2Z:/disk1/d1/evn/mytest# gdb ./TimeServerd  /mydump/core-TimeServerd
GNU gdb (GDB) 7.4.-debian
Copyright (C) Free Software Foundation, Inc.
License GPLv3+: GNU GPL version or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /disk1/d1/evn/mytest/TimeServerd...done.
[New LWP ] warning: Can't read pathname for load map: Input/output error.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./TimeServerd'.
Program terminated with signal , Segmentation fault.
# 0x0000000000404aca in main (argc=, argv=0x7fff018b4c98) at /disk1/d1/evn/mytest/src/TestTimeServer.cpp:
*pTest=0x1233;
(gdb) info share
From To Syms Read Shared Object Library
0x00007fa8ef6c5000 0x00007fa8ef75213c Yes /usr/local/lib/libPocoNetd.so.30
0x00007fa8ef381680 0x00007fa8ef3bc2d4 Yes /usr/local/lib/libPocoUtild.so.30
0x00007fa8ef0bf260 0x00007fa8ef0ee748 Yes /usr/local/lib/libPocoJSONd.so.30
0x00007fa8eedec140 0x00007fa8eee43ff8 Yes /usr/local/lib/libPocoXMLd.so.30
0x00007fa8ee9c5750 0x00007fa8eeaed290 Yes /usr/local/lib/libPocoFoundationd.so.30
0x00007fa8ee297230 0x00007fa8ee351c98 Yes /usr/local/lib/libmyodbc5a.so
0x00007fa8edfa8640 0x00007fa8ee00c71b Yes (*) /usr/lib/x86_64-linux-gnu/libstdc++.so.
0x00007fa8edcc9ef0 0x00007fa8edd096f8 Yes (*) /lib/x86_64-linux-gnu/libm.so.
0x00007fa8edab2e70 0x00007fa8edac25d8 Yes (*) /lib/x86_64-linux-gnu/libgcc_s.so.
0x00007fa8ed743b80 0x00007fa8ed85bc2c Yes (*) /lib/x86_64-linux-gnu/libc.so.
0x00007fa8ed50e690 0x00007fa8ed519ce8 Yes (*) /lib/x86_64-linux-gnu/libpthread.so.
0x00007fa8ed305de0 0x00007fa8ed3068f8 Yes (*) /lib/x86_64-linux-gnu/libdl.so.
0x00007fa8ed0ff190 0x00007fa8ed1024f8 Yes (*) /lib/x86_64-linux-gnu/librt.so.
0x00007fa8ecee8df0 0x00007fa8ecef71f4 Yes /usr/local/lib/libodbcinst.so.
0x00007fa8ef9a9af0 0x00007fa8ef9c1c83 Yes (*) /lib64/ld-linux-x86-.so.
(*): Shared library is missing debugging information.
(gdb) where
# 0x0000000000404aca in main (argc=, argv=0x7fff018b4c98) at /disk1/d1/evn/mytest/src/TestTimeServer.cpp:
(gdb)

  看上面  poco 的so文件也参加载调试信息了.

  "(no debugging symbols found)"  "(*): Shared library is missing debugging information."

  这两个错误已经不见了.

使用GDB 追踪依赖poco的so程序,core dump文件分析.

  这个错误定位已直观了.

  再看看so中的错误呢

root@iZ233or8cn2Z:/disk1/d1/evn/mytest# ./TimeServerd 22 2
Segmentation fault (core dumped)
root@iZ233or8cn2Z:/disk1/d1/evn/mytest# gdb ./TimeServerd /mydump/core-TimeServerd
GNU gdb (GDB) 7.4.-debian
Copyright (C) Free Software Foundation, Inc.
License GPLv3+: GNU GPL version or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /disk1/d1/evn/mytest/TimeServerd...done.
[New LWP ] warning: Can't read pathname for load map: Input/output error.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./TimeServerd '.
Program terminated with signal , Segmentation fault.
#0 0x000000000040588e in TimeServer::main (this=0x7ffed2e55cb0, args=...) at /disk1/d1/evn/mytest/src/TestTimeServer.cpp:178
178 *pTest=0x1234;
(gdb) where
#0 0x000000000040588e in TimeServer::main (this=0x7ffed2e55cb0, args=...) at /disk1/d1/evn/mytest/src/TestTimeServer.cpp:178
#1 0x00007f0212ccf02d in Poco::Util::Application::run (this=0x7ffed2e55cb0) at src/Application.cpp:329
#2 0x00007f0212ceb49c in Poco::Util::ServerApplication::run (this=0x7ffed2e55cb0) at src/ServerApplication.cpp:97
#3 0x00007f0212ceb5ea in Poco::Util::ServerApplication::run (this=0x7ffed2e55cb0, argc=3, argv=0x7ffed2e55e68) at src/ServerApplication.cpp:612
#4 0x0000000000404afd in main (argc=3, argv=0x7ffed2e55e68) at /disk1/d1/evn/mytest/src/TestTimeServer.cpp:211
(gdb)

  使用GDB 追踪依赖poco的so程序,core dump文件分析.

  已经能直观的找到我们的错误了.

  在linux 这种服务程序的开发中,有了日志输出+core dump 对于一般的程序员来方可以节省很多查找错误的时间.

关于cmake

  cmake 虽然简单.但命令也是比较多的.

  以下两个文章供参考:

  http://blog.csdn.net/dbzhang800/article/details/6314073

  http://www.cnblogs.com/lidabo/p/3974305.html

  http://www.hahack.com/codes/cmake/

gdb) file <你的exe>
(gdb) load <你的so>                #这条应该是可选的

(gdb) dir <so'dir>
(gdb) sharedlibrary <你的so>
(gdb) breakpoint <你的so中somewhere>
(gdb) run

(gdb) info share               //查看动态库是否被引用。
load 是将动态库加载入内存。
sharedlibrary是将动态库的符号读入gdb,为了你能找到变量和函数名。
它们本身是没有明显的动作,但后面当你直接设置断点到动态库的函数(或行号)时,你就可以成功了。在此之前要记得用dir将动态库的源码也加入搜索路径。

上一篇:手把手教你玩转nginx负载均衡(四)--源码安装nginx


下一篇:Core Bluetooth下实现两个设备进行互联