首页 > 解决方案 > 无法调试使我的 shell 段错误的 .so 库

问题描述

我正在尝试在 C 中制作mallocfreerealloc函数(使用 mmap )。

我正在使用以下命令行将它们包含在我的 shell 中(我正在使用 sh):

export DYLD_LIBRARY_PATH=.
export DYLD_FORCE_FLAT_NAMESPACE=1
export DYLD_INSERT_LIBRARIES="./malloc.so:./free.so:./realloc.so"

这是我的一些 malloc 代码:

#include "../incs/malloc.h"

void        *malloc(size_t size)
{
    write(2, "\nMALLOC", 7);
    t_block     *res;

    write(2, "0", 1);

    res = NULL;

    if (!(glob))
    {
        write(2, "1", 1);
        // First call of malloc, need to init glob variable
        glob = init_glob();
    }
    write(2, "2", 1);
    res = get_block(size);
    write(2, "3", 1);

    if (!res)
    return (NULL);

    write(2, "4", 1);

    return (res->memory);
}

在我的 init_glob() 函数开始时,我也有一个调试写入。

当我在我的 shell 中执行前面的命令行并运行一个随机命令(例如 ls)时,我得到的是:

MALLOC01
MALLOC01
MALLOC01
MALLOC01
MALLOC01
MALLOC01
MALLOC01
MALLOC01
MALLOC01
MALLOC01
MALLOC01
MALLOC01
MALLOC01
MALLOC01
MALLOC01Segmentation fault: 11

我真的不明白为什么它不起作用,以及如何调试它。

它应该只写一次“MALLOC01”,十次转到我的 init_glob 函数。为什么会这样循环?我怎样才能看到它在 ls 命令中崩溃的位置?

提前致谢。

===== 编辑 =====

这是我的 init_glob() 函数:

#include "../incs/malloc.h"

/*
**  This function returns a t_glob.
**  It shall init the global variable of type t_glob, on the first time
**  malloc is called in a process.
*/
t_glob      *init_glob(void)
{
    write(2, "a", 1);
    t_glob      *res;

    res = NULL;

    write(2, "b", 1);
    res = (t_glob *)allocate_memory(sizeof(t_glob));

    write(2, "c", 1);

    res->tiny = NULL;
    res->small = NULL;
    res->large = NULL;
    write(2, "d", 1);

    return (res);
}

还有我的 allocate_memory() 函数(但似乎程序甚至没有去那里):

void        *allocate_memory(size_t size)
{
    void        *res;

    res = NULL;

    res = mmap(0, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);

    return (res);
}

我的 t_glob 结构的原型是这样的:

typedef struct                  s_glob
{
    t_page                      *tiny;
    t_page                      *small;
    t_page                      *large;
    // size_t                   sizeof_block; // Avoid repeat of sizeof() call
    // size_t                   sizeof_page;
    // size_t                   getpagesize_result;
}                               t_glob;

标签: cunixsegmentation-faultmallocmmap

解决方案


我真的不明白为什么它不起作用,以及如何调试它。

通常的调试方法是让程序转储core( ulimit -c unlimited),然后使用调试器查看无限递归发生的位置。

如果我猜的话,我猜当动态加载器尝试解析调用 from mallocto 时init_glob,这个动态符号解析本身需要动态内存和调用malloc.

如果您提供MCVE,包括构建说明,您会得到更好的答案(更少的猜测)。


推荐阅读