6

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

我尝试使用 callgrind

valgrind --tool=callgrind path/to/postgres arguments-to-postgres

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

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

任何想法都会受到高度评价。

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

4

2 回答 2

2

使用 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(); }

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。

于 2011-07-27T10:17:44.797 回答
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 加载文件来修改测试,即:

全部:exe lib.so
exe:exe.c
        cc -g0 -o exe exe.c -ldl

lib.so:lib.c
        cc -shared lib.c -o lib.so
干净的:
        rm -f exe lib.so *.o

#包括
#包括

无效的主要(){
    无效*句柄;
    无效 (*p)();
    诠释我;

    句柄 = dlopen("./lib.so", RTLD_LAZY);
    if ( !handle ) { printf("找不到对象\n"); 返回; }
    p = dlsym(句柄,“someFunction”);
    if ( ! p ) { printf("找不到函数\n"); 返回; }
    对于 (i = 0; i < 100; ++i) (*p)();
    dlclose(句柄);
}

与呼叫研磨一起使用。也许 Postgres 没有使用 -ldl 打开目标文件?

于 2011-07-29T08:27:34.117 回答