1 # -*- coding: utf-8 -*-
4 Generate .stp file that printfs log messages (DTrace with SystemTAP only).
7 __author__
= "Daniel P. Berrange <berrange@redhat.com>"
8 __copyright__
= "Copyright (C) 2014-2019, Red Hat, Inc."
9 __license__
= "GPL version 2 or (at your option) any later version"
11 __maintainer__
= "Daniel Berrange"
12 __email__
= "berrange@redhat.com"
16 from tracetool
import out
17 from tracetool
.backend
.dtrace
import binary
, probeprefix
18 from tracetool
.backend
.simple
import is_string
19 from tracetool
.format
.stap
import stap_escape
21 def global_var_name(name
):
22 return probeprefix().replace(".", "_") + "_" + name
28 def c_macro_to_format(macro
):
29 if macro
.startswith("PRI"):
32 raise Exception("Unhandled macro '%s'" % macro
)
34 def c_fmt_to_stap(fmt
):
40 for i
in range(len(fmt
)):
46 if state
!= STATE_LITERAL
:
47 raise Exception("Unexpected escape outside string literal")
48 literal
= literal
+ fmt
[i
]
49 elif fmt
[i
] == '"' and not escape
:
50 if state
== STATE_LITERAL
:
55 if state
== STATE_MACRO
:
56 bits
.append(c_macro_to_format(macro
))
58 elif fmt
[i
] == ' ' or fmt
[i
] == '\t':
59 if state
== STATE_MACRO
:
60 bits
.append(c_macro_to_format(macro
))
63 elif state
== STATE_LITERAL
:
64 literal
= literal
+ fmt
[i
]
67 if state
== STATE_SKIP
:
70 if state
== STATE_LITERAL
:
71 literal
= literal
+ fmt
[i
]
73 macro
= macro
+ fmt
[i
]
75 if state
== STATE_MACRO
:
76 bits
.append(c_macro_to_format(macro
))
77 elif state
== STATE_LITERAL
:
80 fmt
= re
.sub("%(\d*)z(x|u|d)", "%\\1\\2", "".join(bits
))
83 def generate(events
, backend
, group
):
84 out('/* This file is autogenerated by tracetool, do not edit. */',
87 for event_id
, e
in enumerate(events
):
88 if 'disable' in e
.properties
:
91 out('probe %(probeprefix)s.log.%(name)s = %(probeprefix)s.%(name)s ?',
93 probeprefix
=probeprefix(),
96 # Get references to userspace strings
97 for type_
, name
in e
.args
:
98 name
= stap_escape(name
)
101 ' arg%(name)s_str = %(name)s ? ' +
102 'user_string_n(%(name)s, 512) : "<null>"',
106 # Determine systemtap's view of variable names
107 fields
= ["pid()", "gettimeofday_ns()"]
108 for type_
, name
in e
.args
:
109 name
= stap_escape(name
)
111 fields
.append("arg" + name
+ "_str")
115 # Emit the entire record in a single SystemTap printf()
116 arg_str
= ', '.join(arg
for arg
in fields
)
117 fmt_str
= "%d@%d " + e
.name
+ " " + c_fmt_to_stap(e
.fmt
) + "\\n"
118 out(' printf("%(fmt_str)s", %(arg_str)s)',
119 fmt_str
=fmt_str
, arg_str
=arg_str
)