mirror of
https://github.com/imcarlost/pidcat-repl.git
synced 2026-08-08 23:17:43 -04:00
Merge pull request #32 from thorikawa/fix_samsung_logcat_issue
Use ps command to detect PIDs
This commit is contained in:
@@ -20,12 +20,16 @@ limitations under the License.
|
|||||||
# Written by Jeff Sharkey, http://jsharkey.org/
|
# Written by Jeff Sharkey, http://jsharkey.org/
|
||||||
# Piping detection and popen() added by other Android team members
|
# Piping detection and popen() added by other Android team members
|
||||||
# Package name restriction by Jake Wharton, http://jakewharton.com
|
# Package name restriction by Jake Wharton, http://jakewharton.com
|
||||||
|
# PID detection with ps command by Takahiro "Poly" Horikawa <horikawa.takahiro@gmail.com>
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import time
|
||||||
|
import thread
|
||||||
|
import threading
|
||||||
from subprocess import PIPE
|
from subprocess import PIPE
|
||||||
|
|
||||||
|
|
||||||
@@ -131,22 +135,26 @@ TAGTYPES = {
|
|||||||
'F': colorize(' F ', fg=BLACK, bg=RED),
|
'F': colorize(' F ', fg=BLACK, bg=RED),
|
||||||
}
|
}
|
||||||
|
|
||||||
PID_START = re.compile(r'^Start proc ([a-zA-Z0-9._:]+) for ([a-z]+ [^:]+): pid=(\d+) uid=(\d+) gids=(.*)$')
|
|
||||||
PID_KILL = re.compile(r'^Killing (\d+):([a-zA-Z0-9._]+)/[^:]+: (.*)$')
|
|
||||||
PID_LEAVE = re.compile(r'^No longer want ([a-zA-Z0-9._]+) \(pid (\d+)\): .*$')
|
|
||||||
PID_DEATH = re.compile(r'^Process ([a-zA-Z0-9._]+) \(pid (\d+)\) has died.?$')
|
|
||||||
LOG_LINE = re.compile(r'^([A-Z])/(.+?)\( *(\d+)\): (.*?)$')
|
LOG_LINE = re.compile(r'^([A-Z])/(.+?)\( *(\d+)\): (.*?)$')
|
||||||
BUG_LINE = re.compile(r'.*nativeGetEnabledTags.*')
|
BUG_LINE = re.compile(r'.*nativeGetEnabledTags.*')
|
||||||
|
|
||||||
adb_command = ['adb']
|
PS_POLLING_INTERVAL_SECS = 1
|
||||||
|
|
||||||
|
adb_options = []
|
||||||
if args.device_serial:
|
if args.device_serial:
|
||||||
adb_command.extend(['-s', args.device_serial])
|
adb_options.extend(['-s', args.device_serial])
|
||||||
if args.use_device:
|
if args.use_device:
|
||||||
adb_command.append('-d')
|
adb_options.append('-d')
|
||||||
if args.use_emulator:
|
if args.use_emulator:
|
||||||
adb_command.append('-e')
|
adb_options.append('-e')
|
||||||
|
adb_command = ['adb']
|
||||||
|
adb_command.extend(adb_options)
|
||||||
adb_command.append('logcat')
|
adb_command.append('logcat')
|
||||||
|
|
||||||
|
ps_command = ['adb']
|
||||||
|
ps_command.extend(adb_options)
|
||||||
|
ps_command.extend(['shell', 'ps'])
|
||||||
|
|
||||||
adb = subprocess.Popen(adb_command, stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
adb = subprocess.Popen(adb_command, stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
||||||
pids = set()
|
pids = set()
|
||||||
last_tag = None
|
last_tag = None
|
||||||
@@ -157,25 +165,60 @@ def match_packages(token):
|
|||||||
index = token.find(':')
|
index = token.find(':')
|
||||||
return (token in args.package) if index == -1 else (token[:index] in args.package)
|
return (token in args.package) if index == -1 else (token[:index] in args.package)
|
||||||
|
|
||||||
def parse_death(tag, message):
|
def parse_ps(ps_out):
|
||||||
if tag != 'ActivityManager':
|
new_pids = set()
|
||||||
return None
|
processes = ps_out.split('\n')
|
||||||
kill = PID_KILL.match(message)
|
fields = processes[0].split();
|
||||||
if kill:
|
nfields = len(fields)
|
||||||
pid = kill.group(1)
|
for row in processes[1:]:
|
||||||
if match_packages(kill.group(2)) and pid in pids:
|
row = row.rstrip()
|
||||||
return pid
|
if not row:
|
||||||
leave = PID_LEAVE.match(message)
|
continue
|
||||||
if leave:
|
fields = row.split(None, nfields)
|
||||||
pid = leave.group(2)
|
name = fields[8]
|
||||||
if match_packages(leave.group(1)) and pid in pids:
|
pid = fields[1]
|
||||||
return pid
|
if match_packages(name):
|
||||||
death = PID_DEATH.match(message)
|
new_pids.add(pid)
|
||||||
if death:
|
return new_pids
|
||||||
pid = death.group(2)
|
|
||||||
if match_packages(death.group(1)) and pid in pids:
|
def print_diff(pids, new_pids):
|
||||||
return pid
|
for new_pid in new_pids:
|
||||||
return None
|
if new_pid not in pids:
|
||||||
|
linebuf = '\n'
|
||||||
|
linebuf += colorize(' ' * (header_size - 1), bg=WHITE)
|
||||||
|
linebuf += ' Process %s is found' % (new_pid)
|
||||||
|
linebuf += '\n'
|
||||||
|
print(linebuf)
|
||||||
|
|
||||||
|
deleted_pids = pids.difference(new_pids)
|
||||||
|
for deleted_pid in deleted_pids:
|
||||||
|
linebuf = '\n'
|
||||||
|
linebuf += colorize(' ' * (header_size - 1), bg=WHITE)
|
||||||
|
linebuf += ' Process %s is deleted' % (deleted_pid)
|
||||||
|
linebuf += '\n'
|
||||||
|
print(linebuf)
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_pids():
|
||||||
|
ps = subprocess.Popen(ps_command, stdout=PIPE)
|
||||||
|
ps_out, ps_err = ps.communicate()
|
||||||
|
return parse_ps(ps_out)
|
||||||
|
|
||||||
|
def update_pids():
|
||||||
|
with lock:
|
||||||
|
new_pids = get_pids()
|
||||||
|
global pids
|
||||||
|
print_diff(pids, new_pids)
|
||||||
|
pids = new_pids
|
||||||
|
last_ps_check = time.time()
|
||||||
|
|
||||||
|
def update_pids_background():
|
||||||
|
while True:
|
||||||
|
update_pids()
|
||||||
|
time.sleep(PS_POLLING_INTERVAL_SECS)
|
||||||
|
|
||||||
|
lock = threading.RLock()
|
||||||
|
thread.start_new_thread(update_pids_background, ())
|
||||||
|
|
||||||
while adb.poll() is None:
|
while adb.poll() is None:
|
||||||
try:
|
try:
|
||||||
@@ -195,32 +238,6 @@ while adb.poll() is None:
|
|||||||
|
|
||||||
level, tag, owner, message = log_line.groups()
|
level, tag, owner, message = log_line.groups()
|
||||||
|
|
||||||
start = PID_START.match(message)
|
|
||||||
if start is not None:
|
|
||||||
line_package, target, line_pid, line_uid, line_gids = start.groups()
|
|
||||||
|
|
||||||
if match_packages(line_package):
|
|
||||||
pids.add(line_pid)
|
|
||||||
|
|
||||||
linebuf = '\n'
|
|
||||||
linebuf += colorize(' ' * (header_size - 1), bg=WHITE)
|
|
||||||
linebuf += indent_wrap(' Process created for %s\n' % target)
|
|
||||||
linebuf += colorize(' ' * (header_size - 1), bg=WHITE)
|
|
||||||
linebuf += ' PID: %s UID: %s GIDs: %s' % (line_pid, line_uid, line_gids)
|
|
||||||
linebuf += '\n'
|
|
||||||
print(linebuf)
|
|
||||||
last_tag = None # Ensure next log gets a tag printed
|
|
||||||
|
|
||||||
dead_pid = parse_death(tag, message)
|
|
||||||
if dead_pid:
|
|
||||||
pids.remove(dead_pid)
|
|
||||||
linebuf = '\n'
|
|
||||||
linebuf += colorize(' ' * (header_size - 1), bg=RED)
|
|
||||||
linebuf += ' Process %s ended' % dead_pid
|
|
||||||
linebuf += '\n'
|
|
||||||
print(linebuf)
|
|
||||||
last_tag = None # Ensure next log gets a tag printed
|
|
||||||
|
|
||||||
if owner not in pids:
|
if owner not in pids:
|
||||||
continue
|
continue
|
||||||
if LOG_LEVELS_MAP[level] < min_level:
|
if LOG_LEVELS_MAP[level] < min_level:
|
||||||
|
|||||||
Reference in New Issue
Block a user