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

时间:2019-03-10 13:30:30

标签: 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>
#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;
}

这是我的共享库中返回字符串的主要功能。我已验证该函数确实正确-在使用printf而不是open_memstream字符串流的独立程序中,相同的逻辑也可以工作。

但是库存在段错误,我无法查明原因。 Valgrind没有输出任何有用的信息:

  

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

gdb回溯也一样:

  

程序收到信号SIGSEGV,分段错误。
  0x0000000000000001在?? ()(gdb)backtrace
  #0 0x0000000000000001 in ?? ()
  #1 0x00007fffffffe6e9 in ?? ()
  #2 0x0000000000000000 in ?? ()

我没主意了。有人可以为我指出一个解决方案,还是.so源错误或Valgrind和gdb都打印的原因?尽管在编译时使用了-g标志?

0 个答案:

没有答案