如何正确调试用C编写的共享库?

如何正确调试用C编写的共享库?,c,linux,gcc,gdb,valgrind,C,Linux,Gcc,Gdb,Valgrind,我目前正在编写一个共享库,它使用UNIX用户名并返回一个字符串,其中包含用户所属的所有组,格式为[group1,group2,group3…] #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <getopt.h> #include <utmp.h> #include <sys/types.h> #include <grp.h>

我目前正在编写一个共享库,它使用UNIX用户名并返回一个字符串,其中包含用户所属的所有组,格式为
[group1,group2,group3…]

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <utmp.h>
#include <sys/types.h>
#include <grp.h>
#include <pwd.h>

int num_groups = 0;
struct passwd *pwd;
gid_t *groups;
struct group *grp;

FILE *stream;
char *buff;
size_t length;

char *printGroups(char *arg)
{
    stream = open_memstream(&buff, &length);
    pwd = getpwnam(arg);
    getgrouplist(arg, pwd->pw_gid, groups, &num_groups);
    groups = malloc(num_groups * sizeof(gid_t));
    if (groups == NULL){
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    getgrouplist(arg, pwd->pw_gid, groups, &num_groups);
    fprintf(stream, " [");
    for (int i = 0; i < num_groups; ++i){
        grp = getgrgid(groups[i]);
        if (i == num_groups - 1)
            fprintf(stream, "%s", grp->gr_name);
        else
            fprintf(stream, "%s ", grp->gr_name);
    }
    free(groups);
    fprintf(stream, "]");
    fclose(stream);
    return buff;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int num_组=0;
结构密码*pwd;
gid_t*组;
结构组*grp;
文件*流;
字符*浅黄色;
尺寸与长度;
字符*打印组(字符*参数)
{
stream=open_memstream(&buff,&length);
pwd=getpwnam(arg);
getgrouplist(arg、pwd->pw_-gid、groups和num_-groups);
groups=malloc(num_groups*sizeof(gid_t));
如果(组==NULL){
佩罗尔(“马洛克”);
退出(退出失败);
}
getgrouplist(arg、pwd->pw_-gid、groups和num_-groups);
fprintf(流,“[”);
对于(int i=0;igr\u名称);
其他的
fprintf(流,“%s”,grp->gr\u名称);
}
自由(团体);
fprintf(流“]”);
fclose(流);
返回buff;
}
这是我的共享库中返回字符串的主要函数。我验证了该函数确实是正确的-相同的逻辑在使用printf而不是
open_memstream
stringstream的独立程序中工作

然而,图书馆出现了故障,我无法查明原因。Valgrind不输出任何有用的内容:

gcc-shared-fpic-g-Wall lib.c
valgrind./a.out
==9916==进程以信号11(SIGSEGV)的默认动作终止
==9916==访问不在地址0x0的映射区域内
==9916==0x1:???
==9916==0xFFF000672:

gdb回溯也是如此:

程序接收信号SIGSEGV,分段故障。
0x0000000000000001英寸??()(gdb)回溯
#0 0x0000000000000001英寸??()
#1 0x00007FFFFFE6E9英寸??()
#2 0x0000000000000000英寸??()


我没有主意了。有人能给我指出一个解决办法吗?这是一个错误的来源还是Valgrind和gdb都打印的原因???尽管在编译时使用了-g标志?

但看起来您试图直接运行共享库。共享库不是这样工作的。它们被其他使用它们的程序引用

例如,此代码将使用您的库:

#include <stdio.h>
#include <stdlib.h>

char *printGroups(char *);

int main()
{
    char *groups = printGroups("root");
    printf("groups: %s\n", groups);
    free(groups);
    return 0;
}
export LD_LIBRARY_PATH=.
然后,假设此库与上述测试代码位于同一目录中,您将按照如下方式编译测试代码:

gcc -shared -fpic -g -Wall lib.c -o libmylib.so
gcc -g -Wall -Wextra -L. -o mytest mytest.c -lmylib
然后设置环境变量以查找库:

#include <stdio.h>
#include <stdlib.h>

char *printGroups(char *);

int main()
{
    char *groups = printGroups("root");
    printf("groups: %s\n", groups);
    free(groups);
    return 0;
}
export LD_LIBRARY_PATH=.

然后,您可以运行将使用您的库的测试程序。

请发布一篇文章。函数中使用的大多数变量都是在其他地方定义的。另外,您可以格式化这个吗?您应该开始检查系统调用的返回值。另外,
gcc-shared-fpic-g3-O0-Wall lib.c
(如果在Valgrind下运行,则使用
-O1
)。刚刚发布了整个源代码。我不知道如何改进格式。你真的要执行库吗?而不是从可执行文件链接并运行它?当我从一个可执行文件调用库函数时,它的执行似乎是合理的。如果这是有意的,您可能会感兴趣,谢谢!实际上是我写的,所以用在dlopen加载的程序中。我使用gdb验证了该函数是否正确加载并设置了找到的组的srting。我的主程序仍然在vprintf.c上出错,但这是另一个问题的问题