- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / tools / chrome-process-identifier.sh
1 #!/bin/bash
2
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.
6
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.
11
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
17 }
18
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"
36 fi
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; }
48
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"
60         ;;
61       extension)
62         echo "Process $child is an extension"
63         ;;
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"
70         ;;
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"
85           fi
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"
93           fi
94         fi
95         ;;
96       zygote)
97         foundzygote=1
98         echo "Process $child is the zygote"
99         identify "$child"
100         ;;
101       *)
102         echo "Process $child is of unknown type \"$type\""
103         identify "$child"
104         ;;
105     esac
106   done
107   return $foundzygote
108 }
109
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
129 }
130
131
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"
144     fi
145   done
146 fi