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
))
59 elif fmt
[i
] == ' ' or fmt
[i
] == '\t':
60 if state
== STATE_MACRO
:
61 bits
.append(c_macro_to_format(macro
))
64 elif state
== STATE_LITERAL
:
65 literal
= literal
+ fmt
[i
]
68 if state
== STATE_SKIP
:
71 if state
== STATE_LITERAL
:
72 literal
= literal
+ fmt
[i
]
74 macro
= macro
+ fmt
[i
]
76 if state
== STATE_MACRO
:
77 bits
.append(c_macro_to_format(macro
))
78 elif state
== STATE_LITERAL
:
81 # All variables in systemtap are 64-bit in size
82 # The "%l" integer size qualifier is thus redundant
83 # and "%ll" is not valid at all. Similarly the size_t
84 # based "%z" size qualifier is not valid. We just
85 # strip all size qualifiers for sanity.
86 fmt
= re
.sub("%(\d*)(l+|z)(x|u|d)", "%\\1\\3", "".join(bits
))
89 def generate(events
, backend
, group
):
90 out('/* This file is autogenerated by tracetool, do not edit. */',
93 for event_id
, e
in enumerate(events
):
94 if 'disable' in e
.properties
:
97 out('probe %(probeprefix)s.log.%(name)s = %(probeprefix)s.%(name)s ?',
99 probeprefix
=probeprefix(),
102 # Get references to userspace strings
103 for type_
, name
in e
.args
:
104 name
= stap_escape(name
)
107 ' arg%(name)s_str = %(name)s ? ' +
108 'user_string_n(%(name)s, 512) : "<null>"',
112 # Determine systemtap's view of variable names
113 fields
= ["pid()", "gettimeofday_ns()"]
114 for type_
, name
in e
.args
:
115 name
= stap_escape(name
)
117 fields
.append("arg" + name
+ "_str")
121 # Emit the entire record in a single SystemTap printf()
122 arg_str
= ', '.join(arg
for arg
in fields
)
123 fmt_str
= "%d@%d " + e
.name
+ " " + c_fmt_to_stap(e
.fmt
) + "\\n"
124 out(' printf("%(fmt_str)s", %(arg_str)s)',
125 fmt_str
=fmt_str
, arg_str
=arg_str
)