mirror of https://gitee.com/openkylin/qemu.git
-----BEGIN PGP SIGNATURE-----
iQEcBAABAgAGBQJapqP6AAoJEJykq7OBq3PIZasIAL+NKBQGa/e0FD28PYdLU/JE sKZZ0O6+eVTCejGXap4bzbKOy+qZyOXvaRk5KNREc5A9R8HFBt5GotMfE80Cw9Nt rryX+qVdf4w27u2jMqY4215jD5jy/nPijRQ0a8UBsi6z2PXVPPNeS3lMB8RSFEZS IZu+l3j1op1wUlM4GfZvLCjmgHC+73lk6a5xZLJ2UvH9UoqJepgVZnSs2YvOctzG LVGMhk6/yAy4hh3NWx/M2h2B2ASMJJya8XrLgelAVnr6CxKBeBII0bSPur+1YIH7 OkJhNsk6QKSWNFKtzXE6N+y1ryWLnbE8vzKSZt+xSzUDjhnqTm5iFpZQ+Ed16qA= =nCAn -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/stefanha/tags/tracing-pull-request' into staging # gpg: Signature made Mon 12 Mar 2018 15:59:54 GMT # gpg: using RSA key 9CA4ABB381AB73C8 # gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" # gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>" # Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35 775A 9CA4 ABB3 81AB 73C8 * remotes/stefanha/tags/tracing-pull-request: trace: only permit standard C types and fixed size integer types trace: remove use of QEMU specific types from trace probes trace: include filename when printing parser error messages simpletrace: fix timestamp argument type log-for-trace.h: Split out parts of log.h used by trace.h Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
73988d529e
|
@ -0,0 +1,35 @@
|
|||
/* log-for-trace.h: logging basics required by the trace.h generated
|
||||
* by the log trace backend.
|
||||
*
|
||||
* This should not be included directly by any .c file: if you
|
||||
* need to use the logging functions include "qemu/log.h".
|
||||
*
|
||||
* The purpose of splitting these parts out into their own header
|
||||
* is to catch the easy mistake where a .c file includes trace.h
|
||||
* but forgets to include qemu/log.h. Without this split, that
|
||||
* would result in the .c file compiling fine when the default
|
||||
* trace backend is in use but failing to compile with any other
|
||||
* backend.
|
||||
*
|
||||
* This code is licensed under the GNU General Public License,
|
||||
* version 2 or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef QEMU_LOG_FOR_TRACE_H
|
||||
#define QEMU_LOG_FOR_TRACE_H
|
||||
|
||||
/* Private global variable, don't use */
|
||||
extern int qemu_loglevel;
|
||||
|
||||
#define LOG_TRACE (1 << 15)
|
||||
|
||||
/* Returns true if a bit is set in the current loglevel mask */
|
||||
static inline bool qemu_loglevel_mask(int mask)
|
||||
{
|
||||
return (qemu_loglevel & mask) != 0;
|
||||
}
|
||||
|
||||
/* main logging function */
|
||||
int GCC_FMT_ATTR(1, 2) qemu_log(const char *fmt, ...);
|
||||
|
||||
#endif
|
|
@ -1,10 +1,11 @@
|
|||
#ifndef QEMU_LOG_H
|
||||
#define QEMU_LOG_H
|
||||
|
||||
/* A small part of this API is split into its own header */
|
||||
#include "qemu/log-for-trace.h"
|
||||
|
||||
/* Private global variables, don't use */
|
||||
/* Private global variable, don't use */
|
||||
extern FILE *qemu_logfile;
|
||||
extern int qemu_loglevel;
|
||||
|
||||
/*
|
||||
* The new API:
|
||||
|
@ -41,16 +42,9 @@ static inline bool qemu_log_separate(void)
|
|||
#define CPU_LOG_MMU (1 << 12)
|
||||
#define CPU_LOG_TB_NOCHAIN (1 << 13)
|
||||
#define CPU_LOG_PAGE (1 << 14)
|
||||
#define LOG_TRACE (1 << 15)
|
||||
/* LOG_TRACE (1 << 15) is defined in log-for-trace.h */
|
||||
#define CPU_LOG_TB_OP_IND (1 << 16)
|
||||
|
||||
/* Returns true if a bit is set in the current loglevel mask
|
||||
*/
|
||||
static inline bool qemu_loglevel_mask(int mask)
|
||||
{
|
||||
return (qemu_loglevel & mask) != 0;
|
||||
}
|
||||
|
||||
/* Lock output for a series of related logs. Since this is not needed
|
||||
* for a single qemu_log / qemu_log_mask / qemu_log_mask_and_addr, we
|
||||
* assume that qemu_loglevel_mask has already been tested, and that
|
||||
|
@ -69,10 +63,6 @@ static inline void qemu_log_unlock(void)
|
|||
|
||||
/* Logging functions: */
|
||||
|
||||
/* main logging function
|
||||
*/
|
||||
int GCC_FMT_ATTR(1, 2) qemu_log(const char *fmt, ...);
|
||||
|
||||
/* vfprintf-like logging function
|
||||
*/
|
||||
static inline void GCC_FMT_ATTR(1, 0)
|
||||
|
|
|
@ -168,7 +168,7 @@ def end(self):
|
|||
def process(events, log, analyzer, read_header=True):
|
||||
"""Invoke an analyzer on each event in a log."""
|
||||
if isinstance(events, str):
|
||||
events = read_events(open(events, 'r'))
|
||||
events = read_events(open(events, 'r'), events)
|
||||
if isinstance(log, str):
|
||||
log = open(log, 'rb')
|
||||
|
||||
|
@ -199,7 +199,7 @@ def build_fn(analyzer, event):
|
|||
fn_argcount = len(inspect.getargspec(fn)[0]) - 1
|
||||
if fn_argcount == event_argcount + 1:
|
||||
# Include timestamp as first argument
|
||||
return lambda _, rec: fn(*((rec[1:2],) + rec[3:3 + event_argcount]))
|
||||
return lambda _, rec: fn(*(rec[1:2] + rec[3:3 + event_argcount]))
|
||||
elif fn_argcount == event_argcount + 2:
|
||||
# Include timestamp and pid
|
||||
return lambda _, rec: fn(*rec[1:3 + event_argcount])
|
||||
|
@ -233,7 +233,7 @@ def run(analyzer):
|
|||
'<trace-file>\n' % sys.argv[0])
|
||||
sys.exit(1)
|
||||
|
||||
events = read_events(open(sys.argv[1], 'r'))
|
||||
events = read_events(open(sys.argv[1], 'r'), sys.argv[1])
|
||||
process(events, sys.argv[2], analyzer, read_header=read_header)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -142,7 +142,7 @@ def main(args):
|
|||
events = []
|
||||
for arg in args:
|
||||
with open(arg, "r") as fh:
|
||||
events.extend(tracetool.read_events(fh))
|
||||
events.extend(tracetool.read_events(fh, arg))
|
||||
|
||||
try:
|
||||
tracetool.generate(events, arg_group, arg_format, arg_backends,
|
||||
|
|
|
@ -41,6 +41,51 @@ def out(*lines, **kwargs):
|
|||
lines = [ l % kwargs for l in lines ]
|
||||
sys.stdout.writelines("\n".join(lines) + "\n")
|
||||
|
||||
# We only want to allow standard C types or fixed sized
|
||||
# integer types. We don't want QEMU specific types
|
||||
# as we can't assume trace backends can resolve all the
|
||||
# typedefs
|
||||
ALLOWED_TYPES = [
|
||||
"int",
|
||||
"long",
|
||||
"short",
|
||||
"char",
|
||||
"bool",
|
||||
"unsigned",
|
||||
"signed",
|
||||
"float",
|
||||
"double",
|
||||
"int8_t",
|
||||
"uint8_t",
|
||||
"int16_t",
|
||||
"uint16_t",
|
||||
"int32_t",
|
||||
"uint32_t",
|
||||
"int64_t",
|
||||
"uint64_t",
|
||||
"void",
|
||||
"size_t",
|
||||
"ssize_t",
|
||||
"uintptr_t",
|
||||
"ptrdiff_t",
|
||||
# Magic substitution is done by tracetool
|
||||
"TCGv",
|
||||
]
|
||||
|
||||
def validate_type(name):
|
||||
bits = name.split(" ")
|
||||
for bit in bits:
|
||||
bit = re.sub("\*", "", bit)
|
||||
if bit == "":
|
||||
continue
|
||||
if bit == "const":
|
||||
continue
|
||||
if bit not in ALLOWED_TYPES:
|
||||
raise ValueError("Argument type '%s' is not in whitelist. "
|
||||
"Only standard C types and fixed size integer "
|
||||
"types should be used. struct, union, and "
|
||||
"other complex pointer types should be "
|
||||
"declared as 'void *'" % name)
|
||||
|
||||
class Arguments:
|
||||
"""Event arguments description."""
|
||||
|
@ -87,6 +132,7 @@ def build(arg_str):
|
|||
else:
|
||||
arg_type, identifier = arg.rsplit(None, 1)
|
||||
|
||||
validate_type(arg_type)
|
||||
res.append((arg_type, identifier))
|
||||
return Arguments(res)
|
||||
|
||||
|
@ -291,13 +337,15 @@ def transform(self, *trans):
|
|||
self)
|
||||
|
||||
|
||||
def read_events(fobj):
|
||||
def read_events(fobj, fname):
|
||||
"""Generate the output for the given (format, backends) pair.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
fobj : file
|
||||
Event description file.
|
||||
fname : str
|
||||
Name of event file
|
||||
|
||||
Returns a list of Event objects
|
||||
"""
|
||||
|
@ -312,7 +360,7 @@ def read_events(fobj):
|
|||
try:
|
||||
event = Event.build(line)
|
||||
except ValueError as e:
|
||||
arg0 = 'Error on line %d: %s' % (lineno, e.args[0])
|
||||
arg0 = 'Error at %s:%d: %s' % (fname, lineno, e.args[0])
|
||||
e.args = (arg0,) + e.args[1:]
|
||||
raise
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
|
||||
def generate_h_begin(events, group):
|
||||
out('#include "qemu/log.h"',
|
||||
out('#include "qemu/log-for-trace.h"',
|
||||
'')
|
||||
|
||||
|
||||
|
@ -35,11 +35,10 @@ def generate_h(event, group):
|
|||
else:
|
||||
cond = "trace_event_get_state(%s)" % ("TRACE_" + event.name.upper())
|
||||
|
||||
out(' if (%(cond)s) {',
|
||||
out(' if (%(cond)s && qemu_loglevel_mask(LOG_TRACE)) {',
|
||||
' struct timeval _now;',
|
||||
' gettimeofday(&_now, NULL);',
|
||||
' qemu_log_mask(LOG_TRACE,',
|
||||
' "%%d@%%zd.%%06zd:%(name)s " %(fmt)s "\\n",',
|
||||
' qemu_log("%%d@%%zd.%%06zd:%(name)s " %(fmt)s "\\n",',
|
||||
' getpid(),',
|
||||
' (size_t)_now.tv_sec, (size_t)_now.tv_usec',
|
||||
' %(argnames)s);',
|
||||
|
|
|
@ -68,9 +68,9 @@ memory_region_tb_read(int cpu_index, uint64_t addr, uint64_t value, unsigned siz
|
|||
memory_region_tb_write(int cpu_index, uint64_t addr, uint64_t value, unsigned size) "cpu %d addr 0x%"PRIx64" value 0x%"PRIx64" size %u"
|
||||
memory_region_ram_device_read(int cpu_index, void *mr, uint64_t addr, uint64_t value, unsigned size) "cpu %d mr %p addr 0x%"PRIx64" value 0x%"PRIx64" size %u"
|
||||
memory_region_ram_device_write(int cpu_index, void *mr, uint64_t addr, uint64_t value, unsigned size) "cpu %d mr %p addr 0x%"PRIx64" value 0x%"PRIx64" size %u"
|
||||
flatview_new(FlatView *view, MemoryRegion *root) "%p (root %p)"
|
||||
flatview_destroy(FlatView *view, MemoryRegion *root) "%p (root %p)"
|
||||
flatview_destroy_rcu(FlatView *view, MemoryRegion *root) "%p (root %p)"
|
||||
flatview_new(void *view, void *root) "%p (root %p)"
|
||||
flatview_destroy(void *view, void *root) "%p (root %p)"
|
||||
flatview_destroy_rcu(void *view, void *root) "%p (root %p)"
|
||||
|
||||
# gdbstub.c
|
||||
gdbstub_op_start(const char *device) "Starting gdbstub using device %s"
|
||||
|
|
Loading…
Reference in New Issue