fix unicode decode error
This commit is contained in:
parent
a5c2b28ae9
commit
f869b0bdbb
122
nohang
122
nohang
@ -19,7 +19,7 @@ if self_uid == 0:
|
||||
else:
|
||||
root = False
|
||||
|
||||
wait_time = 14
|
||||
wait_time = 12
|
||||
|
||||
max_sleep_time = 2
|
||||
min_sleep_time = 0.1
|
||||
@ -29,6 +29,8 @@ notify_helper_path = '/usr/sbin/nohang_notify_helper'
|
||||
psi_path = '/proc/pressure/memory'
|
||||
psi_support = os.path.exists(psi_path)
|
||||
|
||||
HR = '~' * 70
|
||||
|
||||
##########################################################################
|
||||
|
||||
|
||||
@ -182,11 +184,12 @@ def rline1(path):
|
||||
for line in f:
|
||||
return line[:-1]
|
||||
|
||||
|
||||
'''
|
||||
def write(path, string):
|
||||
"""Write string to path."""
|
||||
with open(path, 'w') as f:
|
||||
f.write(string)
|
||||
'''
|
||||
|
||||
|
||||
def kib_to_mib(num):
|
||||
@ -247,12 +250,18 @@ def pid_to_name(pid):
|
||||
"""
|
||||
try:
|
||||
with open('/proc/' + pid + '/status') as f:
|
||||
f.seek(6)
|
||||
for line in f:
|
||||
return line[:-1].split('\t')[1]
|
||||
return line[:-1]
|
||||
except FileNotFoundError:
|
||||
return ''
|
||||
except ProcessLookupError:
|
||||
return ''
|
||||
except UnicodeDecodeError:
|
||||
with open('/proc/' + pid + '/status', 'rb') as f:
|
||||
f.seek(6)
|
||||
return f.read(15).decode(
|
||||
'utf-8', 'ignore').partition('\n')[0]
|
||||
|
||||
|
||||
def pid_to_cmdline(pid):
|
||||
@ -262,22 +271,25 @@ def pid_to_cmdline(pid):
|
||||
pid: str pid of required process
|
||||
returns string cmdline
|
||||
"""
|
||||
with open('/proc/' + pid + '/cmdline') as file:
|
||||
try:
|
||||
return file.readlines()[0].replace('\x00', ' ').strip()
|
||||
except IndexError:
|
||||
return ''
|
||||
with open('/proc/' + pid + '/cmdline') as f:
|
||||
return f.read().replace('\x00', ' ').rstrip()
|
||||
|
||||
|
||||
def pid_to_uid(pid):
|
||||
'''return euid'''
|
||||
with open('/proc/' + pid + '/status') as f:
|
||||
for n, line in enumerate(f):
|
||||
if n is uid_index:
|
||||
return line.split('\t')[2]
|
||||
try:
|
||||
with open('/proc/' + pid + '/status') as f:
|
||||
for n, line in enumerate(f):
|
||||
if n is uid_index:
|
||||
return line.split('\t')[2]
|
||||
except UnicodeDecodeError:
|
||||
with open('/proc/' + pid + '/status', 'rb') as f:
|
||||
f_list = f.read().decode('utf-8', 'ignore').split('\n')
|
||||
return f_list[uid_index].split('\t')[2]
|
||||
|
||||
|
||||
def notify_send_wait(title, body):
|
||||
'''GUI notifications with UID != 0'''
|
||||
with Popen(['notify-send', '--icon=dialog-warning', title, body]) as proc:
|
||||
try:
|
||||
proc.wait(timeout=wait_time)
|
||||
@ -287,6 +299,7 @@ def notify_send_wait(title, body):
|
||||
|
||||
|
||||
def notify_helper(title, body):
|
||||
'''GUI notification with UID = 0'''
|
||||
with Popen([notify_helper_path, title, body]) as proc:
|
||||
try:
|
||||
proc.wait(timeout=wait_time)
|
||||
@ -342,8 +355,8 @@ def send_notify(signal, name, pid):
|
||||
title = 'Preventing OOM'
|
||||
body = '<b>{}</b> process <b>{}</b>, <b>{}</b>'.format(
|
||||
notify_sig_dict[signal], pid, name.replace(
|
||||
# сивол & может ломать уведомления в некоторых темах оформления,
|
||||
# поэтому заменяется на *
|
||||
# symbol '&' can break notifications in some themes,
|
||||
# therefore it is replaced by '*'
|
||||
'&', '*'))
|
||||
if root:
|
||||
# send notification to all active users with notify-send
|
||||
@ -353,6 +366,27 @@ def send_notify(signal, name, pid):
|
||||
notify_send_wait(title, body)
|
||||
|
||||
|
||||
'''
|
||||
def send_notify(signal, name, pid):
|
||||
"""
|
||||
Notificate about OOM Preventing.
|
||||
|
||||
signal: key for notify_sig_dict
|
||||
name: str process name
|
||||
pid: str process pid
|
||||
"""
|
||||
title = 'Preventing OOM'
|
||||
body = '<b>{}</b> process <b>{}</b>, <b>{}</b>'.format(
|
||||
notify_sig_dict[signal], pid, name)
|
||||
if root:
|
||||
# send notification to all active users with notify-send
|
||||
notify_helper(title, body)
|
||||
else:
|
||||
# send notification to user that runs this nohang
|
||||
notify_send_wait(title, body)
|
||||
'''
|
||||
|
||||
|
||||
def send_notify_etc(pid, name, command):
|
||||
"""
|
||||
Notificate about OOM Preventing.
|
||||
@ -472,6 +506,7 @@ def find_victim_and_send_signal(signal):
|
||||
# Get VmRSS and VmSwap and cmdline of victim process and try to send
|
||||
# signal
|
||||
try:
|
||||
|
||||
with open('/proc/' + pid + '/status') as f:
|
||||
for n, line in enumerate(f):
|
||||
|
||||
@ -516,24 +551,67 @@ def find_victim_and_send_signal(signal):
|
||||
|
||||
except FileNotFoundError:
|
||||
print(mem_info)
|
||||
print('The victim died in the search process')
|
||||
update_stat_dict_and_print('The victim died in the search process')
|
||||
print('The victim died in the search process: FileNotFoundError')
|
||||
update_stat_dict_and_print('The victim died in the search process: FileNotFoundError')
|
||||
return None
|
||||
except ProcessLookupError:
|
||||
print(mem_info)
|
||||
print('The victim died in the search process')
|
||||
update_stat_dict_and_print('The victim died in the search process')
|
||||
print('The victim died in the search process: ProcessLookupError')
|
||||
update_stat_dict_and_print('The victim died in the search process: ProcessLookupError')
|
||||
return None
|
||||
except UnicodeDecodeError:
|
||||
|
||||
# тут надо снова все исключ обработать
|
||||
|
||||
with open('/proc/' + pid + '/status', 'rb') as f:
|
||||
f_list = f.read().decode('utf-8', 'ignore').split('\n')
|
||||
|
||||
for i in range(len(f_list)):
|
||||
if i is uid_index:
|
||||
uid = f_list[i].split('\t')[2]
|
||||
|
||||
if i is vm_size_index:
|
||||
vm_size = kib_to_mib(int(f_list[i].split('\t')[1][:-3]))
|
||||
|
||||
if i is vm_rss_index:
|
||||
vm_rss = kib_to_mib(int(f_list[i].split('\t')[1][:-3]))
|
||||
|
||||
if detailed_rss:
|
||||
|
||||
if i is anon_index:
|
||||
anon_rss = kib_to_mib(
|
||||
int(f_list[i].split('\t')[1][:-3]))
|
||||
|
||||
if i is file_index:
|
||||
file_rss = kib_to_mib(
|
||||
int(f_list[i].split('\t')[1][:-3]))
|
||||
|
||||
if i is shmem_index:
|
||||
shmem_rss = kib_to_mib(
|
||||
int(f_list[i].split('\t')[1][:-3]))
|
||||
|
||||
if i is vm_swap_index:
|
||||
vm_swap = kib_to_mib(int(f_list[i].split('\t')[1][:-3]))
|
||||
|
||||
|
||||
with open('/proc/' + pid + '/cmdline') as file:
|
||||
cmdline = file.readlines()[0].replace('\x00', ' ')
|
||||
|
||||
oom_score = rline1('/proc/' + pid + '/oom_score')
|
||||
oom_score_adj = rline1('/proc/' + pid + '/oom_score_adj')
|
||||
|
||||
except IndexError:
|
||||
print(mem_info)
|
||||
print('The victim died in the search process')
|
||||
update_stat_dict_and_print('The victim died in the search process')
|
||||
print('The victim died in the search process: IndexError')
|
||||
update_stat_dict_and_print('The victim died in the search process: IndexError')
|
||||
return None
|
||||
except ValueError:
|
||||
print(mem_info)
|
||||
print('The victim died in the search process')
|
||||
update_stat_dict_and_print('The victim died in the search process')
|
||||
print('The victim died in the search process: ValueError')
|
||||
update_stat_dict_and_print('The victim died in the search process: ValueError')
|
||||
return None
|
||||
|
||||
|
||||
len_vm = len(str(vm_size))
|
||||
|
||||
if detailed_rss:
|
||||
|
16
nohang.conf
16
nohang.conf
@ -132,7 +132,7 @@ min_delay_after_sigkill = 1
|
||||
Valid values are True and False.
|
||||
Values are case sensitive.
|
||||
|
||||
decrease_oom_score_adj = False
|
||||
decrease_oom_score_adj = True
|
||||
|
||||
Valid values are integers from the range [0; 1000].
|
||||
|
||||
@ -160,7 +160,7 @@ oom_score_adj_max = 30
|
||||
|
||||
Valid values are True and False.
|
||||
|
||||
regex_matching = False
|
||||
regex_matching = True
|
||||
|
||||
Syntax:
|
||||
|
||||
@ -184,7 +184,7 @@ regex_matching = False
|
||||
|
||||
A good option that allows fine adjustment.
|
||||
|
||||
re_match_cmdline = False
|
||||
re_match_cmdline = True
|
||||
|
||||
@CMDLINE_RE 300 /// -childID|--type=renderer
|
||||
|
||||
@ -195,7 +195,7 @@ re_match_cmdline = False
|
||||
|
||||
The most slow option
|
||||
|
||||
re_match_uid = False
|
||||
re_match_uid = True
|
||||
|
||||
@UID_RE -100 /// ^0$
|
||||
|
||||
@ -215,7 +215,7 @@ re_match_uid = False
|
||||
|
||||
Valid values are True and False.
|
||||
|
||||
execute_the_command = False
|
||||
execute_the_command = True
|
||||
|
||||
The length of the process name can't exceed 15 characters.
|
||||
The syntax is as follows: lines starting with keyword $ETC are
|
||||
@ -240,7 +240,7 @@ execute_the_command = False
|
||||
|
||||
Also $NAME will be replaced by process name.
|
||||
|
||||
$ETC bash /// kill -9 $PID
|
||||
$ETC bash /// kill -9 $PID
|
||||
$ETC firefox-esr /// kill -SEGV $PID
|
||||
|
||||
#####################################################################
|
||||
@ -258,12 +258,12 @@ $ETC firefox-esr /// kill -SEGV $PID
|
||||
See also wiki.archlinux.org/index.php/Desktop_notifications
|
||||
Valid values are True and False.
|
||||
|
||||
gui_notifications = False
|
||||
gui_notifications = True
|
||||
|
||||
Enable GUI notifications about the low level of available memory.
|
||||
Valid values are True and False.
|
||||
|
||||
gui_low_memory_warnings = False
|
||||
gui_low_memory_warnings = True
|
||||
|
||||
Минимальное время между отправками уведомлений в секундах.
|
||||
Valid values are floating-point numbers from the range [1; 300].
|
||||
|
@ -3,7 +3,7 @@
|
||||
# Usage:
|
||||
# ./nohang_notify_helper "title" "body"
|
||||
|
||||
from sys import argv
|
||||
from sys import argv, stdout
|
||||
from os import listdir
|
||||
from subprocess import Popen, TimeoutExpired
|
||||
|
||||
@ -93,10 +93,17 @@ def root_notify_env():
|
||||
|
||||
|
||||
list_with_envs = root_notify_env()
|
||||
list_len = len(list_with_envs)
|
||||
|
||||
|
||||
# if somebody logged in with GUI
|
||||
if len(list_with_envs) > 0:
|
||||
if list_len > 0:
|
||||
|
||||
for i in list_with_envs:
|
||||
print('Send GUI notification:', argv[1], argv[2], i)
|
||||
|
||||
stdout.flush()
|
||||
|
||||
# iterating over logged-in users
|
||||
for i in list_with_envs:
|
||||
username, display_env, dbus_env = i[0], i[1], i[2]
|
||||
@ -118,4 +125,6 @@ if len(list_with_envs) > 0:
|
||||
proc.kill()
|
||||
print('TimeoutExpired: notify user:' + username)
|
||||
else:
|
||||
print('Nobody logged-in with GUI. Nothing to do.')
|
||||
print('Not send GUI notification: [', argv[1], argv[2], ']. Nobody logged-in with GUI. Nothing to do.')
|
||||
|
||||
stdout.flush()
|
||||
|
Loading…
Reference in New Issue
Block a user