簡體   English   中英

從多線程RPC服務器返回帶有字符串的結構

[英]Return a struct with string from a multi threaded RPC server

我正在嘗試編寫一個返回結構的多線程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;

這是我的服務器,您可以看到它使用了指向我的結構的指針,為名稱字符串分配了一些內存,然后在該字符串上進行復制。 我還添加了調試輸出

// 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' 但是,客戶端崩潰與段。 使用地址清理器,我得到這個:

=================================================================
==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調用用字符串修改結構? 如果我將示例更改為使用整數而不是字符串,則可以正常工作。 因此,似乎我缺少基本的東西。 關於我在做什么錯的任何想法或調試步驟?

在您的客戶端中,嘗試為foo_out結構分配內存:

foo_out *out = malloc(sizeof(foo_out));
if (foo_2(out, cl) != RPC_SUCCESS) {
  printf("failed \n");
  // exit(1);
}
printf("foo out: %s\n",   out->name);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM