无需重新编译主程序即可对共享对象进行配置

时间:2011-07-25 05:31:25

标签: c++ postgresql profiling shared-libraries callgrind

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

我使用

尝试了callgrind
valgrind --tool=callgrind path/to/postgres arguments-to-postgres

这为我提供了PostgreSQL本身的分析信息,但无法记录我感兴趣的共享库。

我也试过sprof,但我不知道如何让那个人工作。

任何想法都会受到高度关注。

P.S。:请不要建议只在调试器中暂停应用程序。如果函数运行时间低于0.01秒,我需要更多详细结果。

2 个答案:

答案 0 :(得分:2)

使用callgrind应该按预期工作。为了测试这个,我使用一个简单的库和main functionMakefile:

设置了一个简单的项目
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(); }

exe.c是一个非常简单的可执行文件:

int someFunction();
void main() { someFunction(); }

使用Makefile构建可执行文件并使用valgrind运行它,如下所示:

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

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

答案 1 :(得分:1)

第1点:Valgrind似乎存在特权升级的问题,这很可能是由Postgres执行的,请参阅http://www.mail-archive.com/valgrind-users@lists.sourceforge.net/msg02355.html

第2点:您是否曾尝试证明(例如使用strace)您的SL实际上是在同一进程中加载​​的?你试过--trace-children = yes?

第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

#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);
}

与callgrind一起使用。也许Postgres没有使用-ldl来打开目标文件?