1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
from ptrace.os_tools import RUNNING_LINUX
if RUNNING_LINUX:
from ptrace.linux_proc import (
ProcError,
openProc,
readProcessLink,
readProcessProcList,
readProcessStat,
)
from ptrace.signames import signalName # noqa
from os import (
WCOREDUMP,
WEXITSTATUS,
WIFSIGNALED,
WIFSTOPPED,
WSTOPSIG,
WTERMSIG,
)
def dumpProcessInfo(log, pid, max_length=None):
"""
Dump all information about a process:
- log: callback to write display one line
- pid: process identifier
- max_length (default: None): maximum number of environment variables
"""
if not RUNNING_LINUX:
log("Process ID: %s" % pid)
return
try:
stat = readProcessStat(pid)
except ProcError:
# Permission denied
stat = None
text = "Process ID: %s" % pid
if stat:
text += " (parent: %s)" % stat.ppid
log(text)
if stat:
state = stat.state
try:
state = "%s (%s)" % (state, stat.STATE_NAMES[state])
except KeyError:
pass
log("Process state: %s" % state)
try:
log("Process command line: %r" % readProcessProcList(pid, 'cmdline'))
except ProcError:
# Permission denied
pass
try:
env = readProcessProcList(pid, 'environ')
if max_length:
# Truncate environment if it's too long
length = 0
removed = 0
index = 0
while index < len(env):
var = env[index]
if max_length < length + len(var):
del env[index]
removed += 1
else:
length += len(var)
index += 1
env = ', '.join("%s=%r" % tuple(item.split("=", 1))
for item in env)
if removed:
env += ', ... (skip %s vars)' % removed
log("Process environment: %s" % env)
except ProcError:
# Permission denied
pass
try:
log("Process working directory: %s" % readProcessLink(pid, 'cwd'))
except ProcError:
# Permission denied
pass
try:
user = None
group = None
status_file = openProc("%s/status" % pid)
for line in status_file:
if line.startswith("Uid:"):
user = [int(id) for id in line[5:].split("\t")]
if line.startswith("Gid:"):
group = [int(id) for id in line[5:].split("\t")]
status_file.close()
if user:
text = "User identifier: %s" % user[0]
if user[0] != user[1]:
text += " (effective: %s)" % user[1]
log(text)
if group:
text = "Group identifier: %s" % group[0]
if group[0] != group[1]:
text += " (effective: %s)" % group[1]
log(text)
except ProcError:
# Permission denied
pass
def formatProcessStatus(status, title="Process"):
"""
Format a process status (integer) as a string.
"""
if WIFSTOPPED(status):
signum = WSTOPSIG(status)
text = "%s stopped by signal %s" % (title, signalName(signum))
elif WIFSIGNALED(status):
signum = WTERMSIG(status)
text = "%s killed by signal %s" % (title, signalName(signum))
else:
exitcode = WEXITSTATUS(status)
if exitcode:
text = "%s exited with code %s" % (title, exitcode)
else:
text = "%s exited normally" % title
if WCOREDUMP(status):
text += " (core dumped)"
return text
|