C++ rpc服务器返回结果字符将获取段错误
当服务器端返回为整数(我设置了整数版本rpc_telnet.x)时,它就可以完美地工作了。 但当服务器端返回结果为string(char*)时,它将得到段错误。 那么,如何正确设置return char(result->msg)? 下面是我的服务器端代码C++ rpc服务器返回结果字符将获取段错误,c++,c,linux,rpc,C++,C,Linux,Rpc,当服务器端返回为整数(我设置了整数版本rpc_telnet.x)时,它就可以完美地工作了。 但当服务器端返回结果为string(char*)时,它将得到段错误。 那么,如何正确设置return char(result->msg)? 下面是我的服务器端代码 ------------------------ rpc_telnet_server.c ------------------------------------------------ 01 /* 02*这是rpcgen生成的示例代码。 0
------------------------
rpc_telnet_server.c
------------------------------------------------
01 /*
02*这是rpcgen生成的示例代码。
03*这些只是模板,您可以使用它们
04*作为开发自己功能的指南。
05 */
06
07#包括“rpc#u telnet.h”
08
09布卢特
10 rpc_test_1_svc(rpc_telnet_data*argp、rpc_result*result、struct svc_req*rqstp)
11 {
12 bool_t retval=1;
13法院(程序){
037案例NULLPROC:
038(无效)svc_sendreply(运输、,
039(xdrproc_t)xdr_void,(char*)NULL);
040返回;
041
042案例RPC_测试:
043 xdr_参数=(xdrproc_t)xdr_rpc_telnet_数据;
044 xdr_result=(xdrproc_t)xdr_rpc_result;
045 local=(bool_t(*)(char*,void*,struct svc_req*)rpc_test_1_svc;
046断裂;
047
048默认值:
049 Sverr_noproc(运输);
050返回;
051 }
052(void)memset((char*)和参数,0,sizeof(参数));
053如果(!svc_getargs(transp,xdr_参数,(char*)(caddr_t)和参数)){
054 svcerr_解码(transp);
055返回;
056 }
057 retval=(bool_t)(*局部)((char*)和参数,(void*)和结果,rqstp);
058
059
060
061如果(retval>0&!svc_sendreply(传输、xdr_结果、(字符*)&结果)){
062
063 svcerr_systemerr(运输);
064 }
065
066 if(!svc_freeargs(transp,xdr_参数,(char*)(caddr_t)和参数)){
067 fprintf(stderr,“无法释放参数”);
068出口(1);
069 }
070
075
076如果(!rpc_telnet_prog_1_freesult(传输、xdr_结果、(字符*)(caddr_t)和结果))
077 fprintf(标准“无法释放结果”);
078
079 cout在我问这个问题之前,我已经测试了代码,谷歌,每周。
最后我得到了正确的解决方案。
当服务器端返回类型为string并使用
rpc_telnet_server.c
------------------------------------------------
01 /*
02 * This is sample code generated by rpcgen.
03 * These are only templates and you can use them
04 * as a guideline for developing your own functions.
05 */
06
07 #include "rpc_telnet.h"
08
09 bool_t
10 rpc_test_1_svc(rpc_telnet_data *argp, rpc_result *result, struct svc_req *rqstp)
11 {
12 bool_t retval=1;
13 cout << (*argp).user_id << endl;
14 result->msg = "kk";
15 /*
16 * insert server code here
17 */
18
19 return (retval);
20 }
21
22 int
23 rpc_telnet_prog_1_freeresult(SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result)
24 {
25
26 (void) xdr_free(xdr_result, result);
27
28 /*
29 * Insert additional freeing code here, if needed
30 */
31
32 }
rpc_telnet_svc.c
------------------------------------------------
001 /*
002 * Please do not edit this file.
003 * It was generated using rpcgen.
004 */
005
006 #include "rpc_telnet.h"
007 #include <stdio.h>
008 #include <stdlib.h> /* getenv, exit */
009 #include <rpc/pmap_clnt.h> /* for pmap_unset */
010 #include <string.h> /* strcmp */
011 #include <rpc/rpc_com.h>
012 #include <fcntl.h> /* open */
013 #include <unistd.h> /* fork / setsid */
014 #include <sys/types.h>
015 #include <string.h>
016 #include <sys/resource.h> /* rlimit */
017 #include <syslog.h>
018
019 #ifdef DEBUG
020 #define RPC_SVC_FG
021 #endif
022
023 void
024 rpc_telnet_prog_1(struct svc_req *rqstp, SVCXPRT *transp)
025 {
026 union {
027 rpc_telnet_data rpc_test_1_arg;
028 } argument;
029 union {
030 rpc_result rpc_test_1_res;
031 } result;
032 bool_t retval;
033 xdrproc_t xdr_argument, xdr_result;
034 bool_t (*local)(char *, void *, struct svc_req *);
035
036 switch (rqstp->rq_proc) {
037 case NULLPROC:
038 (void) svc_sendreply(transp,
039 (xdrproc_t) xdr_void, (char *)NULL);
040 return;
041
042 case RPC_TEST:
043 xdr_argument = (xdrproc_t) xdr_rpc_telnet_data;
044 xdr_result = (xdrproc_t) xdr_rpc_result;
045 local = (bool_t (*) (char *, void *, struct svc_req *))rpc_test_1_svc;
046 break;
047
048 default:
049 svcerr_noproc(transp);
050 return;
051 }
052 (void) memset((char *)&argument, 0, sizeof (argument));
053 if (!svc_getargs(transp, xdr_argument, (char *)(caddr_t) &argument)) {
054 svcerr_decode(transp);
055 return;
056 }
057 retval = (bool_t) (*local)((char *)&argument, (void *)&result, rqstp);
058
059
060
061 if (retval > 0 && !svc_sendreply(transp, xdr_result, (char *)&result)) {
062
063 svcerr_systemerr(transp);
064 }
065
066 if (!svc_freeargs(transp, xdr_argument, (char *)(caddr_t) &argument)) {
067 fprintf(stderr, "unable to free arguments");
068 exit(1);
069 }
070
075
076 if (!rpc_telnet_prog_1_freeresult(transp, xdr_result,(char *) (caddr_t) &result))
077 fprintf(stderr, "unable to free results");
078
079 cout << "rpc_telnet_prog_1_freeresult end" << endl;
080
081 return;
082 }
083
084 int
085 main()
086 {
087 pid_t pid;
088 int i;
089 #ifndef RPC_SVC_FG
090 int size;
091 struct rlimit rl;
092 pid = fork();
093 if (pid < 0) {
094 perror("cannot fork");
095 exit(1);
096 }
097 if (pid)
098 exit(0);
099 rl.rlim_max = 0;
100 getrlimit(RLIMIT_NOFILE, &rl);
101 if ((size = rl.rlim_max) == 0)
102 exit(1);
103 for (i = 0; i < size; i++)
104 (void) close(i);
105 i = open("/dev/console", 2);
106 (void) dup2(i, 1);
107 (void) dup2(i, 2);
108 setsid();
109 openlog("rpc_telnet", LOG_PID, LOG_DAEMON);
110 #endif
111 if (!svc_create(rpc_telnet_prog_1, RPC_TELNET_PROG, RPC_TELNET_VERS, "netpath")) {
112 fprintf(stderr, "unable to create (RPC_TELNET_PROG, RPC_TELNET_VERS) for netpath.");
113 exit(1);
114 }
115
116 svc_run();
117 fprintf(stderr, "svc_run returned");
118 exit(1);
119 /* NOTREACHED */
120 }
gdb ./rpc_telnet_server
---------------------
bt
01 [New LWP 100114]
02 [New Thread 28404300 (LWP 100114/rpc_telnet_server)]
03 55
04
05 Program received signal SIGSEGV, Segmentation fault.
06 [Switching to Thread 28404300 (LWP 100114/rpc_telnet_server)]
07 0x2822b584 in free () from /lib/libc.so.7
08 (gdb) bt
09 #0 0x2822b584 in free () from /lib/libc.so.7
10 #1 0x2824ad2a in xdr_string () from /lib/libc.so.7
11 #2 0x08048ec0 in xdr_rpc_result (xdrs=0x284821c8, objp=0xbfbfd514)
12 at rpc_telnet_xdr.c:21
13 #3 0x28238be3 in svc_create () from /lib/libc.so.7
14 #4 0x08048c4e in rpc_telnet_prog_1 (rqstp=0xbfbfd598, transp=0x28238be3)
15 at rpc_telnet_svc.c:71
16 #5 0x2823cfd8 in svc_getreq_common () from /lib/libc.so.7
17 #6 0x2823d541 in svc_getreqset () from /lib/libc.so.7
18 #7 0x281dbb64 in svc_run () from /lib/libc.so.7
19 #8 0x08048b3f in main () at rpc_telnet_svc.c:116
01 g++ -g -DRPC_SVC_FG -Wall -Wextra -pedantic -O2 -pipe -D_REENTRANT -D_THEAD_SAF -c rpc_telnet_clnt.c
02 g++ -g -DRPC_SVC_FG -Wall -Wextra -pedantic -O2 -pipe -D_REENTRANT -D_THEAD_SAF -c rpc_telnet_client.c
03 rpc_telnet_client.c: In function 'void rpc_telnet_prog_1(char*)':
04 rpc_telnet_client.c:18: warning: deprecated conversion from string constant to 'har*'
05 rpc_telnet_client.c:19: warning: deprecated conversion from string constant to 'har*'
06 g++ -g -DRPC_SVC_FG -Wall -Wextra -pedantic -O2 -pipe -D_REENTRANT -D_THEAD_SAF -c rpc_telnet_xdr.c
07 g++ -g -DRPC_SVC_FG -Wall -Wextra -pedantic -o rpc_telnet_client rpc_telnet_cln.o rpc_telnet_client.o rpc_telnet_xdr.o -pthread
08 g++ -g -DRPC_SVC_FG -Wall -Wextra -pedantic -O2 -pipe -D_REENTRANT -D_THEAD_SAF -c rpc_telnet_svc.c
09 rpc_telnet_svc.c: In function 'int main()':
10 rpc_telnet_svc.c:87: warning: unused variable 'pid'
11 rpc_telnet_svc.c:88: warning: unused variable 'i'
12 g++ -g -DRPC_SVC_FG -Wall -Wextra -pedantic -O2 -pipe -D_REENTRANT -D_THEAD_SAF -c rpc_telnet_server.c
13 rpc_telnet_server.c: In function 'bool_t rpc_test_1_svc(rpc_telnet_data*, rpc_reult*, svc_req*)':
14 rpc_telnet_server.c:14: warning: deprecated conversion from string constant to 'har*'
15 rpc_telnet_server.c: At global scope:
16 rpc_telnet_server.c:10: warning: unused parameter 'rqstp'
17 rpc_telnet_server.c:23: warning: unused parameter 'transp'
18 rpc_telnet_server.c: In function 'int rpc_telnet_prog_1_freeresult(SVCXPRT*, boo_t (*)(XDR*, ...), char*)':
19 rpc_telnet_server.c:32: warning: control reaches end of non-void function
20 g++ -g -DRPC_SVC_FG -Wall -Wextra -pedantic -o rpc_telnet_server rpc_telnet_svco rpc_telnet_server.o rpc_telnet_xdr.o -pthread
1.设置服务器端返回字符串ex:
在rpc_telnet_server.c->rpc_test_1_svc函数中
rpcgen -aM rpc_telnet.x //-M for multithread purpose
2.设置客户端返回字符串ex:
在rpc_telnet_client.c->rpc_telnet_prog_1函数中
result->msg = (char *)malloc(sizeof(char)*8);
strcpy(result->msg,"888");
template generate xdr_free()将为您释放malloc。在我提问之前,我已经测试了代码,谷歌,每周。
最后我得到了正确的解决方案。
当服务器端返回类型为string并使用
rpc_telnet_server.c
------------------------------------------------
01 /*
02 * This is sample code generated by rpcgen.
03 * These are only templates and you can use them
04 * as a guideline for developing your own functions.
05 */
06
07 #include "rpc_telnet.h"
08
09 bool_t
10 rpc_test_1_svc(rpc_telnet_data *argp, rpc_result *result, struct svc_req *rqstp)
11 {
12 bool_t retval=1;
13 cout << (*argp).user_id << endl;
14 result->msg = "kk";
15 /*
16 * insert server code here
17 */
18
19 return (retval);
20 }
21
22 int
23 rpc_telnet_prog_1_freeresult(SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result)
24 {
25
26 (void) xdr_free(xdr_result, result);
27
28 /*
29 * Insert additional freeing code here, if needed
30 */
31
32 }
rpc_telnet_svc.c
------------------------------------------------
001 /*
002 * Please do not edit this file.
003 * It was generated using rpcgen.
004 */
005
006 #include "rpc_telnet.h"
007 #include <stdio.h>
008 #include <stdlib.h> /* getenv, exit */
009 #include <rpc/pmap_clnt.h> /* for pmap_unset */
010 #include <string.h> /* strcmp */
011 #include <rpc/rpc_com.h>
012 #include <fcntl.h> /* open */
013 #include <unistd.h> /* fork / setsid */
014 #include <sys/types.h>
015 #include <string.h>
016 #include <sys/resource.h> /* rlimit */
017 #include <syslog.h>
018
019 #ifdef DEBUG
020 #define RPC_SVC_FG
021 #endif
022
023 void
024 rpc_telnet_prog_1(struct svc_req *rqstp, SVCXPRT *transp)
025 {
026 union {
027 rpc_telnet_data rpc_test_1_arg;
028 } argument;
029 union {
030 rpc_result rpc_test_1_res;
031 } result;
032 bool_t retval;
033 xdrproc_t xdr_argument, xdr_result;
034 bool_t (*local)(char *, void *, struct svc_req *);
035
036 switch (rqstp->rq_proc) {
037 case NULLPROC:
038 (void) svc_sendreply(transp,
039 (xdrproc_t) xdr_void, (char *)NULL);
040 return;
041
042 case RPC_TEST:
043 xdr_argument = (xdrproc_t) xdr_rpc_telnet_data;
044 xdr_result = (xdrproc_t) xdr_rpc_result;
045 local = (bool_t (*) (char *, void *, struct svc_req *))rpc_test_1_svc;
046 break;
047
048 default:
049 svcerr_noproc(transp);
050 return;
051 }
052 (void) memset((char *)&argument, 0, sizeof (argument));
053 if (!svc_getargs(transp, xdr_argument, (char *)(caddr_t) &argument)) {
054 svcerr_decode(transp);
055 return;
056 }
057 retval = (bool_t) (*local)((char *)&argument, (void *)&result, rqstp);
058
059
060
061 if (retval > 0 && !svc_sendreply(transp, xdr_result, (char *)&result)) {
062
063 svcerr_systemerr(transp);
064 }
065
066 if (!svc_freeargs(transp, xdr_argument, (char *)(caddr_t) &argument)) {
067 fprintf(stderr, "unable to free arguments");
068 exit(1);
069 }
070
075
076 if (!rpc_telnet_prog_1_freeresult(transp, xdr_result,(char *) (caddr_t) &result))
077 fprintf(stderr, "unable to free results");
078
079 cout << "rpc_telnet_prog_1_freeresult end" << endl;
080
081 return;
082 }
083
084 int
085 main()
086 {
087 pid_t pid;
088 int i;
089 #ifndef RPC_SVC_FG
090 int size;
091 struct rlimit rl;
092 pid = fork();
093 if (pid < 0) {
094 perror("cannot fork");
095 exit(1);
096 }
097 if (pid)
098 exit(0);
099 rl.rlim_max = 0;
100 getrlimit(RLIMIT_NOFILE, &rl);
101 if ((size = rl.rlim_max) == 0)
102 exit(1);
103 for (i = 0; i < size; i++)
104 (void) close(i);
105 i = open("/dev/console", 2);
106 (void) dup2(i, 1);
107 (void) dup2(i, 2);
108 setsid();
109 openlog("rpc_telnet", LOG_PID, LOG_DAEMON);
110 #endif
111 if (!svc_create(rpc_telnet_prog_1, RPC_TELNET_PROG, RPC_TELNET_VERS, "netpath")) {
112 fprintf(stderr, "unable to create (RPC_TELNET_PROG, RPC_TELNET_VERS) for netpath.");
113 exit(1);
114 }
115
116 svc_run();
117 fprintf(stderr, "svc_run returned");
118 exit(1);
119 /* NOTREACHED */
120 }
gdb ./rpc_telnet_server
---------------------
bt
01 [New LWP 100114]
02 [New Thread 28404300 (LWP 100114/rpc_telnet_server)]
03 55
04
05 Program received signal SIGSEGV, Segmentation fault.
06 [Switching to Thread 28404300 (LWP 100114/rpc_telnet_server)]
07 0x2822b584 in free () from /lib/libc.so.7
08 (gdb) bt
09 #0 0x2822b584 in free () from /lib/libc.so.7
10 #1 0x2824ad2a in xdr_string () from /lib/libc.so.7
11 #2 0x08048ec0 in xdr_rpc_result (xdrs=0x284821c8, objp=0xbfbfd514)
12 at rpc_telnet_xdr.c:21
13 #3 0x28238be3 in svc_create () from /lib/libc.so.7
14 #4 0x08048c4e in rpc_telnet_prog_1 (rqstp=0xbfbfd598, transp=0x28238be3)
15 at rpc_telnet_svc.c:71
16 #5 0x2823cfd8 in svc_getreq_common () from /lib/libc.so.7
17 #6 0x2823d541 in svc_getreqset () from /lib/libc.so.7
18 #7 0x281dbb64 in svc_run () from /lib/libc.so.7
19 #8 0x08048b3f in main () at rpc_telnet_svc.c:116
01 g++ -g -DRPC_SVC_FG -Wall -Wextra -pedantic -O2 -pipe -D_REENTRANT -D_THEAD_SAF -c rpc_telnet_clnt.c
02 g++ -g -DRPC_SVC_FG -Wall -Wextra -pedantic -O2 -pipe -D_REENTRANT -D_THEAD_SAF -c rpc_telnet_client.c
03 rpc_telnet_client.c: In function 'void rpc_telnet_prog_1(char*)':
04 rpc_telnet_client.c:18: warning: deprecated conversion from string constant to 'har*'
05 rpc_telnet_client.c:19: warning: deprecated conversion from string constant to 'har*'
06 g++ -g -DRPC_SVC_FG -Wall -Wextra -pedantic -O2 -pipe -D_REENTRANT -D_THEAD_SAF -c rpc_telnet_xdr.c
07 g++ -g -DRPC_SVC_FG -Wall -Wextra -pedantic -o rpc_telnet_client rpc_telnet_cln.o rpc_telnet_client.o rpc_telnet_xdr.o -pthread
08 g++ -g -DRPC_SVC_FG -Wall -Wextra -pedantic -O2 -pipe -D_REENTRANT -D_THEAD_SAF -c rpc_telnet_svc.c
09 rpc_telnet_svc.c: In function 'int main()':
10 rpc_telnet_svc.c:87: warning: unused variable 'pid'
11 rpc_telnet_svc.c:88: warning: unused variable 'i'
12 g++ -g -DRPC_SVC_FG -Wall -Wextra -pedantic -O2 -pipe -D_REENTRANT -D_THEAD_SAF -c rpc_telnet_server.c
13 rpc_telnet_server.c: In function 'bool_t rpc_test_1_svc(rpc_telnet_data*, rpc_reult*, svc_req*)':
14 rpc_telnet_server.c:14: warning: deprecated conversion from string constant to 'har*'
15 rpc_telnet_server.c: At global scope:
16 rpc_telnet_server.c:10: warning: unused parameter 'rqstp'
17 rpc_telnet_server.c:23: warning: unused parameter 'transp'
18 rpc_telnet_server.c: In function 'int rpc_telnet_prog_1_freeresult(SVCXPRT*, boo_t (*)(XDR*, ...), char*)':
19 rpc_telnet_server.c:32: warning: control reaches end of non-void function
20 g++ -g -DRPC_SVC_FG -Wall -Wextra -pedantic -o rpc_telnet_server rpc_telnet_svco rpc_telnet_server.o rpc_telnet_xdr.o -pthread
1.设置服务器端返回字符串ex:
在rpc_telnet_server.c->rpc_test_1_svc函数中
rpcgen -aM rpc_telnet.x //-M for multithread purpose
2.设置客户端返回字符串ex:
在rpc_telnet_client.c->rpc_telnet_prog_1函数中
result->msg = (char *)malloc(sizeof(char)*8);
strcpy(result->msg,"888");
template generate xdr_free()将为您释放malloc。我发现您无法在使用某些局部变量之前初始化它们。例如rpc_test_1_svc
函数中的retval
。未初始化的局部变量有一个不确定的值并使用它们(例如,通过返回它)导致未定义的行为。未定义的行为,不管它在哪里,都会使整个程序实际上无效。请尝试在启用更多警告的情况下构建(例如,使用GCC或Clang构建时,请使用-Wall-Wextra-pedantic
),并修复您收到的警告的根本原因,因为警告通常表示您做了可疑或奇怪的事情。此外,rpc\u telnet\u prog\u 1\u freesult
声明为返回int
,但根本不返回任何内容,这是另一种未定义行为的情况。如果这是您的实际代码,则需要修复这些问题问题,如果这不是您的实际代码,您需要明确地告诉我们这一点,以及代码中应该忽略哪些问题。更好的是,不要显示不完整的代码,而是创建一个并向我们显示。关于调试器回溯,您能指出rpc\u telnet\u svc.c
中的哪一行71吗?否则我们很难找到它d只是一个想法,您确定可以使用任何指针来表示字符串吗?也许您应该尝试动态分配内存并将字符串复制到该内存中,然后使用指向已分配内存的指针来代替?谢谢您的建议,我重新编码并初始化retval=1
,在rpc_telnet_svc中使用-Wall-Wextra-pedantic.行71进行编译。c是svc_freeargs。(第061行svc_sendreply)seem将向客户端发送回复结果,此时我的客户端也将出现段错误。我发现您在使用某些局部变量之前未能初始化它们。例如,rpc\u test\u 1\u svc
函数中的retval
。未初始化的局部变量有一个不确定的值并使用它们(例如,通过返回它)导致未定义的行为。未定义的行为,不管它在哪里,都会使整个程序实际上无效。请尝试在启用更多警告的情况下构建(例如,使用GCC或Clang构建时,请使用-Wall-Wextra-pedantic
),并修复您收到的警告的根本原因,因为警告通常表示您做了可疑或奇怪的事情。此外,rpc\u telnet\u prog\u 1\u freesult
声明为返回int
,但根本不返回任何内容,这是另一种未定义行为的情况。如果这是您的实际代码,则需要修复这些问题问题,如果这不是您的实际代码,您需要明确地告诉我们这一点,以及代码中应该忽略哪些问题。更好的是,不要显示不完整的代码,而是创建一个并向我们显示。关于调试器回溯,您能指出rpc\u telnet\u svc.c
中的哪一行71吗?否则我们很难找到它我只是想,你确定你可以用任何指针来表示字符串吗?也许你应该尝试动态分配内存并将字符串复制到该内存中,然后用指针来表示分配的内存?谢谢你的建议,我重新编码并初始化了