C++ 配置共享对象而不重新编译主程序

C++ 配置共享对象而不重新编译主程序,c++,postgresql,profiling,shared-libraries,callgrind,C++,Postgresql,Profiling,Shared Libraries,Callgrind,我目前正在开发一个用于加载到PostgreSQL的共享lilbrary(作为C语言函数,请参阅)。现在,我想在不重新编译PostgreSQL本身的情况下分析这个库中的函数 我试着用 valgrind --tool=callgrind path/to/postgres arguments-to-postgres 这为我提供了PostgreSQL本身的分析信息,但无法记录我感兴趣的共享库 我也尝试了sprof,但我不知道如何让它工作 任何想法都将受到高度赞赏 注意:请不要建议在调试器中暂停应用程序

我目前正在开发一个用于加载到PostgreSQL的共享lilbrary(作为C语言函数,请参阅)。现在,我想在不重新编译PostgreSQL本身的情况下分析这个库中的函数

我试着用

valgrind --tool=callgrind path/to/postgres arguments-to-postgres
这为我提供了PostgreSQL本身的分析信息,但无法记录我感兴趣的共享库

我也尝试了
sprof
,但我不知道如何让它工作

任何想法都将受到高度赞赏


注意:请不要建议在调试器中暂停应用程序。由于函数运行时间远低于0.01秒,我需要更详细的结果。

使用callgrind应该可以正常工作。为了测试这一点,我使用简单库和主函数Makefile设置了一个简单项目:

CFLAGS=-fpic
exe:exe.o lib.so
        cc -o exe exe.o lib.so
lib.so:lib.o
        cc -shared lib.o -o lib.so
clean:
        rm -f exe lib.so *.o
lib.c是一个简单的库,包含2个函数:

#include <stdio.h>
void someOtherFunction() { printf("someOtherFunction\n"); }
void someFunction() { printf("someFunction\n"); someOtherFunction(); }
使用Makefile构建可执行文件并使用valgrind运行它,如下所示:

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD valgrind --tool=callgrind ./exe

如果检查callgrind输出,您将在共享库中找到这两个函数的分析数据。如果看不到这些功能,您可能正在使用不支持此功能的非标准环境。我使用的是Linux Mint 11 x64,带有最新的补丁。

第1点:Valgrind似乎在权限提升方面存在问题,这很可能由Postgres执行,请参阅

第2点:您是否试图证明(例如,使用strace)您的SL实际上是在同一过程中加载的?你试过跟踪孩子吗

第3点:我试图通过使用-g0编译exe.o和exe并使用dlopen加载文件来修改测试,即:

all: exe lib.so exe : exe.c cc -g0 -o exe exe.c -ldl lib.so:lib.c cc -shared lib.c -o lib.so clean: rm -f exe lib.so *.o 全部:exe lib.so exe:exe.c cc-g0-o exe.c-ldl lib.so:lib.c cc-shared lib.c-o lib.so 清洁: rm-f exe lib.so*.o 及

#包括 #包括 void main(){ 无效*手柄; 无效(*p)(); int i; handle=dlopen(“./lib.so”,RTLD_-LAZY); if(!handle){printf(“找不到对象”);return;} p=dlsym(句柄,“someFunction”); if(!p){printf(“未找到函数”);return;} 对于(i=0;i<100;++i)(*p)(); dlclose(手柄); }
与callgrind合作。可能Postgres没有使用-ldl打开对象文件?

谢谢您的输入。这个最小的例子有效。但是,在我上面的例子中有两个主要区别:库不是在编译时链接的,而是在运行时使用
dlopen
。此外,我的Postgres构建没有启用调试信息。因此,callgrind似乎在被调用的函数中迷失了方向。PostgreSQL是开源的-用符号重新编译它。谢谢你的想法。关于第2点:strace输出只包含一个对execve的调用,据我所知,这表明一切都在同一个进程中运行。但是,添加--trace children=yes没有效果。稍后我会看一看你的第一点,现在我的时间不多了。我现在有时间看一看你的第一点。对我来说,这也很可能是造成麻烦的原因。这就留下了一个问题:还有其他建议吗?以root身份运行postgres以防止权限升级?postgres禁止以root身份运行。但是,我可以用它自己的用户以单用户模式启动它。但是,这并不能解决问题。它是否仍然调用setuid()?如果是的话,你可以通过LD_预加载setuid调用来解决这个问题。只需一个简短的更新:升级到PostgreSQL 9.0和Ubuntu 11.4就可以了。现在一切正常。 all: exe lib.so exe : exe.c cc -g0 -o exe exe.c -ldl lib.so:lib.c cc -shared lib.c -o lib.so clean: rm -f exe lib.so *.o #include #include void main() { void *handle; void (*p)(); int i; handle = dlopen("./lib.so", RTLD_LAZY); if ( ! handle ) { printf("Object not found\n"); return; } p = dlsym(handle, "someFunction"); if ( ! p ) { printf("Function not found\n"); return; } for (i = 0; i < 100; ++i) (*p)(); dlclose(handle); }