为什么 "Multiple definitions linker error" 当 nm 只看到一个定义

Why "Multiple definitions linker error" when nm only sees one definition

将一些目标文件链接在一起时,我遇到了一堆错误,例如:

obj-ia32/ShadowRoutine.o: In function `InitializeMap(unsigned int*)':
ShadowRoutine.cpp:(.text+0x0): multiple definition of `InitializeMap(unsigned int*)'
obj-ia32/ShadowRoutine.o:ShadowRoutine.cpp:(.text+0x0): first defined here

使用编译和链接命令:

g++ -DBIGARRAY_MULTIPLIER=1 -Wall -Wno-unknown-pragmas -fno-stack-protector \
    -DTARGET_IA32 -DHOST_IA32 -DTARGET_LINUX  -I../../../source/include/pin \
    -I../../../source/include/pin/gen -I../../../extras/components/include \
    -I../../../extras/xed-ia32/include -I../../../source/tools/InstLib -O3 \
    -fomit-frame-pointer -fno-strict-aliasing -Wno-unused-variable \
    -Wno-unused-function -I. -Ishadow-memory -m32 -c \
    -o obj-ia32/ShadowRoutine.o ShadowRoutine.cpp
g++ -DBIGARRAY_MULTIPLIER=1 -Wall -Wno-unknown-pragmas -fno-stack-protector \
    -DTARGET_IA32 -DHOST_IA32 -DTARGET_LINUX  -I../../../source/include/pin \
    -I../../../source/include/pin/gen -I../../../extras/components/include \
    -I../../../extras/xed-ia32/include -I../../../source/tools/InstLib -O3 \
    -fomit-frame-pointer -fno-strict-aliasing -Wno-unused-variable \
    -Wno-unused-function -I. -Ishadow-memory -m32 -c \
    -o obj-ia32/Jikes.o Jikes.cpp
g++ -shared -Wl,--hash-style=sysv -Wl,-Bsymbolic \
    -Wl,--version-script=../../../source/include/pin/pintool.ver \
    -m32 -o obj-ia32/Jikes.so obj-ia32/ClientReq.o obj-ia32/Server.o \
    obj-ia32/ShadowRoutine.o obj-ia32/FncnMap.o obj-ia32/Trace.o \
    obj-ia32/Jikes.o obj-ia32/ClientReq.o obj-ia32/Server.o \
    obj-ia32/ShadowRoutine.o obj-ia32/FncnMap.o obj-ia32/Trace.o \
    -L../../../ia32/lib -L../../../ia32/lib-ext -L../../../ia32/runtime/glibc \
    -L../../../extras/xed-ia32/lib \
    -L/home/karl/r/git/pin/source/tools/Jikes/zmq/inst/lib \
    -lpin -lxed -lpindwarf -ldl -lzmq

只有两个 InitializeMap 的目标文件是 Jikes.oShadowRoutine.o:

$ nm obj-ia32/Jikes.o  | grep InitializeMap
         U _Z13InitializeMapPj
$ nm obj-ia32/ShadowRoutine.o | grep InitializeMap
00000000 T _Z13InitializeMapPj
$ nm obj-ia32/* | grep InitializeMap
         U _Z13InitializeMapPj
00000000 T _Z13InitializeMapPj

那么为什么我得到 "multiple definitions of InitializeMap" 如果它在一个目标文件中只有 "defined" 而在唯一需要它的其他目标文件中 "undefined" 使用 extern

这是声明、定义和使用的样子:

$ grep -r InitializeMap *
Jikes.cpp:  if (rtn_name == "sysInitializeMap") {       RTN_INSERT_1(InitializeMap);
Binary file obj-ia32/Jikes.o matches
Binary file obj-ia32/ShadowRoutine.o matches
ShadowRoutine.cpp:VOID InitializeMap(ADDRINT *smID) { init_map(*(int*)smID); }
ShadowRoutine.hpp:VOID InitializeMap(ADDRINT *smID);

其中两个 cpp 文件 #include "ShadowRoutine.hpp"

编辑:我的问题是为什么链接器命令(上面第二个代码片段中的第三个 g++ 命令)不起作用,即使 nm 说该函数仅在 [=17 的文本中定义=] 和 undefinedJikes.o?

您在 link 命令中列出了文件 obj-ia32/ShadowRoutine.o 两次。