Change "percentage change" function and add comments/test for it.
[chromium-blink-merge.git] / chrome / tools / chrome-process-identifier.sh
blobf6b7af36cbc1ca3e6704209725353c6b0fcfc2ae
1 #!/bin/bash
3 # Copyright (c) 2010 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
7 # This utility finds the different processes in a running instance of Chrome.
8 # It then attempts to identify their types (e.g. browser, extension, plugin,
9 # zygote, renderer). It also prints out information on whether a sandbox is
10 # active and what type of sandbox has been identified.
12 # This script is likely to only work on Linux or systems that closely mimick
13 # Linux's /proc filesystem.
14 [ -x /proc/self/exe ] || {
15 echo "This script cannot be run on your system" >&2
16 exit 1
19 # Find the browser's process id. If there are multiple active instances of
20 # Chrome, the caller can provide a pid on the command line. The provided pid
21 # must match a process in the browser's process hierarchy. When using the
22 # zygote inside of the setuid sandbox, renderers are in a process tree separate
23 # from the browser process. You cannot use any of their pids.
24 # If no pid is provided on the command line, the script will randomly pick
25 # one of the running instances.
26 if [ $# -eq 0 ]; then
27 pid=$(ls -l /proc/*/exe 2>/dev/null |
28 sed '/\/chrome\( .deleted.\)\?$/s,.*/proc/\([^/]*\)/exe.*,\1,;t;d' |
29 while read p; do
30 xargs -0 </proc/$p/cmdline 2>/dev/null|grep -q -- --type= && continue
31 echo "$p"
32 break
33 done)
34 else
35 pid="$1"
37 ls -l "/proc/$pid/exe" 2>/dev/null|egrep -q '/chrome( .deleted.)?$' || {
38 echo "Cannot find any running instance of Chrome" >&2; exit 1; }
39 while :; do
40 ppid="$(ps h --format ppid --pid "$pid" 2>/dev/null)"
41 [ -n "$ppid" ] || {
42 echo "Cannot find any running instance of Chrome" >&2; exit 1; }
43 ls -l "/proc/$ppid/exe" 2>/dev/null|egrep -q '/chrome( .deleted.)?$' &&
44 pid="$ppid" || break
45 done
46 xargs -0 </proc/$p/cmdline 2>/dev/null|grep -q -- --type= && {
47 echo "Cannot find any running instance of Chrome" >&2; exit 1; }
49 # Iterate over child processes and try to identify them
50 identify() {
51 local child cmd foundzygote plugin seccomp type
52 foundzygote=0
53 for child in $(ps h --format pid --ppid $1); do
54 cmd="$(xargs -0 </proc/$child/cmdline|sed 's/ -/\n-/g')" 2>/dev/null
55 type="$(echo "$cmd" | sed 's/--type=//;t1;d;:1;q')"
56 case $type in
57 '')
58 echo "Process $child is part of the browser"
59 identify "$child"
61 extension)
62 echo "Process $child is an extension"
64 plugin)
65 plugin="$(echo "$cmd" |
66 sed 's/--plugin-path=//;t1;d;:1
67 s,.*/lib,,;s,.*/npwrapper[.]lib,,;s,^np,,;s,[.]so$,,;q')"
68 echo "Process $child is a \"$plugin\" plugin"
69 identify "$child"
71 renderer|worker|gpu-process)
72 # The seccomp sandbox has exactly one child process that has no other
73 # threads. This is the trusted helper process.
74 seccomp="$(ps h --format pid --ppid $child|xargs)"
75 if [ -d /proc/$child/cwd/. ]; then
76 if [ $(echo "$seccomp" | wc -w) -eq 1 ] &&
77 [ $(ls /proc/$seccomp/task 2>/dev/null | wc -w) -eq 1 ] &&
78 ls -l /proc/$seccomp/exe 2>/dev/null |
79 egrep -q '/chrome( .deleted.)?$'; then
80 echo "Process $child is a sandboxed $type (seccomp helper:" \
81 "$seccomp)"
82 else
83 echo "Process $child is a $type"
84 identify "$child"
86 else
87 if [ $(echo "$seccomp" | wc -w) -eq 1 ]; then
88 echo "Process $child is a setuid sandboxed $type (seccomp" \
89 "helper: $seccomp)"
90 else
91 echo "Process $child is a $type; setuid sandbox is active"
92 identify "$child"
96 zygote)
97 foundzygote=1
98 echo "Process $child is the zygote"
99 identify "$child"
102 echo "Process $child is of unknown type \"$type\""
103 identify "$child"
105 esac
106 done
107 return $foundzygote
110 cmpcmdline() {
111 # Checks that the command line arguments for pid $1 are a superset of the
112 # commandline arguments for pid $2.
113 # Any additional function arguments $3, $4, ... list options that should
114 # be ignored for the purpose of this comparison.
115 local pida="$1"
116 local pidb="$2"
117 shift; shift
118 local super=("$@" $(xargs -0 </proc/"$pida"/cmdline)) 2>/dev/null
119 local sub=($(xargs -0 </proc/"$pidb"/cmdline)) 2>/dev/null
120 local i j
121 [ ${#sub[*]} -eq 0 -o ${#super[*]} -eq 0 ] && return 1
122 for i in $(seq 0 $((${#sub[*]}-1))); do
123 for j in $(seq 0 $((${#super[*]}-1))); do
124 [ "x${sub[$i]}" = "x${super[$j]}" ] && continue 2
125 done
126 return 1
127 done
128 return 0
132 echo "The browser's main pid is: $pid"
133 if identify "$pid"; then
134 # The zygote can make it difficult to locate renderers, as the setuid
135 # sandbox causes it to be reparented to "init". When this happens, we can
136 # no longer associate it with the browser with 100% certainty. We make a
137 # best effort by comparing command line strings.
138 for i in $(ps h --format pid --ppid 1); do
139 if cmpcmdline "$pid" "$i" "--type=zygote"; then
140 echo -n "Process $i is the zygote"
141 [ -d /proc/$i/cwd/. ] || echo -n "; setuid sandbox is active"
142 echo
143 identify "$i"
145 done