简体   繁体   English

功能段故障的指针

[英]Pointer to function seg faulting

I'm building a user defined shell. 我正在构建一个用户定义的外壳。 I have an array of pointers to functions -- that is, an array full of shared library functions that can be invoked at any point. 我有一个指向函数的指针数组-即,一个充满共享库函数的数组,可以在任何时候调用它。

I typedef here 我在这里输入

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

I have debugged and confirmed that my initializations of placing the pointers into the array is working properly, but here's the code for safe measures... 我已经调试并确认将指针放置到数组中的初始化工作正常,但是这里是安全措施的代码...

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);
         }
    }
}

Here's where the seg fault occurs -- when I invoke the function 这是段错误发生的地方-当我调用该函数时

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;
}

My shared library does indeed take argv as a parameter -- so I don't believe this is the problem. 我的共享库确实确实将argv作为参数-所以我不认为这是问题所在。

As I said, debugging I see that the array of pointers is filled with addresses. 就像我说的,调试时,我看到指针数组充满了地址。 I suppose it could be an incorrect address somehow, but I'm at a brick wall here. 我想这可能是一个不正确的地址,但我在这里的一堵墙。

Any ideas? 有任何想法吗?


So I tested the pointer to function call be defining my own function type (void *) in the same file. 因此,我在同一文件中定义了自己的函数类型(void *)来测试了函数调用的指针。

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

where the function just prints something out to the shell 该函数只是在外壳上打印出一些东西

then I added a condition in the execute_function function to force execution... 然后我在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;
        }
    }

and it works WOOHOO! 而且效果WOOHOO!

So I either have a problem with my dynamic linking, which I can't see. 所以我的动态链接有一个问题,我看不到。 Or with my shared library -- which is unlikely because I've already built successful libraries that work with another shell code of the same project. 或使用我的共享库-这不太可能,因为我已经构建了可以与同一项目的另一个Shell代码一起使用的成功库。

So, what's wrong with my dynamic linking? 那么,我的动态链接怎么了?

Here's an example shared library 这是共享库的示例

#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");
    }
}

Your init function is wrong: you perform a dlclose(handle) which causes all the lib you loaded to be unmapped from memory, and obviously, the functions you expect to call are flying away. 您的init函数是错误的:您执行dlclose(handle)会导致从内存中取消映射所有已加载的lib,显然,您希望调用的函数正在飞走。 You must keep the lib mapped to memory until you completely finished using the function pointers you stored. 您必须将库映射到内存,直到完全使用存储的函数指针为止。

You can probably check this by observing that the address that segfaults actually lies in the library mapped segment (in /proc/your_app_pid/maps) 您可以通过观察segfaults的地址实际上是否位于库映射段中(在/ proc / your_app_pid / maps中)来进行检查

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM