C #define вызывает ошибку сегмента? - PullRequest
0 голосов
/ 01 июля 2011

Вот функция, которую я пытаюсь получить, работая с Red Hat 6 ..

И у меня очень мало опыта работы с C, особенно с использованием #define, поэтому я не уверен, что это за частьдаже пытаясь сделать: SP-> s_port = htons (SP-> s_port);

#ifdef __linux
#define GET_SERVICE_BY_NAME(SP, SERVICE, PROTOCOL)                           \
   char            GSBN_servbuf[HOSTBUFFERLENGTH] = {0};                     \
   struct servent  GSBN_sp;                                                  \
   struct servent *GSBN_serv_result;                                         \
   int             GSBN_s = 0;                                               \
   GSBN_s = getservbyname_r(SERVICE,                                         \
                       PROTOCOL,                                             \
                       &GSBN_sp,                                             \
                       GSBN_servbuf,                                         \
                       sizeof(GSBN_servbuf),                                 \
                       &GSBN_serv_result);                                   \
   SP = GSBN_serv_result;                                                    \
   SP->s_port = htons(SP->s_port);                                           \
   if (SP && SOCKET_DEBUG) {                                                 \
      printf("%s GET_SERVICE_BY_NAME - Service: %s Port: %d Protocol: %s\n", \
             get_timestamp(), SP->s_name, SP->s_port, SP->s_proto);          \
       }                                                                         \
   if (SP == NULL) {                                                         \
      fprintf(stderr, "%s GET_SERVICE_BY_NAME - Service %s not found.\n",    \
              get_timestamp(), SERVICE);                                     \
   }
#else
#define GET_SERVICE_BY_NAME(SP, SERVICE, PROTOCOL)                           \
   char            GSBN_servbuf[HOSTBUFFERLENGTH] = {0};                     \
   struct servent  GSBN_serv_result;                                         \
   SP = getservbyname_r(SERVICE,                                             \
                       PROTOCOL,                                             \
                       &GSBN_serv_result,                                    \
                       GSBN_servbuf,                                         \
                       sizeof(GSBN_servbuf));                                \
   if (SP && SOCKET_DEBUG) {                                                 \
      printf("%s GET_SERVICE_BY_NAME - Service: %s Port: %d Protocol: %s\n", \
             get_timestamp(), SP->s_name, SP->s_port, SP->s_proto);          \
   }                                                                         \
   if (SP == NULL) {                                                         \
      fprintf(stderr, "%s GET_SERVICE_BY_NAME - Service %s not found.\n",    \
              get_timestamp(), SERVICE);                                     \
   }
#endif

Это ошибка, которую я получаю:

Согласно GDBЯ получаю ошибку seg при вызове этой функции:

GET_SERVICE_BY_NAME (sp, serv, prot);

Вот вывод gdb:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x456c6c90 (LWP 14645)]
0x420b1e69 in gi_get_port (serv=Unhandled dwarf expression opcode 0x9c
)
    at /home/user1/Common/src/socket.c:282
282           GET_SERVICE_BY_NAME(sp, serv, prot);
Current language:  auto; currently c

Вот как эта функция вызывается:

int gi_get_port (char *serv, char *prot)
/* obtain the port for the named service */
{
  int p, s;

  /* Data for resolving service name to a socket description. */
  struct servent *sp = NULL;

  GET_SERVICE_BY_NAME(sp, serv, prot);

  if (sp != NULL) {
    p = sp->s_port;
  } else {
    p = -1;
  };

  return p;
}

Ответы [ 2 ]

2 голосов
/ 01 июля 2011

Вот как будет выглядеть ваш код после запуска препроцессора:

int gi_get_port (char *serv, char *prot)
/* obtain the port for the named service */
{
  int p, s;

  /* Data for resolving service name to a socket description. */
  struct servent *sp = NULL;

  char            GSBN_servbuf[HOSTBUFFERLENGTH] = {0};                     
   struct servent  GSBN_sp;                                                  
   struct servent *GSBN_serv_result;                                         
   int             GSBN_s = 0;                                               
   GSBN_s = getservbyname_r(serv,                                         
                       prot,                                             
                       &GSBN_sp,                                             
                       GSBN_servbuf,                                         
                       sizeof(GSBN_servbuf),                                 
                       &GSBN_serv_result);                                   
   sp = GSBN_serv_result;                                                    
   sp->s_port = htons(SP->s_port);                                           
   if (sp && SOCKET_DEBUG) {                                                 
      printf("%s GET_SERVICE_BY_NAME - Service: %s Port: %d Protocol: %s\n", 
             get_timestamp(), sp->s_name, sp->s_port, sp->s_proto);          
       }                                                                         
   if (sp == NULL) {                                                         
      fprintf(stderr, "%s GET_SERVICE_BY_NAME - Service %s not found.\n",    
              get_timestamp(), serv);                                     
   }

  if (sp != NULL) {
    p = sp->s_port;
  } else {
    p = -1;
  };

  return p;
}

Как видите, вы должны проверить, что sp является NULL, прежде чем выполнять htons () впорт.

0 голосов
/ 01 июля 2011

Как долго ваш HOSTBUFFERLENGTH?

Скомпилировав и запустив код, я могу сгенерировать аналогичный сбой, если HOSTBUFFERLENGTH установлен в единицу, но похоже, что он работает, если он установлен в 2000 ....

И если имя службы недопустимо (например, «akhaha» вместо «http»), GSBN_serv_result равен NULL, а SP равен NULL, а SP-> s_port также вызовет сбой .....

...