RPC:分段错误(核心转储)

Posted

技术标签:

【中文标题】RPC:分段错误(核心转储)【英文标题】:RPC: Segmentation Fault (core dumped) 【发布时间】:2018-05-26 15:38:15 【问题描述】:

由于我偶然发现了这个问题并且没有任何答案here,我决定针对我的情况寻求帮助。

我想制作一个简单的 RPC 服务器-客户端,其中包含三个操作:

数组 X[] 的平均值 数组 X[] 的最大和最小元素 将数组 X[] 的每个元素与浮点数 r 相乘

所以我制作了我的 .x 文件,并生成了我需要的代码骨架。

struct X_arr

    int X <100>;
    int X_size;
;

struct max_min

    int max;
    int min;
;

struct X_times_r

    int X <100>;
    int X_size;
    float r;
;

struct prod

    float prod <100>;
;

program DUM_PROG

    version DUM_VERS
    
        float average(X_arr)=1;
        max_min max_and_min(X_arr)=2;
        prod product(X_times_r)=3;
    =1;
=0x23451111;

然后我修复了服务器的 3 个远程过程,并用一个简单的硬编码数组测试了我的客户端,效果很好(尽管我猜有时会出现一些 arguments cannot be encoded 错误)。

但后来我尝试为客户制作一个菜单,询问 X[] 的长度并获取每个所需操作的元素:

...


int i;
int flag=1;
int n;
int r;

int choice;

printf("--------------------------------------------------------------------------\n");

do


    printf("==========================\n");
    printf("=====Dummy Operations=====\n");
    printf("==========================\n");
    printf("1. average of X[] \n");
    printf("2. max & min of X[] \n");
    printf("3. r*X[] \n");
    printf("4. Exit \n");
    printf("==========================\n");
    printf("Choice: ");
    scanf("%d", &choice);
    printf("==========================\n");




    if(choice==1)
    
        ///////////////////////////////////////
        //average of X[]
        ///////////////////////////////////////
        printf("Number of elements: ");
        scanf("%d", &n);

        average_1_arg.X.X_len=n;
        average_1_arg.X_size=n;
        average_1_arg.X.X_val=(int *)malloc(n*sizeof(int));

        for(i=0;i<n;i++)
        
            printf("X[%d] = ", i);
            scanf("%d", &average_1_arg.X.X_val[i]);
        

        result_1=average_1(&average_1_arg, clnt);

        printf("Average of X[]: %.2f\n", *result_1);
        ///////////////////////////////////////
        ///////////////////////////////////////
    
    else if(choice==2)
    
        ///////////////////////////////////////
        //max and min of X[]
        ///////////////////////////////////////
        printf("Number of elements: ");
        scanf("%d", &n);

        max_and_min_1_arg.X.X_len=n;
        max_and_min_1_arg.X_size=n;
        max_and_min_1_arg.X.X_val=(int *)malloc(n*sizeof(int));

        for(i=0;i<n;i++)
        
            printf("X[%d] = ", i);
            scanf("%d", &max_and_min_1_arg.X.X_val[i]);
        

        result_2=max_and_min_1(&max_and_min_1_arg, clnt);

        printf("Max of X[]: %d\n", result_2->max);
        printf("Min of X[]: %d\n", result_2->min);
        ///////////////////////////////////////
        ///////////////////////////////////////
    
    else if(choice==3)
    
        ///////////////////////////////////////
        //r*X[]
        ///////////////////////////////////////
        printf("Number of elements: ");
        scanf("%d", &n);

        printf("r: ");
        scanf("%d", &r);

        product_1_arg.X.X_len=n;
        product_1_arg.X_size=n;
        product_1_arg.r=r;
        product_1_arg.X.X_val=(int *)malloc(n*sizeof(int));

        for(i=0;i<n;i++)
        
            printf("X[%d] = ", i);
            scanf("%d", &product_1_arg.X.X_val[i]);
        

        result_3=product_1(&product_1_arg, clnt);

        for(i=0;i<n;i++)
            printf("%.2f*X[%d]=%.2f\n", product_1_arg.r, i, result_3->prod.prod_val[i]);
        ///////////////////////////////////////
        ///////////////////////////////////////
    
    else if(choice==4)
    
        flag=0;
    
    else
    
        printf("Invalid Choice. Terminating in 3...2...1...\n");
        exit(1);
    
while(flag);

printf("--------------------------------------------------------------------------\n");

...

然后地狱爆发了。 更具体地说,服务器出现分段错误,不久之后,客户端开始在没有服务器连接的情况下“工作”。

“Segmentation Fault”给了我一个流氓指针或未初始化变量的想法,但是在查看代码太多时间之后,我没有找到任何接近的东西。我怀疑我的 .x 文件的编写方式,但我测试了一个更简单的版本,结果相同。

出了什么问题?

ps:回购以更深入地了解此here

更新: 我在服务器上搞砸了程序,似乎几乎整个作为参数传递的结构实际上根本没有传递任何东西,导致基于垃圾创建一个 for 循环。

【问题讨论】:

"[...] 但是在查看代码太久之后,我没有找到任何接近的东西。"这尖叫着“我需要一个调试器”。看起来很好,但调试器会告诉你实际发生了什么。 请写MCVE。 如果你想从我上面链接的 repo 中测试它,只需启动 rpcbind 服务,然后在分别运行 ./dum_server./dum_client 到两个终端之前键入 make。跨度> 【参考方案1】:

啊,耻辱之路……

原来我留下生成的rpc文件交给我的所有默认函数调用,之前 我制作了我的菜单并给出了我的价值观:

result_1 = average_1(&average_1_arg, clnt);
if (result_1 == (float *) NULL) 
clnt_perror (clnt, "call failed");


result_2 = max_and_min_1(&max_and_min_1_arg, clnt);
if (result_2 == (max_min *) NULL) 
clnt_perror (clnt, "call failed");


result_3 = product_1(&product_1_arg, clnt);
if (result_3 == (prod *) NULL) 
    clnt_perror (clnt, "call failed");

所以每次客户端启动时,已经调用了所有函数,没有参数初始化,这真的要感谢你可怕的编码技巧。

修复了它,文字就像一个魅力。你可以自己测试here

【讨论】:

以上是关于RPC:分段错误(核心转储)的主要内容,如果未能解决你的问题,请参考以下文章

分段错误(核心转储)

运行我的代码时出现分段错误(核心转储)问题

pyqt5 中的分段错误(核心转储)

编程求解器的分段错误(核心转储)

分段错误(核心转储) - 无法访问的计数器值

我运行程序时出现“分段错误(核心转储)”