2 # -*- coding: utf-8 -*-
5 Generate .stp file that printfs log messages (DTrace with SystemTAP only).
8 __author__
= "Daniel P. Berrange <berrange@redhat.com>"
9 __copyright__
= "Copyright (C) 2014-2019, Red Hat, Inc."
10 __license__
= "GPL version 2 or (at your option) any later version"
12 __maintainer__
= "Daniel Berrange"
13 __email__
= "berrange@redhat.com"
17 from tracetool
import out
18 from tracetool
.backend
.dtrace
import binary
, probeprefix
19 from tracetool
.backend
.simple
import is_string
20 from tracetool
.format
.stap
import stap_escape
22 def global_var_name(name
):
23 return probeprefix().replace(".", "_") + "_" + name
29 def c_macro_to_format(macro
):
30 if macro
.startswith("PRI"):
33 if macro
== "TARGET_FMT_plx":
36 raise Exception("Unhandled macro '%s'" % macro
)
38 def c_fmt_to_stap(fmt
):
44 for i
in range(len(fmt
)):
50 if state
!= STATE_LITERAL
:
51 raise Exception("Unexpected escape outside string literal")
52 literal
= literal
+ fmt
[i
]
53 elif fmt
[i
] == '"' and not escape
:
54 if state
== STATE_LITERAL
:
59 if state
== STATE_MACRO
:
60 bits
.append(c_macro_to_format(macro
))
62 elif fmt
[i
] == ' ' or fmt
[i
] == '\t':
63 if state
== STATE_MACRO
:
64 bits
.append(c_macro_to_format(macro
))
67 elif state
== STATE_LITERAL
:
68 literal
= literal
+ fmt
[i
]
71 if state
== STATE_SKIP
:
74 if state
== STATE_LITERAL
:
75 literal
= literal
+ fmt
[i
]
77 macro
= macro
+ fmt
[i
]
79 if state
== STATE_MACRO
:
80 bits
.append(c_macro_to_format(macro
))
81 elif state
== STATE_LITERAL
:
84 fmt
= re
.sub("%(\d*)z(x|u|d)", "%\\1\\2", "".join(bits
))
87 def generate(events
, backend
, group
):
88 out('/* This file is autogenerated by tracetool, do not edit. */',
91 for event_id
, e
in enumerate(events
):
92 if 'disable' in e
.properties
:
95 out('probe %(probeprefix)s.log.%(name)s = %(probeprefix)s.%(name)s ?',
97 probeprefix
=probeprefix(),
100 # Get references to userspace strings
101 for type_
, name
in e
.args
:
102 name
= stap_escape(name
)
105 ' arg%(name)s_str = %(name)s ? ' +
106 'user_string_n(%(name)s, 512) : "<null>"',
110 # Determine systemtap's view of variable names
111 fields
= ["pid()", "gettimeofday_ns()"]
112 for type_
, name
in e
.args
:
113 name
= stap_escape(name
)
115 fields
.append("arg" + name
+ "_str")
119 # Emit the entire record in a single SystemTap printf()
120 arg_str
= ', '.join(arg
for arg
in fields
)
121 fmt_str
= "%d@%d " + e
.name
+ " " + c_fmt_to_stap(e
.fmt
) + "\\n"
122 out(' printf("%(fmt_str)s", %(arg_str)s)',
123 fmt_str
=fmt_str
, arg_str
=arg_str
)