RPC:分段错误(堆芯转储)

RPC:分段错误(堆芯转储),c,segmentation-fault,rpc,C,Segmentation Fault,Rpc,因为我偶然发现了这个问题,而且没有任何答案,所以我决定寻求帮助来解决我的问题 我想制作一个简单的RPC服务器客户端,其中有三个操作: 数组X[]的平均值 数组X[]的最大和最小元素 将数组X[]的每个元素与浮点数r相乘 所以我创建了我的.x文件,并生成了我需要的代码框架 struct X_arr { int X <100>; int X_size; }; struct max_min { int max; int min; }; struct

因为我偶然发现了这个问题,而且没有任何答案,所以我决定寻求帮助来解决我的问题

我想制作一个简单的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;
于是地狱开始了。 更具体地说,服务器上发生了一个分段错误,不久之后,客户机在没有连接服务器的情况下开始“工作”

“Segmentation Fault”给了我一个流氓指针或未初始化变量的概念,但是在花了太多时间研究代码之后,我没有发现任何类似的东西。我怀疑我的
.x
文件是如何编写的,但我测试了一个更简单的版本,得到了相同的结果

出了什么问题

ps:repo可更深入地了解这一点

更新: 我在服务器上处理这些过程,看起来几乎整个作为参数传递的结构实际上根本没有传递任何东西,导致了基于垃圾的for循环。

啊,羞耻之路

结果是,在我创建菜单并给出我的值之前,生成的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");
}
因此,每次客户端启动时,都会有对所有函数的调用,没有参数初始化,这要感谢您糟糕的编码技巧

修正了它,文字就像一个符咒。你可以自己测试


“[…]但是在花了太多时间研究代码之后,我没有发现任何与之相近的东西。”这尖叫着“我需要一个调试器。”看起来很好,但调试器告诉你实际发生了什么。请写一个。如果你想从我上面链接的repo中测试它,只需启动
rpcbind
服务,然后键入a
make
,然后分别向两个终端运行
/dum\u服务器
/dum\u客户端
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");
}