/[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.9 by roland, Wed Jan 2 11:22:17 2002 UTC revision 1.10 by roland, Tue Jan 29 10:22:28 2002 UTC
# Line 35  Line 35 
35    
36  const char *argp_program_version = STANDARD_HURD_VERSION (rpctrace);  const char *argp_program_version = STANDARD_HURD_VERSION (rpctrace);
37    
38  static const struct argp_option options[] = {  static const struct argp_option options[] =
39    {
40    {"output", 'o', "FILE", 0, "Send trace output to FILE instead of stderr."},    {"output", 'o', "FILE", 0, "Send trace output to FILE instead of stderr."},
41      {"rpc-list", 'I', "FILE", 0,
42       "Read FILE for assocations of message ID numbers to names."},
43    {0}    {0}
44  };  };
45    
# Line 45  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).  */
52    
53    static void
54    msgid_ihash_cleanup (void *element, void *arg)
55    {
56      free (element);
57    }
58    
59    static struct ihash msgid_ihash = { cleanup: msgid_ihash_cleanup };
60    
61    /* Parse a file of RPC names and message IDs as output by mig's -list
62       option: "subsystem base-id routine n request-id reply-id".  Put each
63       request-id value into `msgid_ihash' with the routine name as its value.  */
64    static void
65    parse_msgid_list (const char *filename)
66    {
67      FILE *fp;
68      char *buffer = NULL;
69      size_t bufsize = 0;
70      unsigned int lineno = 0;
71      char *name;
72      unsigned int msgid;
73    
74      fp = fopen (filename, "r");
75      if (fp == 0)
76        {
77          error (2, errno, "%s", filename);
78          return;
79        }
80    
81      while (getline (&buffer, &bufsize, fp) > 0)
82        {
83          ++lineno;
84          if (buffer[0] == '#' || buffer[0] == '\0')
85            continue;
86          if (sscanf (buffer, "%*s %*u %as %*u %u %*u\n", &name, &msgid) != 2)
87            error (0, 0, "%s:%u: invalid format in RPC list file",
88                   filename, lineno);
89          else
90            {
91              error_t err = ihash_add (&msgid_ihash, msgid, name, NULL);
92              if (err)
93                error (1, err, "ihash_add");
94            }
95        }
96    
97      free (buffer);
98      fclose (fp);
99    }
100    
101    /* Look for a name describing MSGID.  We check the table directly, and
102       also check if this looks like the ID of a reply message whose request
103       ID is already in the table.  */
104    static const char *
105    msgid_name (mach_msg_id_t msgid)
106    {
107      const char *msgname = ihash_find (&msgid_ihash, msgid);
108      if (msgname == 0 && (msgid / 100) % 2 == 1)
109        {
110          /* This message ID is not in the table, and its number makes it
111             what should be an RPC reply message ID.  So look up the message
112             ID of the corresponding RPC request and synthesize a name from
113             that.  Then stash that name in the table so the next time the
114             lookup will match directly.  */
115          msgname = ihash_find (&msgid_ihash, msgid - 100);
116          if (msgname != 0)
117            {
118              char *reply_name = 0;
119              asprintf (&reply_name, "%s-reply", reply_name);
120              if (reply_name != 0)
121                {
122                  ihash_add (&msgid_ihash, msgid, reply_name, NULL);
123                  msgname = reply_name;
124                }
125              else
126                msgname = 0;
127            }
128        }
129        return msgname;
130    }
131    
132  /* 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.  */
133  struct traced_info  struct traced_info
134  {  {
# Line 568  trace_and_forward (mach_msg_header_t *in Line 652  trace_and_forward (mach_msg_header_t *in
652          info = rewrite_right (&inp->msgh_local_port, &reply_type);          info = rewrite_right (&inp->msgh_local_port, &reply_type);
653          assert (info);          assert (info);
654          if (info->name == 0)          if (info->name == 0)
655            asprintf (&info->name, "reply(%u:%u)",            {
656                      (unsigned int) info->pi.port_right,              const char *msgname = msgid_name (inp->msgh_id);
657                      (unsigned int) inp->msgh_id);              if (msgname == 0)
658                  asprintf (&info->name, "reply(%u:%u)",
659                            (unsigned int) info->pi.port_right,
660                            (unsigned int) inp->msgh_id);
661                else
662                  asprintf (&info->name, "reply(%u:%s)",
663                            (unsigned int) info->pi.port_right, msgname);
664              }
665          if (info->type == MACH_MSG_TYPE_MOVE_SEND_ONCE)          if (info->type == MACH_MSG_TYPE_MOVE_SEND_ONCE)
666            {            {
667              info->u.send_once.sent_to = info->pi.port_right;              info->u.send_once.sent_to = info->pi.port_right;
# Line 689  static mach_port_t expected_reply_port; Line 780  static mach_port_t expected_reply_port;
780  static void  static void
781  print_request_header (struct traced_info *receiver, mach_msg_header_t *msg)  print_request_header (struct traced_info *receiver, mach_msg_header_t *msg)
782  {  {
783      const char *msgname = msgid_name (msg->msgh_id);
784    
785    expected_reply_port = msg->msgh_local_port;    expected_reply_port = msg->msgh_local_port;
786    
787    if (receiver->name != 0)    if (receiver->name != 0)
788      fprintf (ostream, "%4s->%5u (", receiver->name, msg->msgh_id);      fprintf (ostream, "%4s->", receiver->name);
789      else
790        fprintf (ostream, "%4u->", (unsigned int) receiver->pi.port_right);
791    
792      if (msgname != 0)
793        fprintf (ostream, "%5s (", msgname);
794    else    else
795      fprintf (ostream, "%4u->%5u (",      fprintf (ostream, "%5u (", (unsigned int) msg->msgh_id);
              (unsigned int) receiver->pi.port_right, msg->msgh_id);  
796  }  }
797    
798  static void  static void
# Line 741  print_reply_header (struct traced_info * Line 838  print_reply_header (struct traced_info *
838          /* This is a normal reply to a previous request.  */          /* This is a normal reply to a previous request.  */
839          fprintf (ostream, " > ");          fprintf (ostream, " > ");
840        else        else
841          /* Weirdo.  */          {
842          fprintf (ostream, " >(%u) ", reply->Head.msgh_id);            /* Weirdo.  */
843              const char *msgname = msgid_name (reply->Head.msgh_id);
844              if (msgname == 0)
845                fprintf (ostream, " >(%u) ", reply->Head.msgh_id);
846              else
847                fprintf (ostream, " >(%s) ", msgname);
848            }
849      }      }
850    
851    if (reply->RetCode == 0)    if (reply->RetCode == 0)
# Line 917  main (int argc, char **argv, char **envp Line 1020  main (int argc, char **argv, char **envp
1020            outfile = arg;            outfile = arg;
1021            break;            break;
1022    
1023            case 'I':
1024              parse_msgid_list (arg);
1025              break;
1026    
1027          case ARGP_KEY_NO_ARGS:          case ARGP_KEY_NO_ARGS:
1028            argp_usage (state);            argp_usage (state);
1029            return EINVAL;            return EINVAL;

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

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