2011-04-18 22 views
0

我将静态库链接到可执行文件。可执行文件本身不使用库符号。但是这个可执行文件在运行时加载了一些共享库,其中一个使用库中的符号。以下是库源文件的非常简化版本。在运行时加载的共享库中使用动态分配的对象时出现分段错误

ParentClass.h

#include <iostream> 

using namespace std; 

class ParentClass { 
    ParentClass() {} 

// some functionality 
}; 

ChildClass.h

#include <ParentClass.h> 

struct StaticData { 
    static const char *staticString; 
}; 

class ChildClass : public ParentClass, public StaticData { 
    ChildClass() {} 
    // some extended functionality here 
}; 

ChildClass.cpp

#include "ChildClass.h" 

const char * StaticData::staticString = "string"; 

// functionality implementation 

下面是几个事实:

1.code这样的:

ChildClass test; 

//extended use of test functionality 

工作得很好。

2.code这样的:

ChieldClass *test = new ChieldClass(); 
    test->some_func(); // some func don't use dynamic memory 
    test->some_other_func(); // dynamic memory used (in my case malloc in gethostbyname system function) 

工作得很好二进制与库直接连接使用时,但在运行时加载共享库时失败,段错误"path_to_exec malloc(): memory corruption: some_address"(见开头描述)。

3.code这样的:

ParentClass *test = new ParentClass(); 
test->some_func(); 
test->some_other_func(); 

工作以及无处不在。

我无法理解为什么第2项中的代码会导致分段错误,但我怀疑这是使用ChildClass中的静态数据的问题(除此之外,ChildClass仅使用扩展功能定义了一些使用ParenClass的新函数即使我使用的不是重载的ParentClass函数,也会发生分割错误)。但是我无法将这种差异与segnemtation故障发生的事实联系起来,只有在共享库中使用ChildClass动态加载到与我的库链接的可执行文件时才会发生这种情况。

我很高兴听到任何想法摆脱这个seg故障。

更新:bt当使用记录器功能与std :: cout(有些名称被省略)。呼叫顺序:

ChildClass *test = new ChildClass(); 
test->printInfo(); 
test->connect(); 

connectFnction未在ChildClass中重新定义。

(gdb) bt 
#0 0x00007f756f67e165 in raise() from /lib/libc.so.6 
#1 0x00007f756f680f70 in abort() from /lib/libc.so.6 
#2 0x00007f756f6b427b in ??() from /lib/libc.so.6 
#3 0x00007f756f6bdad6 in ??() from /lib/libc.so.6 
#4 0x00007f756f6c0b6d in ??() from /lib/libc.so.6 
#5 0x00007f756f6c2930 in malloc() from /lib/libc.so.6 
#6 0x00007f756f6af35b in ??() from /lib/libc.so.6 
#7 0x00007f756f7291de in ??() from /lib/libc.so.6 
#8 0x00007f756f72aa65 in __res_maybe_init() from /lib/libc.so.6 
#9 0x00007f756f72ca70 in __nss_hostname_digits_dots() from /lib/libc.so.6 
#10 0x00007f756f731fe4 in gethostbyname_r() from /lib/libc.so.6 
#11 0x0000000000507929 in underlaying_c_code_connect (client=0x7f7564017348) at /home/beduin/???/lib/???/UnderlayingCCode.cpp:1477 
#12 0x0000000000504a24 in ParentClass::connect (this=0x7f7564017340) at /home/beduin/???/lib/???/ParentClass.cpp:216 
#13 0x00007f7569342f68 in Plugin::Start (this=0x7f75640208c0) at /home/beduin/???/plugins/???/Plugin.cpp:84 
#14 0x00000000004c7d45 in ???::PluginHolder::StartPlugin (this=0x7fffed7dc5e0, [email protected]) at /home/beduin/???/plugins.cpp:317 
#15 0x00000000004c8656 in ???::PluginHolder::Start (this=0x7fffed7dc5e0) at /home/beduin/mrvs/framework/base/plugins.cpp:401 
#16 0x00000000004c7935 in ???::PluginHolder::LockNLoad (this=0x7fffed7dc5e0) at /home/beduin/???/plugins.cpp:284 
#17 0x00000000004afe6f in main (argc=3, argv=0x7fffed7dd978) at /home/beduin/???/main.cpp:148 

