summaryrefslogtreecommitdiffstats
path: root/tools/isolate/trace_inputs.py
diff options
context:
space:
mode:
authormaruel@chromium.org <maruel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-04 19:03:24 +0000
committermaruel@chromium.org <maruel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-04 19:03:24 +0000
commit733dfd0a6f394be71d448d6446b10ae277c57696 (patch)
tree4c03f021a7606ce979dcc6f950d72c2e504794b5 /tools/isolate/trace_inputs.py
parent58373dc0c5717b260e6bea465cdc0325336cbb59 (diff)
downloadchromium_src-733dfd0a6f394be71d448d6446b10ae277c57696.zip
chromium_src-733dfd0a6f394be71d448d6446b10ae277c57696.tar.gz
chromium_src-733dfd0a6f394be71d448d6446b10ae277c57696.tar.bz2
Improve dtrace execve() parsing to support quotes and reenable execve tracing.
Since sprintf() is not available in dtrace, use custom quoting using char '\1'. TBR=cmp@chromium.org NOTRY=true BUG= TEST= Review URL: https://chromiumcodereview.appspot.com/10694084 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@145479 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/isolate/trace_inputs.py')
-rwxr-xr-xtools/isolate/trace_inputs.py59
1 files changed, 45 insertions, 14 deletions
diff --git a/tools/isolate/trace_inputs.py b/tools/isolate/trace_inputs.py
index c5c6dff..089a45b 100755
--- a/tools/isolate/trace_inputs.py
+++ b/tools/isolate/trace_inputs.py
@@ -1325,11 +1325,11 @@ class Dtrace(ApiBase):
match = self.RE_EXECVE.match(args)
if not match:
raise TracingFailure(
- 'Failed to parse arguments: %s' % args,
+ 'Failed to parse arguments: %r' % args,
None, None, None)
proc = self.processes[pid]
proc.executable = match.group(1)
- proc.command = process_quoted_arguments(match.group(3))
+ proc.command = self.process_escaped_arguments(match.group(3))
if int(match.group(2)) != len(proc.command):
raise TracingFailure(
'Failed to parse execve() arguments: %s' % args,
@@ -1400,6 +1400,38 @@ class Dtrace(ApiBase):
"""Is called for all the event traces that are not handled."""
raise NotImplementedError('Please implement me')
+ @staticmethod
+ def process_escaped_arguments(text):
+ """Extracts escaped arguments on a string and return the arguments as a
+ list.
+
+ Implemented as an automaton.
+
+ Example:
+ With text = '\\001python2.7\\001-c\\001print(\\"hi\\")\\0', the
+ function will return ['python2.7', '-c', 'print("hi")]
+ """
+ if not text.endswith('\\0'):
+ raise ValueError('String is not null terminated: %r' % text, text)
+ text = text[:-2]
+
+ def unescape(x):
+ """Replaces '\\' with '\' and '\?' (where ? is anything) with ?.
+
+ Implemented as an automaton.
+ """
+ out = []
+ escaped = False
+ for i in x:
+ if i == '\\' and not escaped:
+ escaped = True
+ continue
+ escaped = False
+ out.append(i)
+ return ''.join(out)
+
+ return [unescape(i) for i in text.split('\\001')]
+
class Tracer(ApiBase.Tracer):
# pylint: disable=C0301
#
@@ -1617,39 +1649,38 @@ class Dtrace(ApiBase):
}
syscall::exec*:return /trackedpid[pid] && errno == 0/ {
/* We need to join strings here, as using multiple printf() would
- * cause tearing when multiple threads/processes are traced. */
+ * cause tearing when multiple threads/processes are traced.
+ * Since it is impossible to escape a string and join it to another one,
+ * like sprintf("%s%S", previous, more), use hackery.
+ * Each of the elements are split with a \\1. \\0 cannot be used because
+ * it is simply ignored. This will conflict with any program putting a
+ * \\1 in their execve() string but this should be "rare enough" */
this->args = "";
/* Process exec_argv[0] */
this->args = strjoin(
- this->args, (self->exec_argc > 0) ? ", \\"" : "");
- this->args = strjoin(
this->args, (self->exec_argc > 0) ? self->exec_argv0 : "");
- this->args = strjoin(this->args, (self->exec_argc > 0) ? "\\"" : "");
/* Process exec_argv[1] */
this->args = strjoin(
- this->args, (self->exec_argc > 1) ? ", \\"" : "");
+ this->args, (self->exec_argc > 1) ? "\\1" : "");
this->args = strjoin(
this->args, (self->exec_argc > 1) ? self->exec_argv1 : "");
- this->args = strjoin(this->args, (self->exec_argc > 1) ? "\\"" : "");
/* Process exec_argv[2] */
this->args = strjoin(
- this->args, (self->exec_argc > 2) ? ", \\"" : "");
+ this->args, (self->exec_argc > 2) ? "\\1" : "");
this->args = strjoin(
this->args, (self->exec_argc > 2) ? self->exec_argv2 : "");
- this->args = strjoin(this->args, (self->exec_argc > 2) ? "\\"" : "");
/* Process exec_argv[3] */
this->args = strjoin(
- this->args, (self->exec_argc > 3) ? ", \\"" : "");
+ this->args, (self->exec_argc > 3) ? "\\1" : "");
this->args = strjoin(
this->args, (self->exec_argc > 3) ? self->exec_argv3 : "");
- this->args = strjoin(this->args, (self->exec_argc > 3) ? "\\"" : "");
/* Prints self->exec_argc to permits verifying the internal
* consistency since this code is quite fishy. */
- printf("%d %d %s(\\"%s\\", [%d%s])\\n",
+ printf("%d %d %s(\\"%s\\", [%d, %S])\\n",
logindex, pid, probefunc,
self->exec_arg0,
self->exec_argc,
@@ -1786,7 +1817,7 @@ class Dtrace(ApiBase):
os.getpid(),
self._script,
self._dummy_file_id,
- self.D_CODE)
+ self.D_CODE) + self.D_CODE_EXECVE
def trace(self, cmd, cwd, tracename, output):
"""Runs dtrace on an executable.