Statically linking libprotobuf

2,596 views
Skip to first unread message

Matt

unread,
Jul 12, 2008, 7:25:37 PM7/12/08
to Protocol Buffers
Hi,

When I compile against libprotobuf and dynamically link against it,
everything works fine. However, when I statically link against
libprotobuf.a, I get a segfault immediately when I run the code. This
is on Mac OS X 10.5.3. Here is some info from gdb:

(gdb) run
Starting program: /Users/mtolton/Documents/code/yame/build/test
Reading symbols for shared libraries +++. done

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0xfffffffc
0x964d22e5 in std::string::_Rep::_M_grab ()
(gdb) bt
#0 0x964d22e5 in std::string::_Rep::_M_grab ()
#1 0x964d340e in std::basic_string<char, std::char_traits<char>,
std::allocator<char> >::basic_string ()
#2 0x00015c85 in
google::protobuf::DescriptorPool::Tables::AllocateString
(this=0x200150, value=@0xfffffff4) at google/protobuf/descriptor.cc:
553
#3 0x00025e04 in google::protobuf::DescriptorBuilder::BuildFile
(this=0xbfffd9a0, proto=@0xbfffda2c) at google/protobuf/descriptor.cc:
2063
#4 0x00028b6a in google::protobuf::DescriptorPool::BuildFile
(this=0x96ac8, proto=@0xfffffff4) at google/protobuf/descriptor.cc:
1686
#5 0x00028c70 in
google::protobuf::DescriptorPool::InternalBuildGeneratedFile
(this=0xfffffff4, data=0xfffffff4, size=-12) at google/protobuf/
descriptor.cc:1751
#6 0x00011410 in proto_BuildDescriptors_mudnode_2eproto () at build/
mudnode.pb.cc:26
#7 0x00011953 in
StaticDescriptorInitializer_mudnode_2eproto::StaticDescriptorInitializer_mudnode_2eproto
(this=0x96bd0) at build/mudnode.pb.cc:35
#8 0x00011967 in
StaticDescriptorInitializer_mudnode_2eproto::StaticDescriptorInitializer_mudnode_2eproto
(this=0x96bd0) at build/mudnode.pb.cc:36
#9 0x00073798 in __static_initialization_and_destruction_0 () at
repeated_field.h:467
#10 0x00073831 in global constructors keyed to
_ZN48_GLOBAL__N_build_mudnode.pb.cc_00000000_055C2A1A23TestMessage_descriptor_E
() at repeated_field.h:467
#11 0x8fe12e76 in
__dyld__ZN16ImageLoaderMachO18doModInitFunctionsERKN11ImageLoader11LinkContextE
()
#12 0x8fe0e723 in
__dyld__ZN11ImageLoader23recursiveInitializationERKNS_11LinkContextEj
()
#13 0x8fe0e809 in
__dyld__ZN11ImageLoader15runInitializersERKNS_11LinkContextE ()
#14 0x8fe04102 in __dyld__ZN4dyld24initializeMainExecutableEv ()
#15 0x8fe07b5f in __dyld__ZN4dyld5_mainEPK11mach_headermiPPKcS5_S5_ ()
#16 0x8fe01872 in
__dyld__ZN13dyldbootstrap5startEPK11mach_headeriPPKcl ()
#17 0x8fe01037 in __dyld__dyld_start ()
(gdb)

Anyone have any ideas?

Thanks,
Matt

Blair Zajac

unread,
Jul 12, 2008, 8:09:11 PM7/12/08
to Protocol Buffers
Matt wrote:
> Hi,
>
> When I compile against libprotobuf and dynamically link against it,
> everything works fine. However, when I statically link against
> libprotobuf.a, I get a segfault immediately when I run the code. This
> is on Mac OS X 10.5.3. Here is some info from gdb:

I don't have any additional information, but I can reproduce the
problem. This is with no use of the protocol buffers besides
GOOGLE_PROTOBUF_VERIFY_VERSION.

(gdb) start
Breakpoint 1 at 0x52d5a: file main.cpp, line 574.
Starting program: /Users/blair/a.out
Reading symbols for shared libraries .++...++.+++++++....+.............
+ done

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0xfffffffc
0x90b2ef65 in std::string::_Rep::_M_grab ()

I tried recompiling protobuf and my package with g++ 4.3 and it made
no difference.

Regards,
Blair

Matt

unread,
Jul 12, 2008, 11:47:19 PM7/12/08
to Protocol Buffers
> I don't have any additional information, but I can reproduce the
> problem.  This is with no use of the protocol buffers besides
> GOOGLE_PROTOBUF_VERIFY_VERSION.

What OS? Mac OS X?

Blair Zajac

unread,
Jul 12, 2008, 11:49:22 PM7/12/08
to Matt, Protocol Buffers

Yes. Mac OS X 10.4.11 with gcc version 4.0.1 (Apple Computer, Inc. build 5370).
Trying g++ 4.3.1 made no difference.

Blair

--
Blair Zajac, Ph.D.
CTO, OrcaWare Technologies
<bl...@orcaware.com>
Subversion training, consulting and support
http://www.orcaware.com/svn/

Kenton Varda

unread,
Jul 15, 2008, 1:18:59 AM7/15/08
to Matt, Protocol Buffers
I think I see the bug here.  It's a complicated static initialization ordering problem.  It looks like one way to work around the problem would be to declare a package name in your .proto file.  I'll put it on my TODO list to fix this bug, hopefully sometime this week.  Feel free to file an issue in the issue tracker.

Matt

unread,
Jul 24, 2008, 8:29:14 PM7/24/08
to Protocol Buffers
Hi Kenton,

Any ETA on this fix?

Thanks,
Matt

On Jul 14, 10:18 pm, "Kenton Varda" <ken...@google.com> wrote:
> I think I see the bug here.  It's a complicated static initialization
> ordering problem.  It looks like one way to work around the problem would be
> to declare a package name in your .proto file.  I'll put it on my TODO list
> to fix this bug, hopefully sometime this week.  Feel free to file an issue
> in the issue tracker.
>

Kenton Varda

unread,
Jul 24, 2008, 8:47:41 PM7/24/08
to Matt, Protocol Buffers
Sorry, had a lot of stuff to do.

I can't reproduce this on Linux.  I tried once on my mac at home and wasn't able to reproduce it there either, but I may have done the wrong thing.

I think the fix should be simple, though, so maybe you can try it for me.  Can you try editing line 2063 of descriptor.cc to change it from this:

  result->package_ = tables_->AllocateString(proto.package());

to this:

  if (proto.has_package()) {
    result->package_ = tables_->AllocateString(proto.package());
  } else {
    result->package_ = &kEmptyString;
  }

and see if that fixes it?  (The problem is that the default value for proto.package() is not yet initialized during static init time so relying on proto.package() to return the default if the field isn't present doesn't work.)

Matt Tolton

unread,
Jul 24, 2008, 10:54:12 PM7/24/08
to Kenton Varda, Protocol Buffers
Nope, didn't fix it. I get this:

(gdb) run
Starting program: /Users/mtolton/Documents/code/yame/build/test
Reading symbols for shared libraries +++. done

Program received signal EXC_BAD_ACCESS, Could not access memory.

Reason: KERN_INVALID_ADDRESS at address: 0xfffffff4
google::protobuf::DescriptorBuilder::BuildFile (this=0xbfffdb20,
proto=@0xbfffdbac) at google/protobuf/descriptor.cc:2079
2079 if (!result->package().empty()) {
(gdb) bt
#0 google::protobuf::DescriptorBuilder::BuildFile (this=0xbfffdb20,
proto=@0xbfffdbac) at google/protobuf/descriptor.cc:2079
#1 0x0002db2a in google::protobuf::DescriptorPool::BuildFile
(this=0x9fa00, proto=@0x0) at google/protobuf/descriptor.cc:1686
#2 0x0002dc30 in
google::protobuf::DescriptorPool::InternalBuildGeneratedFile
(this=0x0, data=0x0, size=0) at google/protobuf/descriptor.cc:1751
#3 0x00015e7a in proto_BuildDescriptors_config_2eproto () at
build/config.pb.cc:26
#4 0x000163bd in
StaticDescriptorInitializer_config_2eproto::StaticDescriptorInitializer_config_2eproto
(this=0x9fb30) at build/config.pb.cc:35
#5 0x000163d1 in
StaticDescriptorInitializer_config_2eproto::StaticDescriptorInitializer_config_2eproto
(this=0x9fb30) at build/config.pb.cc:36
#6 0x00079098 in __static_initialization_and_destruction_0 () at
basic_string.h:227
#7 0x00079131 in global constructors keyed to
_ZN47_GLOBAL__N_build_config.pb.cc_00000000_64E2D46822YameConfig_descriptor_E
() at basic_string.h:227
#8 0x8fe12e76 in
__dyld__ZN16ImageLoaderMachO18doModInitFunctionsERKN11ImageLoader11LinkContextE
()
#9 0x8fe0e723 in
__dyld__ZN11ImageLoader23recursiveInitializationERKNS_11LinkContextEj
()
#10 0x8fe0e809 in
__dyld__ZN11ImageLoader15runInitializersERKNS_11LinkContextE ()
#11 0x8fe04102 in __dyld__ZN4dyld24initializeMainExecutableEv ()
#12 0x8fe07b5f in __dyld__ZN4dyld5_mainEPK11mach_headermiPPKcS5_S5_ ()
#13 0x8fe01872 in __dyld__ZN13dyldbootstrap5startEPK11mach_headeriPPKcl ()
#14 0x8fe01037 in __dyld__dyld_start ()
(gdb)

Matt Tolton

unread,
Jul 24, 2008, 11:07:48 PM7/24/08
to Kenton Varda, Protocol Buffers
Ok, here is an example which gives me a seg fault when I run it.

~/Documents/code/protocrash $ ls
test.cc test.proto
~/Documents/code/protocrash $ cat test.proto
message TestMessage {
required string contents = 1;
required string tag = 2;
}
~/Documents/code/protocrash $ cat test.cc
#include "test.pb.h"

int main() {
return 0;
}
~/Documents/code/protocrash $ protoc --cpp_out=. test.proto
~/Documents/code/protocrash $ g++ *.cc /usr/local/lib/libprotobuf.a
~/Documents/code/protocrash $ ./a.out
Segmentation fault
~/Documents/code/protocrash $

Kenton Varda

unread,
Jul 24, 2008, 11:08:28 PM7/24/08
to Matt Tolton, Protocol Buffers
Oh dammit, I guess kEmptyString isn't initialized either.

Can you delete the definition of kEmptyString on line 104:

  const string kEmptyString;

And replace both instances of "&kEmptyString" in the file (line 2066 and also the line I told you to edit before) with:

  tables_->AllocateString("")

On Thu, Jul 24, 2008 at 7:54 PM, Matt Tolton <ma...@tolton.com> wrote:

Matt Tolton

unread,
Jul 25, 2008, 12:03:51 AM7/25/08
to Kenton Varda, Protocol Buffers
Ok. Yes, that seems to fix it. Thanks. :)

Kenton Varda

unread,
Jul 25, 2008, 12:40:55 AM7/25/08
to Matt Tolton, Protocol Buffers
Great.  I've committed this fix as revision 24.

(I realized that the usage of kEmptyString that already existed was fine because it isn't actually accessed; just the address is used.  So, I left it alone.)
Reply all
Reply to author
Forward
0 new messages