summaryrefslogtreecommitdiff
path: root/utils/rpctrace.c
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2015-05-31 00:26:40 +0200
committerJustus Winter <4winter@informatik.uni-hamburg.de>2015-06-30 17:10:00 +0200
commit74fb5209f06edcf0b52bdf44ba805cb5f6cd41c8 (patch)
tree3481be39655a9f72626722dab60ba6be08285116 /utils/rpctrace.c
parentf57ed76faed9e9e922ba93dd3bf8740974eb718a (diff)
utils: split-off the message id parsing
* utils/rpctrace.c: Move all the code handling the message id files... * utils/msgids.c: ... to a new file. * utils/msgids.h: And add the relevand declarations. * utils/Makefile (SRCS): Add the new file.
Diffstat (limited to 'utils/rpctrace.c')
-rw-r--r--utils/rpctrace.c202
1 files changed, 8 insertions, 194 deletions
diff --git a/utils/rpctrace.c b/utils/rpctrace.c
index 48daa078..d53b510f 100644
--- a/utils/rpctrace.c
+++ b/utils/rpctrace.c
@@ -26,9 +26,7 @@
#include <mach/message.h>
#include <assert.h>
#include <fcntl.h>
-#include <fnmatch.h>
#include <sys/stat.h>
-#include <dirent.h>
#include <unistd.h>
#include <argp.h>
#include <error.h>
@@ -41,24 +39,15 @@
#include <argz.h>
#include <envz.h>
-const char *argp_program_version = STANDARD_HURD_VERSION (rpctrace);
+#include "msgids.h"
-#define STD_MSGIDS_DIR DATADIR "/msgids/"
+const char *argp_program_version = STANDARD_HURD_VERSION (rpctrace);
static unsigned strsize = 80;
-#define OPT_NOSTDINC -1
static const struct argp_option options[] =
{
{"output", 'o', "FILE", 0, "Send trace output to FILE instead of stderr."},
- {"nostdinc", OPT_NOSTDINC, 0, 0,
- "Do not search inside the standard system directory, `" STD_MSGIDS_DIR
- "', for `.msgids' files."},
- {"rpc-list", 'i', "FILE", 0,
- "Read FILE for assocations of message ID numbers to names."},
- {0, 'I', "DIR", 0,
- "Add the directory DIR to the list of directories to be searched for files "
- "containing message ID numbers."},
{0, 's', "SIZE", 0, "Specify the maximum string size to print (the default is 80)."},
{0, 'E', "var[=value]", 0,
"Set/change (var=value) or remove (var) an environment variable among the "
@@ -71,23 +60,6 @@ static const struct argp_option options[] =
static const char args_doc[] = "COMMAND [ARG...]";
static const char doc[] = "Trace Mach Remote Procedure Calls.";
-/* The msgid_ihash table maps msgh_id values to names. */
-
-struct msgid_info
-{
- char *name;
- char *subsystem;
-};
-
-static void
-msgid_ihash_cleanup (void *element, void *arg)
-{
- struct msgid_info *info = element;
- free (info->name);
- free (info->subsystem);
- free (info);
-}
-
/* This structure stores the information of the traced task. */
struct task_info
{
@@ -95,9 +67,6 @@ struct task_info
boolean_t threads_wrapped; /* All threads of the task has been wrapped? */
};
-static struct hurd_ihash msgid_ihash
- = HURD_IHASH_INITIALIZER (HURD_IHASH_NO_LOCP);
-
static struct hurd_ihash task_ihash
= HURD_IHASH_INITIALIZER (HURD_IHASH_NO_LOCP);
@@ -126,86 +95,6 @@ remove_task (task_t task)
hurd_ihash_remove (&task_ihash, task);
}
-/* Parse a file of RPC names and message IDs as output by mig's -list
- option: "subsystem base-id routine n request-id reply-id". Put each
- request-id value into `msgid_ihash' with the routine name as its value. */
-static void
-parse_msgid_list (const char *filename)
-{
- FILE *fp;
- char *buffer = NULL;
- size_t bufsize = 0;
- unsigned int lineno = 0;
- char *name, *subsystem;
- unsigned int msgid;
- error_t err;
-
- fp = fopen (filename, "r");
- if (fp == 0)
- {
- error (2, errno, "%s", filename);
- return;
- }
-
- while (getline (&buffer, &bufsize, fp) > 0)
- {
- ++lineno;
- if (buffer[0] == '#' || buffer[0] == '\0')
- continue;
- if (sscanf (buffer, "%ms %*u %ms %*u %u %*u\n",
- &subsystem, &name, &msgid) != 3)
- error (0, 0, "%s:%u: invalid format in RPC list file",
- filename, lineno);
- else
- {
- struct msgid_info *info = malloc (sizeof *info);
- if (info == 0)
- error (1, errno, "malloc");
- info->name = name;
- info->subsystem = subsystem;
- err = hurd_ihash_add (&msgid_ihash, msgid, info);
- if (err)
- error (1, err, "hurd_ihash_add");
- }
- }
-
- free (buffer);
- fclose (fp);
-}
-
-/* Look for a name describing MSGID. We check the table directly, and
- also check if this looks like the ID of a reply message whose request
- ID is already in the table. */
-static const struct msgid_info *
-msgid_info (mach_msg_id_t msgid)
-{
- const struct msgid_info *info = hurd_ihash_find (&msgid_ihash, msgid);
- if (info == 0 && (msgid / 100) % 2 == 1)
- {
- /* This message ID is not in the table, and its number makes it
- what should be an RPC reply message ID. So look up the message
- ID of the corresponding RPC request and synthesize a name from
- that. Then stash that name in the table so the next time the
- lookup will match directly. */
- info = hurd_ihash_find (&msgid_ihash, msgid - 100);
- if (info != 0)
- {
- struct msgid_info *reply_info = malloc (sizeof *info);
- if (reply_info != 0)
- {
- reply_info->subsystem = strdup (info->subsystem);
- reply_info->name = 0;
- asprintf (&reply_info->name, "%s-reply", info->name);
- hurd_ihash_add (&msgid_ihash, msgid, reply_info);
- info = reply_info;
- }
- else
- info = 0;
- }
- }
- return info;
-}
-
static const char *
msgid_name (mach_msg_id_t msgid)
{
@@ -1781,55 +1670,9 @@ traced_spawn (char **argv, char **envp)
return pid;
}
-
-static void
-scan_msgids_dir (char **argz, size_t *argz_len, char *dir, bool append)
-{
- struct dirent **eps;
- int n;
-
- int
- msgids_file_p (const struct dirent *eps)
- {
- if (fnmatch ("*.msgids", eps->d_name, 0) != FNM_NOMATCH)
- return 1;
- return 0;
- }
-
- n = scandir (dir, &eps, msgids_file_p, NULL);
- if (n >= 0)
- {
- for (int cnt = 0; cnt < n; ++cnt)
- {
- char *msgids_file;
-
- if (asprintf (&msgids_file, "%s/%s", dir, eps[cnt]->d_name) < 0)
- error (1, errno, "asprintf");
-
- if (append == TRUE)
- {
- if (argz_add (argz, argz_len, msgids_file) != 0)
- error (1, errno, "argz_add");
- }
- else
- {
- if (argz_insert (argz, argz_len, *argz, msgids_file) != 0)
- error (1, errno, "argz_insert");
- }
- free (msgids_file);
- }
- }
-
- /* If the directory couldn't be scanned for whatever reason, just ignore
- it. */
-}
-
int
main (int argc, char **argv, char **envp)
{
- char *msgids_files_argz = NULL;
- size_t msgids_files_argz_len = 0;
- bool nostdinc = FALSE;
const char *outfile = 0;
char **cmd_argv = 0;
pthread_t thread;
@@ -1847,21 +1690,6 @@ main (int argc, char **argv, char **envp)
outfile = arg;
break;
- case OPT_NOSTDINC:
- nostdinc = TRUE;
- break;
-
- case 'i':
- if (argz_add (&msgids_files_argz, &msgids_files_argz_len,
- arg) != 0)
- error (1, errno, "argz_add");
- break;
-
- case 'I':
- scan_msgids_dir (&msgids_files_argz, &msgids_files_argz_len,
- arg, TRUE);
- break;
-
case 's':
strsize = atoi (arg);
break;
@@ -1908,7 +1736,12 @@ main (int argc, char **argv, char **envp)
}
return 0;
}
- const struct argp argp = { options, parse_opt, args_doc, doc };
+ const struct argp_child children[] =
+ {
+ { .argp=&msgid_argp, },
+ { 0 }
+ };
+ const struct argp argp = { options, parse_opt, args_doc, doc, &children };
/* Parse our arguments. */
argp_parse (&argp, argc, argv, ARGP_IN_ORDER, 0, 0);
@@ -1917,23 +1750,6 @@ main (int argc, char **argv, char **envp)
&unknown_task);
assert_perror (err);
- /* Insert the files from STD_MSGIDS_DIR at the beginning of the list, so that
- their content can be overridden by subsequently parsed files. */
- if (nostdinc == FALSE)
- scan_msgids_dir (&msgids_files_argz, &msgids_files_argz_len,
- STD_MSGIDS_DIR, FALSE);
-
- if (msgids_files_argz != NULL)
- {
- char *msgids_file = NULL;
-
- while ((msgids_file = argz_next (msgids_files_argz,
- msgids_files_argz_len, msgids_file)))
- parse_msgid_list (msgids_file);
-
- free (msgids_files_argz);
- }
-
if (outfile)
{
ostream = fopen (outfile, "w");
@@ -1951,8 +1767,6 @@ main (int argc, char **argv, char **envp)
sizeof (*notify_pi), &notify_pi);
assert_perror (err);
- hurd_ihash_set_cleanup (&msgid_ihash, msgid_ihash_cleanup, 0);
-
/* Spawn a single thread that will receive intercepted messages, print
them, and interpose on the ports they carry. The access to the
`traced_info' and ihash data structures is all single-threaded,