129b62a10SMarkus Armbruster /* 229b62a10SMarkus Armbruster * HMP commands related to tracing 329b62a10SMarkus Armbruster * 429b62a10SMarkus Armbruster * Copyright (c) 2003-2004 Fabrice Bellard 529b62a10SMarkus Armbruster * 629b62a10SMarkus Armbruster * Permission is hereby granted, free of charge, to any person obtaining a copy 729b62a10SMarkus Armbruster * of this software and associated documentation files (the "Software"), to deal 829b62a10SMarkus Armbruster * in the Software without restriction, including without limitation the rights 929b62a10SMarkus Armbruster * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 1029b62a10SMarkus Armbruster * copies of the Software, and to permit persons to whom the Software is 1129b62a10SMarkus Armbruster * furnished to do so, subject to the following conditions: 1229b62a10SMarkus Armbruster * 1329b62a10SMarkus Armbruster * The above copyright notice and this permission notice shall be included in 1429b62a10SMarkus Armbruster * all copies or substantial portions of the Software. 1529b62a10SMarkus Armbruster * 1629b62a10SMarkus Armbruster * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1729b62a10SMarkus Armbruster * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1829b62a10SMarkus Armbruster * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1929b62a10SMarkus Armbruster * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2029b62a10SMarkus Armbruster * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 2129b62a10SMarkus Armbruster * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 2229b62a10SMarkus Armbruster * THE SOFTWARE. 2329b62a10SMarkus Armbruster */ 2429b62a10SMarkus Armbruster 2529b62a10SMarkus Armbruster #include "qemu/osdep.h" 2629b62a10SMarkus Armbruster #include "monitor/hmp.h" 2729b62a10SMarkus Armbruster #include "monitor/monitor.h" 2829b62a10SMarkus Armbruster #include "qapi/error.h" 2929b62a10SMarkus Armbruster #include "qapi/qapi-commands-trace.h" 3029b62a10SMarkus Armbruster #include "qapi/qmp/qdict.h" 3129b62a10SMarkus Armbruster #include "trace/control.h" 3229b62a10SMarkus Armbruster #ifdef CONFIG_TRACE_SIMPLE 3329b62a10SMarkus Armbruster #include "trace/simple.h" 3429b62a10SMarkus Armbruster #endif 3529b62a10SMarkus Armbruster 3629b62a10SMarkus Armbruster void hmp_trace_event(Monitor *mon, const QDict *qdict) 3729b62a10SMarkus Armbruster { 3829b62a10SMarkus Armbruster const char *tp_name = qdict_get_str(qdict, "name"); 3929b62a10SMarkus Armbruster bool new_state = qdict_get_bool(qdict, "option"); 4029b62a10SMarkus Armbruster Error *local_err = NULL; 4129b62a10SMarkus Armbruster 4289aafcf2SAlex Bennée qmp_trace_event_set_state(tp_name, new_state, 43*7ffc4894SPhilippe Mathieu-Daudé true, true, &local_err); 4429b62a10SMarkus Armbruster if (local_err) { 4529b62a10SMarkus Armbruster error_report_err(local_err); 4629b62a10SMarkus Armbruster } 4729b62a10SMarkus Armbruster } 4829b62a10SMarkus Armbruster 4929b62a10SMarkus Armbruster #ifdef CONFIG_TRACE_SIMPLE 5029b62a10SMarkus Armbruster void hmp_trace_file(Monitor *mon, const QDict *qdict) 5129b62a10SMarkus Armbruster { 5229b62a10SMarkus Armbruster const char *op = qdict_get_try_str(qdict, "op"); 5329b62a10SMarkus Armbruster const char *arg = qdict_get_try_str(qdict, "arg"); 5429b62a10SMarkus Armbruster 5529b62a10SMarkus Armbruster if (!op) { 5629b62a10SMarkus Armbruster st_print_trace_file_status(); 5729b62a10SMarkus Armbruster } else if (!strcmp(op, "on")) { 5829b62a10SMarkus Armbruster st_set_trace_file_enabled(true); 5929b62a10SMarkus Armbruster } else if (!strcmp(op, "off")) { 6029b62a10SMarkus Armbruster st_set_trace_file_enabled(false); 6129b62a10SMarkus Armbruster } else if (!strcmp(op, "flush")) { 6229b62a10SMarkus Armbruster st_flush_trace_buffer(); 6329b62a10SMarkus Armbruster } else if (!strcmp(op, "set")) { 6429b62a10SMarkus Armbruster if (arg) { 6529b62a10SMarkus Armbruster st_set_trace_file(arg); 6629b62a10SMarkus Armbruster } 6729b62a10SMarkus Armbruster } else { 6829b62a10SMarkus Armbruster monitor_printf(mon, "unexpected argument \"%s\"\n", op); 6929b62a10SMarkus Armbruster hmp_help_cmd(mon, "trace-file"); 7029b62a10SMarkus Armbruster } 7129b62a10SMarkus Armbruster } 7229b62a10SMarkus Armbruster #endif 7329b62a10SMarkus Armbruster 7429b62a10SMarkus Armbruster void hmp_info_trace_events(Monitor *mon, const QDict *qdict) 7529b62a10SMarkus Armbruster { 7629b62a10SMarkus Armbruster const char *name = qdict_get_try_str(qdict, "name"); 7729b62a10SMarkus Armbruster TraceEventInfoList *events; 7829b62a10SMarkus Armbruster TraceEventInfoList *elem; 7929b62a10SMarkus Armbruster Error *local_err = NULL; 8029b62a10SMarkus Armbruster 8129b62a10SMarkus Armbruster if (name == NULL) { 8229b62a10SMarkus Armbruster name = "*"; 8329b62a10SMarkus Armbruster } 8429b62a10SMarkus Armbruster 85*7ffc4894SPhilippe Mathieu-Daudé events = qmp_trace_event_get_state(name, &local_err); 8629b62a10SMarkus Armbruster if (local_err) { 8729b62a10SMarkus Armbruster error_report_err(local_err); 8829b62a10SMarkus Armbruster return; 8929b62a10SMarkus Armbruster } 9029b62a10SMarkus Armbruster 9129b62a10SMarkus Armbruster for (elem = events; elem != NULL; elem = elem->next) { 9229b62a10SMarkus Armbruster monitor_printf(mon, "%s : state %u\n", 9329b62a10SMarkus Armbruster elem->value->name, 9429b62a10SMarkus Armbruster elem->value->state == TRACE_EVENT_STATE_ENABLED ? 1 : 0); 9529b62a10SMarkus Armbruster } 9629b62a10SMarkus Armbruster qapi_free_TraceEventInfoList(events); 9729b62a10SMarkus Armbruster } 9829b62a10SMarkus Armbruster 9929b62a10SMarkus Armbruster void info_trace_events_completion(ReadLineState *rs, int nb_args, const char *str) 10029b62a10SMarkus Armbruster { 10129b62a10SMarkus Armbruster size_t len; 10229b62a10SMarkus Armbruster 10329b62a10SMarkus Armbruster len = strlen(str); 10429b62a10SMarkus Armbruster readline_set_completion_index(rs, len); 10529b62a10SMarkus Armbruster if (nb_args == 2) { 10629b62a10SMarkus Armbruster TraceEventIter iter; 10729b62a10SMarkus Armbruster TraceEvent *ev; 10829b62a10SMarkus Armbruster char *pattern = g_strdup_printf("%s*", str); 10929b62a10SMarkus Armbruster trace_event_iter_init_pattern(&iter, pattern); 11029b62a10SMarkus Armbruster while ((ev = trace_event_iter_next(&iter)) != NULL) { 11129b62a10SMarkus Armbruster readline_add_completion(rs, trace_event_get_name(ev)); 11229b62a10SMarkus Armbruster } 11329b62a10SMarkus Armbruster g_free(pattern); 11429b62a10SMarkus Armbruster } 11529b62a10SMarkus Armbruster } 11629b62a10SMarkus Armbruster 11729b62a10SMarkus Armbruster void trace_event_completion(ReadLineState *rs, int nb_args, const char *str) 11829b62a10SMarkus Armbruster { 11929b62a10SMarkus Armbruster size_t len; 12029b62a10SMarkus Armbruster 12129b62a10SMarkus Armbruster len = strlen(str); 12229b62a10SMarkus Armbruster readline_set_completion_index(rs, len); 12329b62a10SMarkus Armbruster if (nb_args == 2) { 12429b62a10SMarkus Armbruster TraceEventIter iter; 12529b62a10SMarkus Armbruster TraceEvent *ev; 12629b62a10SMarkus Armbruster char *pattern = g_strdup_printf("%s*", str); 12729b62a10SMarkus Armbruster trace_event_iter_init_pattern(&iter, pattern); 12829b62a10SMarkus Armbruster while ((ev = trace_event_iter_next(&iter)) != NULL) { 12929b62a10SMarkus Armbruster readline_add_completion(rs, trace_event_get_name(ev)); 13029b62a10SMarkus Armbruster } 13129b62a10SMarkus Armbruster g_free(pattern); 13229b62a10SMarkus Armbruster } else if (nb_args == 3) { 13329b62a10SMarkus Armbruster readline_add_completion_of(rs, str, "on"); 13429b62a10SMarkus Armbruster readline_add_completion_of(rs, str, "off"); 13529b62a10SMarkus Armbruster } 13629b62a10SMarkus Armbruster } 137