我正在尝试编写一个返回结构的多线程RPC服务器。这是我的XDR文件。我正在运行rpcgen -MN foo.x
以生成多线程兼容代码。
// foo.x
struct foo_out {
string name<128>;
};
program FOO_PROG {
version FOO_VERS {
foo_out foo(void) = 2;
} = 2 ;
} = 0x31230000;
这是我的服务器,你可以看到它需要一个指向我的struct的指针,为名称字符串分配一些内存然后复制字符串。我还添加了一个调试输出
// foo_server.c
#include "foo.h"
#include <stdio.h>
#include <stdlib.h>
#include <rpc/pmap_clnt.h>
#include <string.h>
#include <memory.h>
#include <sys/socket.h>
#include <netinet/in.h>
bool_t foo_2_svc(foo_out *out, struct svc_req *req) {
out->name = malloc(sizeof("foo"));
strcpy(out->name, "foo");
printf("Value: '%s'\n", out->name);
return TRUE;
}
int
foo_prog_2_freeresult(SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result) {
xdr_free(xdr_result, result);
return(1);
}
这是客户。它创建一个变量,传入指向该变量的指针,然后输出值:
// foo_client.c
#include "memory.h" /* for memset */
#include "foo.h"
#include "stdio.h"
#include "stdlib.h"
#include "rpc/pmap_clnt.h"
#include "string.h"
#include "memory.h"
#include "sys/socket.h"
#include "netinet/in.h"
#include <unistd.h>
int
main (int argc,char **argv)
{
CLIENT *cl;
cl = clnt_create("127.0.0.1", FOO_PROG, FOO_VERS, "tcp");
if (cl == NULL) {
clnt_perror(cl, "call failed");
exit (1);
}
foo_out out;
if (foo_2(&out, cl) != RPC_SUCCESS) {
printf("failed \n");
// exit(1);
}
printf("foo out: %s\n", out.name);
sleep(1);
exit(0);
}
当我运行它时,服务器很好我每次通过客户端调用时都会看到Value: 'foo'
。然而,客户端崩溃与segv。使用地址清洁剂我得到了这个:
=================================================================
==8269==ERROR: AddressSanitizer: SEGV on unknown address 0x0000004b0503 (pc 0x7fc9e2b5160f bp 0x000000000003 sp 0x7ffe264190c0 T0)
#0 0x7fc9e2b5160e in xdr_string (/lib/x86_64-linux-gnu/libc.so.6+0x13b60e)
#1 0x460751 in __interceptor_xdr_string.part.268 (/vagrant/foo/foo_client+0x460751)
#2 0x4b04a7 in xdr_foo_out /vagrant/foo/foo_xdr.c:13
#3 0x7fc9e2b4b3ea (/lib/x86_64-linux-gnu/libc.so.6+0x1353ea)
#4 0x4b03b8 in foo_2 /vagrant/foo/foo_clnt.c:15
#5 0x4b042e in main /vagrant/foo/foo_client.c:28
#6 0x7fc9e2a3682f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
#7 0x405298 in _start (/vagrant/foo/foo_client+0x405298)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV ??:0 xdr_string
==8269==ABORTING
当我使用GDB在foo_2
调用之前和之后检查结构的内容时,它没有改变。看起来服务器根本没有修改该值。
问题:如何使用多线程RPC调用使用字符串修改结构?如果我将我的示例更改为使用整数而不是字符串,则它可以正常工作。所以我似乎缺少一些基本的东西。关于我做错了什么的想法或者调试这个的步骤?
答案 0 :(得分:0)
在您的客户端尝试为foo_out结构分配内存:
whereHas()