ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2019-11-08 06:50:33  阅读:183  来源: 互联网

标签:gdb gcc valgrind c-3 linux


我当前正在编写一个使用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的独立程序中,相同的逻辑也可以工作.

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

gcc -shared -fpic -g -Wall lib.c
valgrind ./a.out
==9916== Process terminating with default action of signal 11 (SIGSEGV)
==9916== Access not within mapped region at address 0x0
==9916== at 0x1: ???
==9916== by 0xFFF000672: ???

gdb backtrace也是如此:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000001 in ?? () (gdb) backtrace
#0 0x0000000000000001 in ?? ()
#1 0x00007fffffffe6e9 in ?? ()
#2 0x0000000000000000 in ?? ()

我没主意.有人可以为我指出一个解决方案,还是.so源错误或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;
}

如果您首先像这样编译您的库:

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

然后,假设该库与上述测试代码位于同一目录中,则您可以像这样编译测试代码:

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

然后设置环境变量以找到您的库:

export LD_LIBRARY_PATH=.

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

标签:gdb,gcc,valgrind,c-3,linux
来源: https://codeday.me/bug/20191108/2006226.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有