rpc 服务器 return 结果 char 将出现段错误

rpc server return result char will get segment fault

my rpc_telnet.x is below,
01 
02 struct rpc_telnet_data { 
03     string user_id<50>;
04 }; 
05  
06 struct rpc_result { 
07     string msg<50>;
08    
09 }; 
10  
11 program RPC_TELNET_PROG { 
12     version RPC_TELNET_VERS { 
13         rpc_result RPC_TEST(rpc_telnet_data) = 1;
14  
15     } = 1; 
16 } = 0x23451112;


}; 

program RPC_TELNET_PROG { 
version RPC_TELNET_VERS { 
    rpc_result RPC_TEST(rpc_telnet_data) = 1;

} = 1; 
} = 0x23451112;

`

------------------------

当服务器端 return 是整数时(我设置了整数版本 rpc_telnet.x ),它工作得很好。 但是当服务器端 return 结果是 string(char*) 时,它会出现段错误。 那么,如何正确设置 return char(result->msg) 呢? 下面是我的服务器端代码。

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

在我提出问题之前,我每周都会测试代码,google。 最后我得到了正确的解决方案。 当服务器端 return 类型为字符串并使用

生成模板
rpcgen -aM rpc_telnet.x   //-M for multithread purpose

1.setup 服务器端 return 字符串 ex: 在 rpc_telnet_server.c -> rpc_test_1_svc 函数中

result->msg =  (char *)malloc(sizeof(char)*8);
strcpy(result->msg,"888");

2.setup 客户端 return 字符串 ex: 在 rpc_telnet_client.c -> rpc_telnet_prog_1 函数中

result_1.msg = (char *)malloc(sizeof(char)*8);
strcpy(result_1.msg,"");

模板生成 xdr_free() 将为您释放 malloc。