mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 07:13:54 -06:00
Simpletrace v2: Support multiple arguments, strings.
Existing simpletrace backend allows to trace at max 6 args and does not support strings. This newer tracelog format gets rid of fixed size records and therefore allows to trace variable number of args including strings. Sample trace with strings: v9fs_version 0.000 tag=0xffff id=0x64 msize=0x2000 version=9P2000.L v9fs_version_return 6.705 tag=0xffff id=0x64 msize=0x2000 version=9P2000.L Signed-off-by: Harsh Prateek Bora <harsh@linux.vnet.ibm.com> Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
This commit is contained in:
parent
88affa1c77
commit
62bab73213
3 changed files with 273 additions and 131 deletions
|
@ -15,9 +15,16 @@ __email__ = "stefanha@linux.vnet.ibm.com"
|
|||
|
||||
from tracetool import out
|
||||
|
||||
def is_string(arg):
|
||||
strtype = ('const char*', 'char*', 'const char *', 'char *')
|
||||
if arg.lstrip().startswith(strtype):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def c(events):
|
||||
out('#include "trace.h"',
|
||||
'#include "trace/simple.h"',
|
||||
'',
|
||||
'TraceEvent trace_list[] = {')
|
||||
|
||||
|
@ -26,30 +33,75 @@ def c(events):
|
|||
name = e.name,
|
||||
)
|
||||
|
||||
out('};')
|
||||
out('};',
|
||||
'')
|
||||
|
||||
for num, event in enumerate(events):
|
||||
out('void trace_%(name)s(%(args)s)',
|
||||
'{',
|
||||
' TraceBufferRecord rec;',
|
||||
name = event.name,
|
||||
args = event.args,
|
||||
)
|
||||
sizes = []
|
||||
for type_, name in event.args:
|
||||
if is_string(type_):
|
||||
out(' size_t arg%(name)s_len = %(name)s ? MIN(strlen(%(name)s), MAX_TRACE_STRLEN) : 0;',
|
||||
name = name,
|
||||
)
|
||||
strsizeinfo = "4 + arg%s_len" % name
|
||||
sizes.append(strsizeinfo)
|
||||
else:
|
||||
sizes.append("8")
|
||||
sizestr = " + ".join(sizes)
|
||||
if len(event.args) == 0:
|
||||
sizestr = '0'
|
||||
|
||||
|
||||
out('',
|
||||
' if (!trace_list[%(event_id)s].state) {',
|
||||
' return;',
|
||||
' }',
|
||||
'',
|
||||
' if (trace_record_start(&rec, %(event_id)s, %(size_str)s)) {',
|
||||
' return; /* Trace Buffer Full, Event Dropped ! */',
|
||||
' }',
|
||||
event_id = num,
|
||||
size_str = sizestr,
|
||||
)
|
||||
|
||||
if len(event.args) > 0:
|
||||
for type_, name in event.args:
|
||||
# string
|
||||
if is_string(type_):
|
||||
out(' trace_record_write_str(&rec, %(name)s, arg%(name)s_len);',
|
||||
name = name,
|
||||
)
|
||||
# pointer var (not string)
|
||||
elif type_.endswith('*'):
|
||||
out(' trace_record_write_u64(&rec, (uint64_t)(uint64_t *)%(name)s);',
|
||||
name = name,
|
||||
)
|
||||
# primitive data type
|
||||
else:
|
||||
out(' trace_record_write_u64(&rec, (uint64_t)%(name)s);',
|
||||
name = name,
|
||||
)
|
||||
|
||||
out(' trace_record_finish(&rec);',
|
||||
'}',
|
||||
'')
|
||||
|
||||
|
||||
def h(events):
|
||||
out('#include "trace/simple.h"',
|
||||
'')
|
||||
|
||||
for num, e in enumerate(events):
|
||||
if len(e.args):
|
||||
argstr = e.args.names()
|
||||
arg_prefix = ', (uint64_t)(uintptr_t)'
|
||||
cast_args = arg_prefix + arg_prefix.join(argstr)
|
||||
simple_args = (str(num) + cast_args)
|
||||
else:
|
||||
simple_args = str(num)
|
||||
|
||||
out('static inline void trace_%(name)s(%(args)s)',
|
||||
'{',
|
||||
' trace%(argc)d(%(trace_args)s);',
|
||||
'}',
|
||||
name = e.name,
|
||||
args = e.args,
|
||||
argc = len(e.args),
|
||||
trace_args = simple_args,
|
||||
for event in events:
|
||||
out('void trace_%(name)s(%(args)s);',
|
||||
name = event.name,
|
||||
args = event.args,
|
||||
)
|
||||
|
||||
out('')
|
||||
out('#define NR_TRACE_EVENTS %d' % len(events))
|
||||
out('extern TraceEvent trace_list[NR_TRACE_EVENTS];')
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue