问题
I'm catching a Valgrind finding on an uninitialized read. I know exactly where its coming from - its an empty std::string
declared in a cpp
file with static
storage class.
The object file that has the std::string
's storage allocation is listed first in the static archive.
# string of interest is located in a.o
LIBOBJS := a.o b.o c.o ... x.o y.o z.o
library.a: $(LIBOBJS)
$(AR) $(ARFLAGS) $@ $(LIBOBJS)
$(RANLIB) $@
In addition, I modified the link recipe to the following (I know it looks silly):
program.exe: library.a $(TESTOBJS)
$(CXX) $(CXXFLAGS) -o $@ ./library.a $(TESTOBJS) ./library.a -pthread
Above, library.a
is listed the first time to ensure the std::string
static initializer is the very first initializer that is run. library.a
is listed a second time to ensure all symbols can be found for the test object since these are single pass linkers.
From Valgrind results on both OS X and Linux, it appears the linkers are not respecting object file order and static initialization.
I have two questions. First, how do I force Apple's linker to respect the order of the object files? Second how do I force GNU's linker to respect the order of the object files?
We cannot use linker scripts. The GCC folks specifically tell folks not to use them. Plus, I'm not sure of the format on Apple platforms.
For what its worth, this is a fallback in case init_priority
is not available. Unfortunately, its not available on many platforms. Only modern GNU linkers have it, and Apple lacks it completely.
(Our testing goes back quite a ways, from Fedora 1 with GCC 3.2 to Windows 2000).
来源:https://stackoverflow.com/questions/34698745/how-to-force-the-linker-to-honor-object-file-order