我的ceph版本为13.2.2
以ceph-osd为例子
在src/CMakeLists.txt中可以看到如下几行编译ceph-osd的代码
add_subdirectory(osd)
set(ceph_osd_srcs ceph_osd.cc)
add_executable(ceph-osd ${ceph_osd_srcs})
add_dependencies(ceph-osd erasure_code_plugins)
target_link_libraries(ceph-osd osd os global-static ceph-common
${BLKID_LIBRARIES} ${RDMA_LIBRARIES} ${ALLOC_LIBS})
从上面可以看到,ceph_osd编译时作为源文件编译的仅有ceph_osd.cc这一个,其他的都是作为库链接到ceph_osd.中了,比如ceph-common和osd。
查看src/osd/CMakeLists.txt文件
并不是所有的文件在gdb调试时都搜索不到,osd目录下的文件就能搜索到,其原因是osd目录下的源文件都被编译成静态库了,而其他一些源文件(比如msg下的)都被编译成动态库了,而静态库在ceph_osd编译时会拷贝到ceph_osd中,所以可以搜索到符号表,但是动态库则不能,查看CMakeLists,txt就可以看到,如下
set(osd_srcs
OSD.cc
Watch.cc
ClassHandler.cc
PG.cc
PGLog.cc
PrimaryLogPG.cc
ReplicatedBackend.cc
ECBackend.cc
ECTransaction.cc
PGBackend.cc
OSDCap.cc
Watch.cc
ClassHandler.cc
Session.cc
SnapMapper.cc
ScrubStore.cc
osd_types.cc
ECUtil.cc
ExtentCache.cc
mClockOpClassSupport.cc
mClockOpClassQueue.cc
mClockClientQueue.cc
OpQueueItem.cc
${CMAKE_SOURCE_DIR}/src/common/TrackedOp.cc
${osd_cyg_functions_src}
${osdc_osd_srcs})
if(HAS_VTA)
set_source_files_properties(osdcap.cc
PROPERTIES COMPILE_FLAGS -fno-var-tracking-assignments)
endif()
add_library(osd STATIC ${osd_srcs}
$<TARGET_OBJECTS:cls_references_objs>
$<TARGET_OBJECTS:global_common_objs>
$<TARGET_OBJECTS:heap_profiler_objs>)
add_library(osd STATIC ${osd_srcs} 就是将osd目录下的代码编译成libosd静态库
而查看src/CMakeLists.txt
set(libcommon_files
${CMAKE_BINARY_DIR}/src/include/ceph_ver.h
ceph_ver.c
common/AsyncOpTracker.cc
common/DecayCounter.cc
common/LogClient.cc
common/LogEntry.cc
common/PrebufferedStreambuf.cc
common/CachedPrebufferedStreambuf.cc
common/BackTrace.cc
common/perf_counters.cc
common/perf_histogram.cc
msg/simple/Pipe.cc
msg/simple/PipeConnection.cc
msg/simple/SimpleMessenger.cc
msg/async/AsyncConnection.cc
msg/async/AsyncMessenger.cc
msg/async/Event.cc
msg/async/EventSelect.cc
msg/async/Stack.cc
msg/async/PosixStack.cc
msg/async/net_handler.cc
msg/QueueStrategy.cc
add_library(common-objs OBJECT ${libcommon_files})
set(ceph_common_objs
$<TARGET_OBJECTS:common_buffer_obj>
$<TARGET_OBJECTS:common_texttable_obj>
$<TARGET_OBJECTS:compressor_objs>
$<TARGET_OBJECTS:common-objs>
$<TARGET_OBJECTS:common_mountcephfs_objs>
$<TARGET_OBJECTS:global_common_objs>
$<TARGET_OBJECTS:crush_objs>)
add_library(ceph-common SHARED ${ceph_common_objs})
可以看到libceph-common被编译成了动态库,所以在其中的源文件就不能在gdb调试时被找到。
方法:
libceph-common动态库处于/usr/lib64/ceph/下,在gdb中执行
(gdb) set env LD_LIBRARY_PATH /usr/lib64/ceph/
或者
在bashrc中设置LD_LIBRARY_PATH包含 /usr/lib64/ceph/
当然也可以利用systemtap直接probe动态库
但是有一个问题,gdb设置断点时不能指定libceph-common中的函数,只能指定某个源文件的某一行。这个有待研究。但是用systemtap调试动态库时可以指定函数。