/[hurd]/hurd/utils/rpctrace.c
ViewVC logotype

Diff of /hurd/utils/rpctrace.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.10 by roland, Tue Jan 29 10:22:28 2002 UTC revision 1.11 by roland, Wed Jan 30 12:25:44 2002 UTC
# Line 48  static const char *doc = Line 48  static const char *doc =
48  "Trace Mach Remote Procedure Calls."  "Trace Mach Remote Procedure Calls."
49  "\v.";  "\v.";
50    
51  /* The msgid_ihash table maps msgh_id values to names (malloc'd strings).  */  /* The msgid_ihash table maps msgh_id values to names.  */
52    
53    struct msgid_info
54    {
55      char *name;
56      char *subsystem;
57    };
58    
59  static void  static void
60  msgid_ihash_cleanup (void *element, void *arg)  msgid_ihash_cleanup (void *element, void *arg)
61  {  {
62    free (element);    struct msgid_info *info = element;
63      free (info->name);
64      free (info->subsystem);
65      free (info);
66  }  }
67    
68  static struct ihash msgid_ihash = { cleanup: msgid_ihash_cleanup };  static struct ihash msgid_ihash = { cleanup: msgid_ihash_cleanup };
# Line 68  parse_msgid_list (const char *filename) Line 77  parse_msgid_list (const char *filename)
77    char *buffer = NULL;    char *buffer = NULL;
78    size_t bufsize = 0;    size_t bufsize = 0;
79    unsigned int lineno = 0;    unsigned int lineno = 0;
80    char *name;    char *name, *subsystem;
81    unsigned int msgid;    unsigned int msgid;
82    
83    fp = fopen (filename, "r");    fp = fopen (filename, "r");
# Line 83  parse_msgid_list (const char *filename) Line 92  parse_msgid_list (const char *filename)
92        ++lineno;        ++lineno;
93        if (buffer[0] == '#' || buffer[0] == '\0')        if (buffer[0] == '#' || buffer[0] == '\0')
94          continue;          continue;
95        if (sscanf (buffer, "%*s %*u %as %*u %u %*u\n", &name, &msgid) != 2)        if (sscanf (buffer, "%as %*u %as %*u %u %*u\n",
96                      &subsystem, &name, &msgid) != 2)
97          error (0, 0, "%s:%u: invalid format in RPC list file",          error (0, 0, "%s:%u: invalid format in RPC list file",
98                 filename, lineno);                 filename, lineno);
99        else        else
100          {          {
101            error_t err = ihash_add (&msgid_ihash, msgid, name, NULL);            struct msgid_info *info = malloc (sizeof *info);
102            if (err)            if (info == 0)
103              error (1, err, "ihash_add");              error (1, errno, "malloc");
104              info->name = name;
105              info->subsystem = subsystem;
106              errno = ihash_add (&msgid_ihash, msgid, info, NULL);
107              if (errno)
108                error (1, errno, "ihash_add");
109          }          }
110      }      }
111    
# Line 101  parse_msgid_list (const char *filename) Line 116  parse_msgid_list (const char *filename)
116  /* Look for a name describing MSGID.  We check the table directly, and  /* Look for a name describing MSGID.  We check the table directly, and
117     also check if this looks like the ID of a reply message whose request     also check if this looks like the ID of a reply message whose request
118     ID is already in the table.  */     ID is already in the table.  */
119  static const char *  static const struct msgid_info *
120  msgid_name (mach_msg_id_t msgid)  msgid_info (mach_msg_id_t msgid)
121  {  {
122    const char *msgname = ihash_find (&msgid_ihash, msgid);    const struct msgid_info *info = ihash_find (&msgid_ihash, msgid);
123    if (msgname == 0 && (msgid / 100) % 2 == 1)    if (info == 0 && (msgid / 100) % 2 == 1)
124      {      {
125        /* This message ID is not in the table, and its number makes it        /* This message ID is not in the table, and its number makes it
126           what should be an RPC reply message ID.  So look up the message           what should be an RPC reply message ID.  So look up the message
127           ID of the corresponding RPC request and synthesize a name from           ID of the corresponding RPC request and synthesize a name from
128           that.  Then stash that name in the table so the next time the           that.  Then stash that name in the table so the next time the
129           lookup will match directly.  */           lookup will match directly.  */
130        msgname = ihash_find (&msgid_ihash, msgid - 100);        info = ihash_find (&msgid_ihash, msgid - 100);
131        if (msgname != 0)        if (info != 0)
132          {          {
133            char *reply_name = 0;            struct msgid_info *reply_info = malloc (sizeof *info);
134            asprintf (&reply_name, "%s-reply", reply_name);            if (reply_info != 0)
           if (reply_name != 0)  
135              {              {
136                ihash_add (&msgid_ihash, msgid, reply_name, NULL);                reply_info->subsystem = strdup (info->subsystem);
137                msgname = reply_name;                reply_info->name = 0;
138                  asprintf (&reply_info->name, "%s-reply", info->name);
139                  ihash_add (&msgid_ihash, msgid, reply_info, NULL);
140                  info = reply_info;
141              }              }
142            else            else
143              msgname = 0;              info = 0;
144          }          }
145      }      }
146      return msgname;    return info;
147    }
148    
149    static const char *
150    msgid_name (mach_msg_id_t msgid)
151    {
152      const struct msgid_info *info = msgid_info (msgid);
153      return info ? info->name : 0;
154    }
155    
156    /* Return true if this message's data should be printed out.
157       For a request message, that means the in parameters.
158       For a reply messages, that means the return code and out parameters.  */
159    static int
160    msgid_display (const struct msgid_info *info)
161    {
162      return 1;
163    }
164    
165    /* Return true if we should interpose on this RPC's reply port.  If this
166       returns false, we will pass the caller's original reply port through so
167       we never see the reply message at all.  */
168    static int
169    msgid_trace_replies (const struct msgid_info *info)
170    {
171      return 1;
172  }  }
173    
174  /* We keep one of these structures for each port right we are tracing.  */  /* We keep one of these structures for each port right we are tracing.  */
# Line 594  trace_and_forward (mach_msg_header_t *in Line 636  trace_and_forward (mach_msg_header_t *in
636    };    };
637    
638    error_t err;    error_t err;
639      const struct msgid_info *msgid;
640    struct traced_info *info;    struct traced_info *info;
641    mach_msg_bits_t complex;    mach_msg_bits_t complex;
642    
# Line 640  trace_and_forward (mach_msg_header_t *in Line 683  trace_and_forward (mach_msg_header_t *in
683    
684    complex = inp->msgh_bits & MACH_MSGH_BITS_COMPLEX;    complex = inp->msgh_bits & MACH_MSGH_BITS_COMPLEX;
685    
686      msgid = msgid_info (inp->msgh_id);
687    
688    /* Swap the header data like a crossover cable. */    /* Swap the header data like a crossover cable. */
689    {    {
690      mach_msg_type_name_t this_type = MACH_MSGH_BITS_LOCAL (inp->msgh_bits);      mach_msg_type_name_t this_type = MACH_MSGH_BITS_LOCAL (inp->msgh_bits);
691      mach_msg_type_name_t reply_type = MACH_MSGH_BITS_REMOTE (inp->msgh_bits);      mach_msg_type_name_t reply_type = MACH_MSGH_BITS_REMOTE (inp->msgh_bits);
692    
693      inp->msgh_local_port = inp->msgh_remote_port;      inp->msgh_local_port = inp->msgh_remote_port;
694      if (reply_type)      if (reply_type && msgid_trace_replies (msgid))
695        {        {
696          struct traced_info *info;          struct traced_info *info;
697          info = rewrite_right (&inp->msgh_local_port, &reply_type);          info = rewrite_right (&inp->msgh_local_port, &reply_type);
698          assert (info);          assert (info);
699          if (info->name == 0)          if (info->name == 0)
700            {            {
701              const char *msgname = msgid_name (inp->msgh_id);              if (msgid == 0)
             if (msgname == 0)  
702                asprintf (&info->name, "reply(%u:%u)",                asprintf (&info->name, "reply(%u:%u)",
703                          (unsigned int) info->pi.port_right,                          (unsigned int) info->pi.port_right,
704                          (unsigned int) inp->msgh_id);                          (unsigned int) inp->msgh_id);
705              else              else
706                asprintf (&info->name, "reply(%u:%s)",                asprintf (&info->name, "reply(%u:%s)",
707                          (unsigned int) info->pi.port_right, msgname);                          (unsigned int) info->pi.port_right, msgid->name);
708            }            }
709          if (info->type == MACH_MSG_TYPE_MOVE_SEND_ONCE)          if (info->type == MACH_MSG_TYPE_MOVE_SEND_ONCE)
710            {            {
# Line 691  trace_and_forward (mach_msg_header_t *in Line 735  trace_and_forward (mach_msg_header_t *in
735    /* The message now appears as it would if we were the sender.    /* The message now appears as it would if we were the sender.
736       It is ready to be resent.  */       It is ready to be resent.  */
737    
738    if (inp->msgh_local_port == MACH_PORT_NULL    if (msgid_display (msgid))
       && info->type == MACH_MSG_TYPE_MOVE_SEND_ONCE  
       && inp->msgh_size >= sizeof (mig_reply_header_t)  
       && (*(int *) &((mig_reply_header_t *) inp)->RetCodeType  
           == *(int *)&RetCodeType))  
     {  
       /* This sure looks like an RPC reply message.  */  
       mig_reply_header_t *rh = (void *) inp;  
       print_reply_header (info, rh);  
       putc (' ', ostream);  
       print_contents (&rh->Head, rh + 1);  
       putc ('\n', ostream);  
     }  
   else  
739      {      {
740        /* Print something about the message header.  */        if (inp->msgh_local_port == MACH_PORT_NULL
741        print_request_header (info, inp);            && info->type == MACH_MSG_TYPE_MOVE_SEND_ONCE
742        print_contents (inp, inp + 1);            && inp->msgh_size >= sizeof (mig_reply_header_t)
743        if (inp->msgh_local_port == MACH_PORT_NULL) /* simpleroutine */            && (*(int *) &((mig_reply_header_t *) inp)->RetCodeType
744          fprintf (ostream, ");\n");                == *(int *)&RetCodeType))
745            {
746              /* This sure looks like an RPC reply message.  */
747              mig_reply_header_t *rh = (void *) inp;
748              print_reply_header (info, rh);
749              putc (' ', ostream);
750              print_contents (&rh->Head, rh + 1);
751              putc ('\n', ostream);
752            }
753        else        else
754          /* Leave a partial line that will be finished later.  */          {
755          fprintf (ostream, ")");            /* Print something about the message header.  */
756              print_request_header (info, inp);
757              print_contents (inp, inp + 1);
758              if (inp->msgh_local_port == MACH_PORT_NULL) /* simpleroutine */
759                fprintf (ostream, ");\n");
760              else
761                /* Leave a partial line that will be finished later.  */
762                fprintf (ostream, ")");
763            }
764      }      }
765    
766    /* Resend the message to the tracee.  */    /* Resend the message to the tracee.  */

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.11

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26