show_delta使用
setenv mmcroot "/dev/mmcblk1p2 rootwait rw initcall_debug printk.time=1"
dmesg > kerneltime
scripts/bootgraph.pl kerneltime > boot.svg
# printk.time=1 or CONFIG_PRINTK_TIME=y
scripts/show_delta kerneltime > deltatime
bootgraph命令执行以后生成的boot.svg还可以,不过show_delta则匪夷所思,完全是将原始数据打印了一份还多了空行,deltatime的结果部分如下
[ 0.002652] Calibrating delay loop (skipped), value calculated using timer frequency.. 48.00 BogoMIPS (lpj=240000)
[ 0.002689] CPU: Testing write buffer coherency: ok
[ 0.002784] pid_max: default: 32768 minimum: 301
[ 0.003227] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 0.003269] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 0.007276] cblist_init_generic: Setting adjustable number of callback queues.
当时以为是命令使用不正确, 搜索了一下,有的多了-b选项,也就是找一个有指定字符串的行开始处理,如scripts/show_delta -b Calibrating kerneltime > deltatime
, 有点找不到方向了,乘兴而来,可能要败兴而归了,虽然这个功能用处不大,不过仍然想要弄明白,于是想看看脚本如何写的
usage: show_delta [<options>] <filename>
This program parses the output from a set of printk message lines which
have time data prefixed because the CONFIG_PRINTK_TIME option is set, or
the kernel command line option "time" is specified. When run with no
options, the time information is converted to show the time delta between
each printk line and the next. When run with the '-b' option, all times
are relative to a single (base) point in time.
Options:
-h Show this usage help.
-b <base> Specify a base for time references.
<base> can be a number or a string.
If it is a string, the first message line
which matches (at the beginning of the
line) is used as the time reference.
ex: $ dmesg >timefile
$ show_delta -b NET4 timefile
will show times relative to the line in the kernel output
starting with "NET4".
show_delta源码分析
show_delta代码很简单,仅仅100多行python代码,不过啥打印没有且有一段时间没有接触python了,还是需要静下心来看懂 main => convert_line(line, base_time)=>get_time(line),在get_time返回的加打印,尝试没有打印出来,函数一开始打印可以,所以问题在于string.split和string.atof中,疑问为啥执行有问题也不报错?
# returns a tuple containing the seconds and text for each message line
# seconds is returned as a float
# raise an exception if no timing data was found
def get_time(line):
if line[0]!="[":
raise ValueError
# split on closing bracket
(time_str, rest) = string.split(line[1:],']',1)
time = string.atof(time_str)
#print "time=", time
return (time, rest)
通过搜索python3相关的函数实现,同时去掉'\n'
结果如下:
[0.002652 < 0.000082 >] Calibrating delay loop (skipped), value calculated using timer frequency.. 48.00 BogoMIPS (lpj=240000)
[0.002689 < 0.000037 >] CPU: Testing write buffer coherency: ok
[0.002784 < 0.000095 >] pid_max: default: 32768 minimum: 301
[0.003227 < 0.000443 >] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[0.003269 < 0.000042 >] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[0.007276 < 0.004007 >] cblist_init_generic: Setting adjustable number of callback queues.
[0.007307 < 0.000031 >] cblist_init_generic: Setting shift to 0 and lim to 1.
[0.007564 < 0.000257 >] cblist_init_generic: Setting adjustable number of callback queues.
[0.007579 < 0.000015 >] cblist_init_generic: Setting shift to 0 and lim to 1.
(time_str, rest) = string.split(line[1:],']',1) ==>> time_str, rest = line[1:].split(']',1)
time = string.atof(time_str) ==> time=float(time_str)
rest = rest.rstrip('\n')
python相关
使用之前的show_delta,使用python2.7是可以的,因为我用的python3.10.12,才有问题 我们可以用dir(object)或者help(obj)在交互模式下查看到string对应的函数, 我们分别看看python2.7和python3.10.12的string情况 python3.10.12,可以看出没有string中已经没有split/find/atof等函数了, 而python2.7有的
Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import string
>>> help(string)
>>> dir(string)
['Formatter', 'Template', '_ChainMap', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_re', '_sentinel_dict', '_string', 'ascii_letters', 'ascii_lowercase', 'ascii_uppercase', 'capwords', 'digits', 'hexdigits', 'octdigits', 'printable', 'punctuation', 'whitespace']
>>> help(string)
>>> string.split
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'string' has no attribute 'split'
>>> string.find
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'string' has no attribute 'find'
>>> string.atof
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'string' has no attribute 'atof'
>>> string.ascii_letters
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> string.capwords
<function capwords at 0x7710c5fee680>
>>> string.digits
'0123456789'
>>> string
<module 'string' from '/usr/lib/python3.10/string.py'>
>>> print(string)
<module 'string' from '/usr/lib/python3.10/string.py'>
python2.7
Python 2.7.18 (default, Oct 15 2023, 16:43:11)
[GCC 11.4.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import string
>>> dir(string)
['Formatter', 'Template', '_TemplateMetaclass', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_float', '_idmap', '_idmapL', '_int', '_long', '_multimap', '_re', 'ascii_letters', 'ascii_lowercase', 'ascii_uppercase', 'atof', 'atof_error', 'atoi', 'atoi_error', 'atol', 'atol_error', 'capitalize', 'capwords', 'center', 'count', 'digits', 'expandtabs', 'find', 'hexdigits', 'index', 'index_error', 'join', 'joinfields', 'letters', 'ljust', 'lower', 'lowercase', 'lstrip', 'maketrans', 'octdigits', 'printable', 'punctuation', 'replace', 'rfind', 'rindex', 'rjust', 'rsplit', 'rstrip', 'split', 'splitfields', 'strip', 'swapcase', 'translate', 'upper', 'uppercase', 'whitespace', 'zfill']
>>> help(string)
>>> string.split
<function split at 0x7f842a07d6d0>
>>> string.split("hello]dd",']',1)
['hello', 'dd']
>>> string.atof("0.12308")
0.12308
>>> string
<module 'string' from '/usr/lib/python2.7/string.pyc'>
关于string相关,网上的信息如下:
string.ato* were deprecated in python 2.0, and removed >= 3.0. I replaced them with float()/int(), where appropriate.
show_delta 修改完全版
完整的代码如下:
#!/usr/bin/env python
# SPDX-License-Identifier: GPL-2.0-only
#
# show_deltas: Read list of printk messages instrumented with
# time data, and format with time deltas.
#
# Also, you can show the times relative to a fixed point.
#
# Copyright 2003 Sony Corporation
#
import sys
import string
def usage():
print ("""usage: show_delta [<options>] <filename>
This program parses the output from a set of printk message lines which
have time data prefixed because the CONFIG_PRINTK_TIME option is set, or
the kernel command line option "time" is specified. When run with no
options, the time information is converted to show the time delta between
each printk line and the next. When run with the '-b' option, all times
are relative to a single (base) point in time.
Options:
-h Show this usage help.
-b <base> Specify a base for time references.
<base> can be a number or a string.
If it is a string, the first message line
which matches (at the beginning of the
line) is used as the time reference.
ex: $ dmesg >timefile
$ show_delta -b NET4 timefile
will show times relative to the line in the kernel output
starting with "NET4".
""")
sys.exit(1)
# returns a tuple containing the seconds and text for each message line
# seconds is returned as a float
# raise an exception if no timing data was found
def get_time(line):
if line[0]!="[":
raise ValueError
# split on closing bracket
#(time_str, rest) = string.split(line[1:],']',1)
# time = string.atof(time_str)
time_str, rest = line[1:].split(']',1)
time = float(time_str)
rest = rest.rstrip('\n')
return (time, rest)
# average line looks like:
# [ 0.084282] VFS: Mounted root (romfs filesystem) readonly
# time data is expressed in seconds.useconds,
# convert_line adds a delta for each line
last_time = 0.0
def convert_line(line, base_time):
global last_time
try:
(time, rest) = get_time(line)
except:
# if any problem parsing time, don't convert anything
return line
if base_time:
# show time from base
delta = time - base_time
else:
# just show time from last line
delta = time - last_time
last_time = time
return ("[%5.6f < %5.6f >]" % (time, delta)) + rest
def main():
base_str = ""
filein = ""
for arg in sys.argv[1:]:
if arg=="-b":
base_str = sys.argv[sys.argv.index("-b")+1]
elif arg=="-h":
usage()
else:
filein = arg
if not filein:
usage()
try:
lines = open(filein,"r").readlines()
except:
print ("Problem opening file: %s" % filein)
sys.exit(1)
if base_str:
print ('base= "%s"' % base_str)
# assume a numeric base. If that fails, try searching
# for a matching line.
try:
base_time = float(base_str)
except:
# search for line matching <base> string
found = 0
for line in lines:
try:
(time, rest) = get_time(line)
except:
continue
if rest.find(base_str)==1:
base_time = time
found = 1
# stop at first match
break
if not found:
print ('Couldn\'t find line matching base pattern "%s"' % base_str)
sys.exit(1)
else:
base_time = 0.0
for line in lines:
print (convert_line(line, base_time),)
main()
references:
- https://ioflood.com/blog/convert-string-to-float-python/
- https://github.com/psychopy/psychopy/pull/1853