使用自定义记录器:

#0 0x00007f824aa12165 in raise() from /lib/libc.so.6 
#1 0x00007f824aa14f70 in abort() from /lib/libc.so.6 
#2 0x00007f824aa4827b in ??() from /lib/libc.so.6 
#3 0x00007f824aa51ad6 in ??() from /lib/libc.so.6 
#4 0x00007f824aa54b6d in ??() from /lib/libc.so.6 
#5 0x00007f824aa56930 in malloc() from /lib/libc.so.6 
#6 0x00007f824b2a46bd in operator new() from /usr/lib/libstdc++.so.6 
#7 0x00007f824b280b29 in std::string::_Rep::_S_create() from /usr/lib/libstdc++.so.6 
#8 0x00007f824b281aeb in std::string::_Rep::_M_clone() from /usr/lib/libstdc++.so.6 
#9 0x00007f824b28205c in std::string::reserve() from /usr/lib/libstdc++.so.6 
#10 0x00007f824b27c021 in std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::overflow() from /usr/lib/libstdc++.so.6 
#11 0x00007f824b280215 in std::basic_streambuf<char, std::char_traits<char> >::xsputn() from /usr/lib/libstdc++.so.6 
#12 0x00007f824b2763b5 in std::__ostream_insert<char, std::char_traits<char> >() from /usr/lib/libstdc++.so.6 
#13 0x00007f824b27662f in std::operator<< <std::char_traits<char> >() from /usr/lib/libstdc++.so.6 
#14 0x00000000004f4fb0 in ???::Logger::LogWriter::operator<< <char [25]> (this=0x7fff8e241fc0, [email protected]) 
    at /home/beduin/???/log:184 
#15 0x0000000000500388 in ChildClass::printInfo (this=0x7f8240017470) at /home/beduin/???/ChildClass.cpp:480 
#16 0x00007f82446d6f5c in Plugin::Start (this=0x7f82400208a0) at /home/beduin/???/plugins/???/Plugin.cpp:83 
#17 0x00000000004c7d35 in ???::PluginHolder::StartPlugin (this=0x7fff8e243b30, [email protected]) at /home/beduin/???/plugins.cpp:317 
#18 0x00000000004c8646 in ???::PluginHolder::Start (this=0x7fff8e243b30) at /home/beduin/???/plugins.cpp:401 
#19 0x00000000004c7925 in ???::PluginHolder::LockNLoad (this=0x7fff8e243b30) at /home/beduin/???/plugins.cpp:284 
#20 0x00000000004afe5f in main (argc=3, argv=0x7fff8e244ec8) at /home/beduin/???/main.cpp:148 
+1

使用一个调试器准确指出是什么导致了错误,并发布代码 - 我们不知道你在哪里或如何(或为什么)调用malloc。 – Mat 2011-04-18 12:54:22

+0

第一个调用的malloc发生了段错误。例如,我编写了一个小的func来打印出内部数据成员的值。如果我使用std :: cout,则此函数执行成功(所有maemeber值都正确),并在下一个调用gethostbyname(使用malloc的函数内)的函数中发生seg fault。但是如果我使用我们的项目自定义Logger类,在其中使用malloc,我会在调用记录器时收到seg错误。我会在几分钟内用gdb更新帖子。 – beduin 2011-04-18 13:01:32

+0

malloc上的Segfault使我认为堆已损坏,通常是由数组边界外的代码写入引起的。 – 2011-04-18 13:07:19

回答

2

下的valgrind运行程序(而不是GDB)。它会告诉你第一个出现无效内存访问的地方,这可能与最终发生崩溃的地方不同。

关于作为共享库链接时发生故障的事实,您是否使用-fPIC?如果没有,尝试一下。

+1

奇怪的事实。在valgrind分段下运行时,故障消失。反而有很多错误。它看起来像在加载库期间某处发生内存损坏,然后影响所有后续操作。我会深入他们的,谢谢。 – beduin 2011-04-18 13:30:01

+0

是的,使用了-fPIC。 – beduin 2011-04-18 13:51:59

相关问题