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