2

我正在构建一个用户定义的外壳。我有一个指向函数的指针数组——也就是说,一个包含可以在任何时候调用的共享库函数的数组。

我在这里输入定义

typedef void (*func_ptr)(char **);
func_ptr function;
void *pointers_to_functions[64];

我已经调试并确认我将指针放入数组的初始化工作正常,但这是安全措施的代码......

void initialize_built_in(){
    void *handle;
    char *error;
    int i;
    for (i = 0; i < 5; i++){
        handle = dlopen(builtin_files[i], RTLD_LOCAL | RTLD_LAZY);
        if (!handle) {
            fprintf(stderr, "%s\n", dlerror());
            exit(1);
        }
        pointers_to_functions[i] = dlsym(handle, builtin_functions[i]);
        if ((error = dlerror()) != NULL) {
            fprintf(stderr, "%c\n", *error);
            exit(1);
        }

        if (dlclose(handle) < 0) {
            fprintf(stderr, "%c\n", *dlerror());
            exit(1);
         }
    }
}

这是发生段错误的地方——当我调用函数时

int execute_built_in(char **argv){

    int i;
    //scan through the builtin_functions strings to find the correct index of pointers_to_functions - that is, they have the same ordering
    for (i = 0; i < sizeof(builtin_functions); i++){
        if (!strcmp(argv[0], builtin_functions[i])){
            //the index has been found
            function = pointers_to_functions[i];
            function(argv); //execute function
            return 0;
        }
    }
    return -1;
}

我的共享库确实将 argv 作为参数——所以我不认为这是问题所在。

正如我所说,调试我看到指针数组充满了地址。我想这可能是一个不正确的地址,但我在这里是一堵砖墙。

有任何想法吗?


所以我测试了指向函数调用的指针,在同一个文件中定义了我自己的函数类型(void *)。

func_ptr function;
void *testfunction(char **);
void *pointers_to_functions[64] = {testfunction};

该函数只是将某些内容打印到shell

然后我在execute_function函数中添加了一个条件来强制执行......

for (i = 0; i < sizeof(builtin_functions); i++){
        if (i == 0){
            function = pointers_to_functions[1];
            char *bleh[] = {"bleh"};
            function(bleh);
        }
        if (!strcmp(argv[0], builtin_functions[i])){
            //the index has been found
            function = pointers_to_functions[i];
            function(argv); //execute function
            return 0;
        }
    }

它有效WOOHOO!

所以我的动态链接有问题,我看不到。或者使用我的共享库——这不太可能,因为我已经构建了可以与同一项目的另一个 shell 代码一起使用的成功库。

那么,我的动态链接有什么问题?

这是一个示例共享库

#include <stdio.h>
#include <unistd.h>

struct NewBuiltIn{
    char *CommandName[64];
    char *FunctionName[64];
    char *AnalyzerName[64];
};

struct NewBuiltIn pluggin_method = {{"cd", "cd", ""}};

void cd(char *argv[]) {
    if(chdir(argv[1]) < 0){
        printf("There was an error in changing your directory. Please check the path name and retry.\n");
    }
}
4

1 回答 1

0

您的 init 函数是错误的:您执行 adlclose(handle)导致您加载的所有库都从内存中取消映射,显然,您希望调用的函数正在飞走。您必须将 lib 映射到内存,直到您完全使用存储的函数指针。

您可以通过观察段错误的地址实际上位于库映射段中来检查这一点(在 /proc/your_app_pid/maps 中)

于 2015-11-18T16:38:55.030 回答