Как правильно отлаживать разделяемую библиотеку, написанную на C? - PullRequest
3 голосов
/ 10 марта 2019

В настоящее время я пишу общую библиотеку, которая принимает имя пользователя 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 stringstream.

Библиотека однако segfaults, и я не могу точно определить, почему.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 0x00007fffffffe6e9 in ??()
# 2 0x0000000000000000 в ??()

У меня нет идей.Может ли кто-нибудь указать мне на решение, эти ошибки в источнике .so или причину, по которой и Valgrind, и gdb печатают ???несмотря на использование флага -g при компиляции?

1 Ответ

3 голосов
/ 10 марта 2019

Похоже, вы пытаетесь запустить общую библиотеку напрямую.Это не так, как работают разделяемые библиотеки.На них ссылаются другие программы, которые их используют.

Например, этот код будет использовать вашу библиотеку:

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

char *printGroups(char *);

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

Если вы впервые скомпилируете свою библиотеку следующим образом:

gcc -shared -fpic -g -Wall lib.c -o libmylib.so

Затем, предполагая, что эта библиотека находится в том же каталоге, что и приведенный выше тестовый код, вы компилируете тестовый код следующим образом:

gcc -g -Wall -Wextra -L. -o mytest mytest.c -lmylib

Затем установите переменную среды, чтобы найти вашу библиотеку:

export LD_LIBRARY_PATH=.

Затем вы можете запустить тестовую программу, которая будет использовать вашу библиотеку.

...