From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-dy1-f201.google.com (mail-dy1-f201.google.com [74.125.82.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F022F313523 for ; Mon, 20 Apr 2026 00:01:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776643294; cv=none; b=cgaTZG0WwKAIqNwBG9mCYJuNge/yxt2/FKXI0rN34SwHVPH08NLSjzzZ5AYXKD0NFN4cuWnClPwe0dtfUxNYMj4BWsyZIHJJTpeRX5U+4GaoqvDQYE6awnW6DC/Yzi3y1LHz3KQTJe9AlVYcElPb5KrKlJfgPEvHHvL2kwbz72M= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776643294; c=relaxed/simple; bh=zXqSf2X01xHehkOtz9vQuDMcSRKFKVgSiDTYKicD8zw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Xj1ldcnSAkGinhmwc171Fa3U/DvuaGgSOEMuNLDoFo8DVHOktNBQGAzW0r0mpoT6FmV14i+iMsqutL+lF1lPOR5SaqgVLvJzXFp7ynFbi+tdWO4EZuYxNI63Hr1U4VQX1LqmBL17xplM8TQZHQxNSfZHUrmy7GuSlhCwpyS+NeA= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=qCA03TgA; arc=none smtp.client-ip=74.125.82.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="qCA03TgA" Received: by mail-dy1-f201.google.com with SMTP id 5a478bee46e88-2ba9a744f7dso3051863eec.0 for ; Sun, 19 Apr 2026 17:01:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1776643290; x=1777248090; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=7/jxayaTvBUn04jWydsb4VhIa5ntm4OV2aHE0raxfFM=; b=qCA03TgAYjWplcodKSJhp+LgG4XDMpYm1dabBeNpPqZzzi9b8CjJAYI9F1aJbtv3Uv wGs3nfX2bo8c+hL+9MJwB6VDr9LgLIW16qQa2uOEYH7kzfFfFLfqX2CXt8xlxTmEQd9b AtHGP3MXSbkYw/DpMTsg1PCyyYkENIQRmuX2OiADq1HK6645KFmxCvyH6cEQ3idQdO/T qtKNVKQzLVmqUQii8W8lb/00uXF18raS5uoDrGRQq9rJBmRh2HmUuvZBG4gC4mnmLyWh gcr2NCBfTmQsnRFDnzFQ/OsjrAr0e9GO2Ur22UV9atJiBGP+cSAr8ab4m5fjqLzEt3WV to9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776643290; x=1777248090; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=7/jxayaTvBUn04jWydsb4VhIa5ntm4OV2aHE0raxfFM=; b=HkUpPWkR8LtgCx7uvk9U+oPKiWdqTPH3jhmpzJPKCUvjkwnVUkdyE8aFrl9/ssQs+Y 2WLz3ZCEIN/mXoUQJIWR31KKWF3sC0E68rrJOnX09NUUhCK4gzieSgR27n8dvT0eXC2S iulKTLt12beaq0e0VKCCdyHq2Pa1Oaw5Z4YQLZeK+xbjjOiSKLijSiwK7jVwqOhByK0n +IqRf6bx4VshKCu4gKNdKw6nDrMWt8gwx7Uqewhj0k13z00GAN4emtwMOZake9Ql5ly4 uGZHINmk88ggjpOZzLRxktIUHDGuEKlFokR8euYCVzcCe0qIUuVmAin/U2viZGpgLsvv I29g== X-Forwarded-Encrypted: i=1; AFNElJ+uW1ylTBZPJylmmuRoy6uFgmnl+Py9WcZU+zVDHlCd4X5pGIiwM4rArmITxKYZQCcMU/zl8ssbLIddakxZYNKW@vger.kernel.org X-Gm-Message-State: AOJu0YxPIN4NgrT6k0k9UpufQhMsbUwcbxoq/EmHpUyK6GJOz1K760SC 7/2J8VID8EKC5z9sQGJx7PIhTPWacahgEyixtg+tr44mYe53cCbyi429OrQfwz9c2zk2zrDxJMd y4CdpNwACiw== X-Received: from dyer22.prod.google.com ([2002:a05:7300:2316:b0:2d9:e328:e0db]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7300:e60d:b0:2be:833c:149d with SMTP id 5a478bee46e88-2e479110f8fmr6270578eec.28.1776643289915; Sun, 19 Apr 2026 17:01:29 -0700 (PDT) Date: Sun, 19 Apr 2026 16:59:08 -0700 In-Reply-To: <20260419235911.2186050-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-perf-users@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260419235911.2186050-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.rc1.513.gad8abe7a5a-goog Message-ID: <20260419235911.2186050-57-irogers@google.com> Subject: [PATCH v1 56/58] perf script: Refactor to support standalone scripts and remove legacy features From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Adrian Hunter , James Clark , Alice Rogers , Suzuki K Poulose , Mike Leach , John Garry , Leo Yan , Yicong Yang , Jonathan Cameron , Nick Terrell , David Sterba , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , Alexandre Chartre , Dmitrii Dolgov <9erthalion6@gmail.com>, Yuzhuo Jing , Blake Jones , Changbin Du , Gautam Menghani , Wangyang Guo , Pan Deng , Zhiguo Zhou , Tianyou Li , Thomas Falcon , Athira Rajeev , Collin Funk , Dapeng Mi , Ravi Bangoria , Zecheng Li , tanze , Thomas Richter , Ankur Arora , "Tycho Andersen (AMD)" , Howard Chu , Sun Jian , Derek Foreman , Swapnil Sapkal , Anubhav Shelat , Ricky Ringler , Qinxin Xia , Aditya Bodkhe , Chun-Tse Shao , Stephen Brennan , Yang Li , Chuck Lever , Chen Ni , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org Cc: Ian Rogers Content-Type: text/plain; charset="UTF-8" - Remove -g / --gen-script option as it is no longer needed. - Hide -s / --script option to imply running standalone scripts directly. - Update find_script to search in 'python' instead of 'scripts/python'. - Add support for launching standalone scripts using fork and execvp, skipping the event processing loop. - Update list_available_scripts to look for .py files directly in 'python' directory. - Remove all references to scripting_ops and clean up unused functions and variables. Assisted-by: Gemini:gemini-3.1-pro-preview Signed-off-by: Ian Rogers --- tools/perf/builtin-script.c | 746 +++++++++--------------- tools/perf/util/Build | 1 - tools/perf/util/scripting-engines/Build | 1 - tools/perf/util/trace-event-parse.c | 65 --- tools/perf/util/trace-event-scripting.c | 333 ----------- tools/perf/util/trace-event.h | 75 +-- 6 files changed, 280 insertions(+), 941 deletions(-) delete mode 100644 tools/perf/util/scripting-engines/Build delete mode 100644 tools/perf/util/trace-event-scripting.c diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index c0949556d1bb..8d8bfbd321f4 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -77,7 +78,6 @@ #endif static char const *script_name; -static char const *generate_script_lang; static bool reltime; static bool deltatime; static u64 initial_time; @@ -95,6 +95,7 @@ static int max_blocks; static struct dlfilter *dlfilter; static int dlargc; static char **dlargv; +static unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH; enum perf_output_field { PERF_OUTPUT_COMM = 1ULL << 0, @@ -1730,6 +1731,143 @@ static int perf_sample__fprintf_bts(struct perf_sample *sample, return printed; } +#define SAMPLE_FLAGS_BUF_SIZE 64 +#define SAMPLE_FLAGS_STR_ALIGNED_SIZE 21 + +static int sample_flags_to_name(u32 flags, char *str, size_t size) +{ + static const struct { + u32 flags; + const char *name; + } sample_flags[] = { + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL, "call"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN, "return"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CONDITIONAL, "jcc"}, + {PERF_IP_FLAG_BRANCH, "jmp"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_INTERRUPT, "int"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_INTERRUPT, "iret"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_SYSCALLRET, "syscall"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_SYSCALLRET, "sysret"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_ASYNC, "async"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC | PERF_IP_FLAG_INTERRUPT, + "hw int"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TX_ABORT, "tx abrt"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_BEGIN, "tr strt"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_END, "tr end"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_VMENTRY, "vmentry"}, + {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_VMEXIT, "vmexit"}, + {0, NULL} + }; + static const struct { + u32 flags; + const char *name; + } branch_events[] = { + {PERF_IP_FLAG_BRANCH_MISS, "miss"}, + {PERF_IP_FLAG_NOT_TAKEN, "not_taken"}, + {0, NULL} + }; + int i; + const char *prefix; + int pos = 0, ret, ev_idx = 0; + u32 xf = flags & PERF_ADDITIONAL_STATE_MASK; + u32 types, events; + char xs[16] = { 0 }; + + /* Clear additional state bits */ + flags &= ~PERF_ADDITIONAL_STATE_MASK; + + if (flags & PERF_IP_FLAG_TRACE_BEGIN) + prefix = "tr strt "; + else if (flags & PERF_IP_FLAG_TRACE_END) + prefix = "tr end "; + else + prefix = ""; + + ret = snprintf(str + pos, size - pos, "%s", prefix); + if (ret < 0) + return ret; + pos += ret; + + flags &= ~(PERF_IP_FLAG_TRACE_BEGIN | PERF_IP_FLAG_TRACE_END); + + types = flags & ~PERF_IP_FLAG_BRANCH_EVENT_MASK; + for (i = 0; sample_flags[i].name; i++) { + if (sample_flags[i].flags != types) + continue; + + ret = snprintf(str + pos, size - pos, "%s", sample_flags[i].name); + if (ret < 0) + return ret; + pos += ret; + break; + } + + events = flags & PERF_IP_FLAG_BRANCH_EVENT_MASK; + for (i = 0; branch_events[i].name; i++) { + if (!(branch_events[i].flags & events)) + continue; + + ret = snprintf(str + pos, size - pos, !ev_idx ? "/%s" : ",%s", + branch_events[i].name); + if (ret < 0) + return ret; + pos += ret; + ev_idx++; + } + + /* Add an end character '/' for events */ + if (ev_idx) { + ret = snprintf(str + pos, size - pos, "/"); + if (ret < 0) + return ret; + pos += ret; + } + + if (!xf) + return pos; + + snprintf(xs, sizeof(xs), "(%s%s%s)", + flags & PERF_IP_FLAG_IN_TX ? "x" : "", + flags & PERF_IP_FLAG_INTR_DISABLE ? "D" : "", + flags & PERF_IP_FLAG_INTR_TOGGLE ? "t" : ""); + + /* Right align the string if its length is less than the limit */ + if ((pos + strlen(xs)) < SAMPLE_FLAGS_STR_ALIGNED_SIZE) + ret = snprintf(str + pos, size - pos, "%*s", + (int)(SAMPLE_FLAGS_STR_ALIGNED_SIZE - ret), xs); + else + ret = snprintf(str + pos, size - pos, " %s", xs); + if (ret < 0) + return ret; + + return pos + ret; +} + +static int perf_sample__sprintf_flags(u32 flags, char *str, size_t sz) +{ + const char *chars = PERF_IP_FLAG_CHARS; + const size_t n = strlen(PERF_IP_FLAG_CHARS); + size_t i, pos = 0; + int ret; + + ret = sample_flags_to_name(flags, str, sz); + if (ret > 0) + return ret; + + for (i = 0; i < n; i++, flags >>= 1) { + if ((flags & 1) && pos < sz) + str[pos++] = chars[i]; + } + for (; i < 32; i++, flags >>= 1) { + if ((flags & 1) && pos < sz) + str[pos++] = '?'; + } + if (pos < sz) + str[pos] = 0; + + return pos; +} + static int perf_sample__fprintf_flags(u32 flags, FILE *fp) { char str[SAMPLE_FLAGS_BUF_SIZE]; @@ -2571,8 +2709,6 @@ static void process_event(struct perf_script *script, fflush(fp); } -static struct scripting_ops *scripting_ops; - static void __process_stat(struct evsel *counter, u64 tstamp) { int nthreads = perf_thread_map__nr(counter->core.threads); @@ -2607,35 +2743,14 @@ static void __process_stat(struct evsel *counter, u64 tstamp) static void process_stat(struct evsel *counter, u64 tstamp) { - if (scripting_ops && scripting_ops->process_stat) - scripting_ops->process_stat(&stat_config, counter, tstamp); - else - __process_stat(counter, tstamp); -} - -static void process_stat_interval(u64 tstamp) -{ - if (scripting_ops && scripting_ops->process_stat_interval) - scripting_ops->process_stat_interval(tstamp); -} - -static void setup_scripting(void) -{ - - setup_python_scripting(); + __process_stat(counter, tstamp); } -static int flush_scripting(void) +static void process_stat_interval(u64 tstamp __maybe_unused) { - return scripting_ops ? scripting_ops->flush_script() : 0; } -static int cleanup_scripting(void) -{ - pr_debug("\nperf script stopped\n"); - return scripting_ops ? scripting_ops->stop_script() : 0; -} static bool filter_cpu(struct perf_sample *sample) { @@ -2708,19 +2823,7 @@ static int process_sample_event(const struct perf_tool *tool, goto out_put; } - if (scripting_ops) { - struct addr_location *addr_al_ptr = NULL; - - if ((evsel->core.attr.sample_type & PERF_SAMPLE_ADDR) && - sample_addr_correlates_sym(&evsel->core.attr)) { - if (!addr_al.thread) - thread__resolve(al.thread, &addr_al, sample); - addr_al_ptr = &addr_al; - } - scripting_ops->process_event(event, sample, evsel, &al, addr_al_ptr); - } else { - process_event(scr, sample, evsel, &al, &addr_al, machine); - } + process_event(scr, sample, evsel, &al, &addr_al, machine); out_put: addr_location__exit(&addr_al); @@ -3029,8 +3132,7 @@ static int process_switch_event(const struct perf_tool *tool, if (perf_event__process_switch(tool, event, sample, machine) < 0) return -1; - if (scripting_ops && scripting_ops->process_switch && !filter_cpu(sample)) - scripting_ops->process_switch(event, sample, machine); + if (!script->show_switch_events) return 0; @@ -3039,17 +3141,7 @@ static int process_switch_event(const struct perf_tool *tool, sample->tid); } -static int process_auxtrace_error(const struct perf_tool *tool, - struct perf_session *session, - union perf_event *event) -{ - if (scripting_ops && scripting_ops->process_auxtrace_error) { - scripting_ops->process_auxtrace_error(session, event); - return 0; - } - return perf_event__process_auxtrace_error(tool, session, event); -} static int process_lost_event(const struct perf_tool *tool, @@ -3063,12 +3155,11 @@ process_lost_event(const struct perf_tool *tool, static int process_throttle_event(const struct perf_tool *tool __maybe_unused, - union perf_event *event, - struct perf_sample *sample, - struct machine *machine) + union perf_event *event __maybe_unused, + struct perf_sample *sample __maybe_unused, + struct machine *machine __maybe_unused) { - if (scripting_ops && scripting_ops->process_throttle) - scripting_ops->process_throttle(event, sample, machine); + return 0; } @@ -3211,10 +3302,9 @@ static int __cmd_script(struct perf_script *script) script->tool.mmap = process_mmap_event; script->tool.mmap2 = process_mmap2_event; } - if (script->show_switch_events || (scripting_ops && scripting_ops->process_switch)) + if (script->show_switch_events) script->tool.context_switch = process_switch_event; - if (scripting_ops && scripting_ops->process_auxtrace_error) - script->tool.auxtrace_error = process_auxtrace_error; + script->tool.auxtrace_error = perf_event__process_auxtrace_error; if (script->show_namespace_events) script->tool.namespaces = process_namespaces_event; if (script->show_cgroup_events) @@ -3251,96 +3341,47 @@ static int __cmd_script(struct perf_script *script) return ret; } -static int list_available_languages_cb(struct scripting_ops *ops, const char *spec) -{ - fprintf(stderr, " %-42s [%s]\n", spec, ops->name); - return 0; -} -static void list_available_languages(void) -{ - fprintf(stderr, "\n"); - fprintf(stderr, "Scripting language extensions (used in " - "perf script -s [spec:]script.[spec]):\n\n"); - script_spec__for_each(&list_available_languages_cb); - fprintf(stderr, "\n"); -} /* Find script file relative to current directory or exec path */ static char *find_script(const char *script) { char path[PATH_MAX]; + char *exec_path; - if (!scripting_ops) { - const char *ext = strrchr(script, '.'); + if (access(script, R_OK) == 0) + goto found; - if (!ext) - return NULL; + exec_path = get_argv_exec_path(); + if (!exec_path) + return NULL; - scripting_ops = script_spec__lookup(++ext); - if (!scripting_ops) - return NULL; - } + snprintf(path, sizeof(path), "%s/python/%s", exec_path, script); + free(exec_path); + script = path; - if (access(script, R_OK)) { - char *exec_path = get_argv_exec_path(); + if (access(path, R_OK) == 0) + goto found; - if (!exec_path) - return NULL; - snprintf(path, sizeof(path), "%s/scripts/%s/%s", - exec_path, scripting_ops->dirname, script); - free(exec_path); - script = path; - if (access(script, R_OK)) - return NULL; - } + /* Try with .py suffix. */ + strncat(path, ".py", sizeof(path) - 1); + + if (access(script, R_OK) == 0) + goto found; + + /* Failure to find script. */ + return NULL; + +found: return strdup(script); } static int parse_scriptname(const struct option *opt __maybe_unused, const char *str, int unset __maybe_unused) { - char spec[PATH_MAX]; - const char *script, *ext; - int len; - - if (strcmp(str, "lang") == 0) { - list_available_languages(); - exit(0); - } - - script = strchr(str, ':'); - if (script) { - len = script - str; - if (len >= PATH_MAX) { - fprintf(stderr, "invalid language specifier"); - return -1; - } - strncpy(spec, str, len); - spec[len] = '\0'; - scripting_ops = script_spec__lookup(spec); - if (!scripting_ops) { - fprintf(stderr, "invalid language specifier"); - return -1; - } - script++; - } else { - script = str; - ext = strrchr(script, '.'); - if (!ext) { - fprintf(stderr, "invalid script extension"); - return -1; - } - scripting_ops = script_spec__lookup(++ext); - if (!scripting_ops) { - fprintf(stderr, "invalid script extension"); - return -1; - } - } - - script_name = find_script(script); + script_name = find_script(str); if (!script_name) - script_name = strdup(script); + script_name = strdup(str); return 0; } @@ -3551,16 +3592,18 @@ static struct script_desc *script_desc__new(const char *name) return s; } -static void script_desc__delete(struct script_desc *s) -{ - zfree(&s->name); - zfree(&s->half_liner); - zfree(&s->args); - free(s); -} + static void script_desc__add(struct script_desc *s) { + struct script_desc *pos; + + list_for_each_entry(pos, &script_descs, node) { + if (strcasecmp(s->name, pos->name) < 0) { + list_add_tail(&s->node, &pos->node); + return; + } + } list_add_tail(&s->node, &script_descs); } @@ -3608,15 +3651,59 @@ static int read_script_info(struct script_desc *desc, const char *filename) { char line[BUFSIZ], *p; FILE *fp; + bool in_docstring = false; + bool found_description = false; fp = fopen(filename, "r"); if (!fp) return -1; while (fgets(line, sizeof(line), fp)) { + static const char * const triple_quote_str[] = { + "\"\"\"", + "'''", + "r\"\"\"", + }; p = skip_spaces(line); if (strlen(p) == 0) continue; + + if (in_docstring) { + if (strlen(p) && p[strlen(p) - 1] == '\n') + p[strlen(p) - 1] = '\0'; + desc->half_liner = strdup(skip_spaces(p)); + in_docstring = false; + found_description = true; + break; + } + + + for (size_t i = 0; i < ARRAY_SIZE(triple_quote_str); i++) { + const char *quote = triple_quote_str[i]; + + if (!strstarts(p, quote)) + continue; + + p += strlen(quote); + p = skip_spaces(p); + if (strlen(p) > 0) { + if (p[strlen(p) - 1] == '\n') + p[strlen(p) - 1] = '\0'; + p = skip_spaces(p); + if (str_ends_with(p, quote)) + p[strlen(p) - strlen(quote)] = '\0'; + desc->half_liner = strdup(skip_spaces(p)); + found_description = true; + break; + } + in_docstring = true; + break; + } + if (found_description) + break; + if (in_docstring) + continue; + if (*p != '#') continue; p++; @@ -3630,13 +3717,15 @@ static int read_script_info(struct script_desc *desc, const char *filename) if (!strncmp(p, "description:", strlen("description:"))) { p += strlen("description:"); desc->half_liner = strdup(skip_spaces(p)); - continue; + found_description = true; + break; } - if (!strncmp(p, "args:", strlen("args:"))) { - p += strlen("args:"); - desc->args = strdup(skip_spaces(p)); - continue; + if (!found_description && strlen(p) > 0 && + strncmp(p, "SPDX-License-Identifier", 23)) { + desc->half_liner = strdup(p); + found_description = true; + // Don't break, maybe we find a better "description:" later! } } @@ -3667,9 +3756,9 @@ static int list_available_scripts(const struct option *opt __maybe_unused, const char *s __maybe_unused, int unset __maybe_unused) { - struct dirent *script_dirent, *lang_dirent; - char *buf, *scripts_path, *script_path, *lang_path, *first_half; - DIR *scripts_dir, *lang_dir; + struct dirent *script_dirent; + char *buf, *scripts_path, *script_path, *first_half; + DIR *scripts_dir; struct script_desc *desc; char *script_root; @@ -3680,10 +3769,9 @@ static int list_available_scripts(const struct option *opt __maybe_unused, } scripts_path = buf; script_path = buf + MAXPATHLEN; - lang_path = buf + 2 * MAXPATHLEN; first_half = buf + 3 * MAXPATHLEN; - snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path()); + snprintf(scripts_path, MAXPATHLEN, "%s/python", get_argv_exec_path()); scripts_dir = opendir(scripts_path); if (!scripts_dir) { @@ -3695,26 +3783,24 @@ static int list_available_scripts(const struct option *opt __maybe_unused, exit(-1); } - for_each_lang(scripts_path, scripts_dir, lang_dirent) { - scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, - lang_dirent->d_name); - lang_dir = opendir(lang_path); - if (!lang_dir) - continue; + while ((script_dirent = readdir(scripts_dir)) != NULL) { + if (script_dirent->d_type != DT_DIR && + (script_dirent->d_type != DT_UNKNOWN || + !is_directory(scripts_path, script_dirent))) { - for_each_script(lang_path, lang_dir, script_dirent) { - script_root = get_script_root(script_dirent, REPORT_SUFFIX); + script_root = get_script_root(script_dirent, ".py"); if (script_root) { desc = script_desc__findnew(script_root); scnprintf(script_path, MAXPATHLEN, "%s/%s", - lang_path, script_dirent->d_name); + scripts_path, script_dirent->d_name); read_script_info(desc, script_path); free(script_root); } } } + closedir(scripts_dir); - fprintf(stdout, "List of available trace scripts:\n"); + fprintf(stdout, "List of available scripts:\n"); list_for_each_entry(desc, &script_descs, node) { sprintf(first_half, "%s %s", desc->name, desc->args ? desc->args : ""); @@ -3754,93 +3840,7 @@ static void free_dlarg(void) free(dlargv); } -static char *get_script_path(const char *script_root, const char *suffix) -{ - struct dirent *script_dirent, *lang_dirent; - char scripts_path[MAXPATHLEN]; - char script_path[MAXPATHLEN]; - DIR *scripts_dir, *lang_dir; - char lang_path[MAXPATHLEN]; - char *__script_root; - - snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path()); - - scripts_dir = opendir(scripts_path); - if (!scripts_dir) - return NULL; - - for_each_lang(scripts_path, scripts_dir, lang_dirent) { - scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, - lang_dirent->d_name); - lang_dir = opendir(lang_path); - if (!lang_dir) - continue; - for_each_script(lang_path, lang_dir, script_dirent) { - __script_root = get_script_root(script_dirent, suffix); - if (__script_root && !strcmp(script_root, __script_root)) { - free(__script_root); - closedir(scripts_dir); - scnprintf(script_path, MAXPATHLEN, "%s/%s", - lang_path, script_dirent->d_name); - closedir(lang_dir); - return strdup(script_path); - } - free(__script_root); - } - closedir(lang_dir); - } - closedir(scripts_dir); - - return NULL; -} - -static bool is_top_script(const char *script_path) -{ - return ends_with(script_path, "top") != NULL; -} - -static int has_required_arg(char *script_path) -{ - struct script_desc *desc; - int n_args = 0; - char *p; - - desc = script_desc__new(NULL); - - if (read_script_info(desc, script_path)) - goto out; - - if (!desc->args) - goto out; - - for (p = desc->args; *p; p++) - if (*p == '<') - n_args++; -out: - script_desc__delete(desc); - - return n_args; -} - -static int have_cmd(int argc, const char **argv) -{ - char **__argv = calloc(argc, sizeof(const char *)); - - if (!__argv) { - pr_err("malloc failed\n"); - return -1; - } - - memcpy(__argv, argv, sizeof(const char *) * argc); - argc = parse_options(argc, (const char **)__argv, record_options, - NULL, PARSE_OPT_STOP_AT_NON_OPTION); - free(__argv); - - system_wide = (argc == 0); - - return 0; -} static void script__setup_sample_type(struct perf_script *script) { @@ -4026,17 +4026,13 @@ int cmd_script(int argc, const char **argv) bool show_full_info = false; bool header = false; bool header_only = false; - bool script_started = false; bool unsorted_dump = false; bool merge_deferred_callchains = true; - char *rec_script_path = NULL; - char *rep_script_path = NULL; struct perf_session *session; struct itrace_synth_opts itrace_synth_opts = { .set = false, .default_no_sample = true, }; - char *script_path = NULL; const char *dlfilter_file = NULL; const char **__argv; int i, j, err = 0; @@ -4057,11 +4053,10 @@ int cmd_script(int argc, const char **argv) list_available_scripts), OPT_CALLBACK_NOOPT(0, "list-dlfilters", NULL, NULL, "list available dlfilters", list_available_dlfilters), - OPT_CALLBACK('s', "script", NULL, "name", - "script file name (lang:script name, script name, or *)", - parse_scriptname), - OPT_STRING('g', "gen-script", &generate_script_lang, "lang", - "generate perf-script.xx script in specified language"), + { .type = OPTION_CALLBACK, .short_name = 's', .long_name = "script", + .value = NULL, .argh = "name", + .help = "script file name (lang:script name, script name, or *)", + .callback = parse_scriptname, .flags = PARSE_OPT_HIDDEN }, OPT_STRING(0, "dlfilter", &dlfilter_file, "file", "filter .so file name"), OPT_CALLBACK(0, "dlarg", NULL, "argument", "filter argument", add_dlarg), @@ -4198,7 +4193,6 @@ int cmd_script(int argc, const char **argv) perf_set_singlethreaded(); - setup_scripting(); argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage, PARSE_OPT_STOP_AT_NON_OPTION); @@ -4223,21 +4217,7 @@ int cmd_script(int argc, const char **argv) if (symbol__validate_sym_arguments()) return -1; - if (argc > 1 && strlen(argv[0]) > 2 && strstarts("record", argv[0])) { - rec_script_path = get_script_path(argv[1], RECORD_SUFFIX); - if (!rec_script_path) - return cmd_record(argc, argv); - } - if (argc > 1 && strlen(argv[0]) > 2 && strstarts("report", argv[0])) { - rep_script_path = get_script_path(argv[1], REPORT_SUFFIX); - if (!rep_script_path) { - fprintf(stderr, - "Please specify a valid report script" - "(see 'perf script -l' for listing)\n"); - return -1; - } - } if (reltime && deltatime) { fprintf(stderr, @@ -4253,149 +4233,49 @@ int cmd_script(int argc, const char **argv) /* make sure PERF_EXEC_PATH is set for scripts */ set_argv_exec_path(get_argv_exec_path()); - if (argc && !script_name && !rec_script_path && !rep_script_path) { - int live_pipe[2]; - int rep_args; - pid_t pid; - - rec_script_path = get_script_path(argv[0], RECORD_SUFFIX); - rep_script_path = get_script_path(argv[0], REPORT_SUFFIX); - - if (!rec_script_path && !rep_script_path) { - script_name = find_script(argv[0]); - if (script_name) { - argc -= 1; - argv += 1; - goto script_found; - } - usage_with_options_msg(script_usage, options, - "Couldn't find script `%s'\n\n See perf" - " script -l for available scripts.\n", argv[0]); - } - - if (is_top_script(argv[0])) { - rep_args = argc - 1; - } else { - int rec_args; - - rep_args = has_required_arg(rep_script_path); - rec_args = (argc - 1) - rep_args; - if (rec_args < 0) { - usage_with_options_msg(script_usage, options, - "`%s' script requires options." - "\n\n See perf script -l for available " - "scripts and options.\n", argv[0]); - } + if (argc && !script_name) { + script_name = find_script(argv[0]); + if (script_name) { + argc -= 1; + argv += 1; + goto script_found; } + usage_with_options_msg(script_usage, options, + "Couldn't find script `%s'\n\n" + " See perf script -l for available scripts.\n", argv[0]); + } +script_found: - if (pipe(live_pipe) < 0) { - perror("failed to create pipe"); - return -1; - } - pid = fork(); + if (script_name) { + pid_t pid = fork(); if (pid < 0) { - perror("failed to fork"); - return -1; + pr_err("failed to fork\n"); + return -errno; } - - if (!pid) { + if (pid == 0) { /* child */ + __argv = calloc(argc + 2, sizeof(const char *)); j = 0; - - dup2(live_pipe[1], 1); - close(live_pipe[0]); - - if (is_top_script(argv[0])) { - system_wide = true; - } else if (!system_wide) { - if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) { - err = -1; - goto out; - } - } - - __argv = calloc(argc + 6, sizeof(const char *)); if (!__argv) { - pr_err("malloc failed\n"); - err = -ENOMEM; - goto out; + exit(-ENOMEM); } - - __argv[j++] = "/bin/sh"; - __argv[j++] = rec_script_path; - if (system_wide) - __argv[j++] = "-a"; - __argv[j++] = "-q"; - __argv[j++] = "-o"; - __argv[j++] = "-"; - for (i = rep_args + 1; i < argc; i++) + __argv[j++] = script_name; + for (i = 0; i < argc; i++) __argv[j++] = argv[i]; __argv[j++] = NULL; - execvp("/bin/sh", (char **)__argv); - free(__argv); - exit(-1); - } - - dup2(live_pipe[0], 0); - close(live_pipe[1]); - - __argv = calloc(argc + 4, sizeof(const char *)); - if (!__argv) { - pr_err("malloc failed\n"); - err = -ENOMEM; - goto out; - } + execvp(script_name, (char **)__argv); + exit(-errno); + } else { /* parent */ + int status; - j = 0; - __argv[j++] = "/bin/sh"; - __argv[j++] = rep_script_path; - for (i = 1; i < rep_args + 1; i++) - __argv[j++] = argv[i]; - __argv[j++] = "-i"; - __argv[j++] = "-"; - __argv[j++] = NULL; - - execvp("/bin/sh", (char **)__argv); - free(__argv); - exit(-1); - } -script_found: - if (rec_script_path) - script_path = rec_script_path; - if (rep_script_path) - script_path = rep_script_path; - - if (script_path) { - j = 0; - - if (!rec_script_path) - system_wide = false; - else if (!system_wide) { - if (have_cmd(argc - 1, &argv[1]) != 0) { - err = -1; - goto out; + waitpid(pid, &status, 0); + if (WIFEXITED(status)) { + return WEXITSTATUS(status); + } else { + return -1; } } - - __argv = calloc(argc + 2, sizeof(const char *)); - if (!__argv) { - pr_err("malloc failed\n"); - err = -ENOMEM; - goto out; - } - - __argv[j++] = "/bin/sh"; - __argv[j++] = script_path; - if (system_wide) - __argv[j++] = "-a"; - for (i = 2; i < argc; i++) - __argv[j++] = argv[i]; - __argv[j++] = NULL; - - execvp("/bin/sh", (char **)__argv); - free(__argv); - exit(-1); } if (dlfilter_file) { @@ -4487,77 +4367,12 @@ int cmd_script(int argc, const char **argv) goto out_delete; } #endif - if (generate_script_lang) { - struct stat perf_stat; - int input; - char *filename = strdup("perf-script"); - - if (output_set_by_user()) { - fprintf(stderr, - "custom fields not supported for generated scripts"); - err = -EINVAL; - goto out_delete; - } - - input = open(data.path, O_RDONLY); /* input_name */ - if (input < 0) { - err = -errno; - perror("failed to open file"); - goto out_delete; - } - - err = fstat(input, &perf_stat); - if (err < 0) { - perror("failed to stat file"); - goto out_delete; - } - - if (!perf_stat.st_size) { - fprintf(stderr, "zero-sized file, nothing to do!\n"); - goto out_delete; - } - - scripting_ops = script_spec__lookup(generate_script_lang); - if (!scripting_ops && ends_with(generate_script_lang, ".py")) { - scripting_ops = script_spec__lookup("python"); - free(filename); - filename = strdup(generate_script_lang); - filename[strlen(filename) - 3] = '\0'; - } else if (!scripting_ops && ends_with(generate_script_lang, ".pl")) { - scripting_ops = script_spec__lookup("perl"); - free(filename); - filename = strdup(generate_script_lang); - filename[strlen(filename) - 3] = '\0'; - } - if (!scripting_ops) { - fprintf(stderr, "invalid language specifier '%s'\n", generate_script_lang); - err = -ENOENT; - goto out_delete; - } - if (!filename) { - err = -ENOMEM; - goto out_delete; - } -#ifdef HAVE_LIBTRACEEVENT - err = scripting_ops->generate_script(session->tevent.pevent, filename); -#else - err = scripting_ops->generate_script(NULL, filename); -#endif - free(filename); - goto out_delete; - } err = dlfilter__start(dlfilter, session); if (err) goto out_delete; - if (script_name) { - err = scripting_ops->start_script(script_name, argc, argv, session); - if (err) - goto out_delete; - pr_debug("perf script started with script %s\n\n", script_name); - script_started = true; - } + err = perf_session__check_output_opt(session); @@ -4587,7 +4402,6 @@ int cmd_script(int argc, const char **argv) err = __cmd_script(&script); - flush_scripting(); if (verbose > 2 || debug_kmaps) perf_session__dump_kmaps(session); @@ -4603,10 +4417,8 @@ int cmd_script(int argc, const char **argv) perf_session__delete(session); perf_script__exit(&script); - if (script_started) - cleanup_scripting(); + dlfilter__cleanup(dlfilter); free_dlarg(); -out: return err; } diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 70cc91d00804..91457de2ea18 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -94,7 +94,6 @@ perf-util-y += tool_pmu.o perf-util-y += tp_pmu.o perf-util-y += svghelper.o perf-util-y += trace-event-info.o -perf-util-y += trace-event-scripting.o perf-util-$(CONFIG_LIBTRACEEVENT) += trace-event.o perf-util-$(CONFIG_LIBTRACEEVENT) += trace-event-parse.o perf-util-$(CONFIG_LIBTRACEEVENT) += trace-event-read.o diff --git a/tools/perf/util/scripting-engines/Build b/tools/perf/util/scripting-engines/Build deleted file mode 100644 index 54920e7e1d5d..000000000000 --- a/tools/perf/util/scripting-engines/Build +++ /dev/null @@ -1 +0,0 @@ -# No embedded scripting engines diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index 9c015fc2bcfb..374cf82fd86e 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c @@ -14,71 +14,6 @@ #include #include -static int get_common_field(struct scripting_context *context, - int *offset, int *size, const char *type) -{ - struct tep_handle *pevent = context->pevent; - struct tep_event *event; - struct tep_format_field *field; - - if (!*size) { - - event = tep_get_first_event(pevent); - if (!event) - return 0; - - field = tep_find_common_field(event, type); - if (!field) - return 0; - *offset = field->offset; - *size = field->size; - } - - return tep_read_number(pevent, context->event_data + *offset, *size); -} - -int common_lock_depth(struct scripting_context *context) -{ - static int offset; - static int size; - int ret; - - ret = get_common_field(context, &size, &offset, - "common_lock_depth"); - if (ret < 0) - return -1; - - return ret; -} - -int common_flags(struct scripting_context *context) -{ - static int offset; - static int size; - int ret; - - ret = get_common_field(context, &size, &offset, - "common_flags"); - if (ret < 0) - return -1; - - return ret; -} - -int common_pc(struct scripting_context *context) -{ - static int offset; - static int size; - int ret; - - ret = get_common_field(context, &size, &offset, - "common_preempt_count"); - if (ret < 0) - return -1; - - return ret; -} - unsigned long long raw_field_value(struct tep_event *event, const char *name, void *data) { diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c deleted file mode 100644 index 0a0a50d9e1e1..000000000000 --- a/tools/perf/util/trace-event-scripting.c +++ /dev/null @@ -1,333 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * trace-event-scripting. Scripting engine common and initialization code. - * - * Copyright (C) 2009-2010 Tom Zanussi - */ - -#include -#include -#include -#include -#ifdef HAVE_LIBTRACEEVENT -#include -#endif - -#include "debug.h" -#include "event.h" -#include "trace-event.h" -#include "evsel.h" -#include -#include -#include "util/sample.h" - -unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH; - -struct scripting_context *scripting_context; - -struct script_spec { - struct list_head node; - struct scripting_ops *ops; - char spec[]; -}; - -static LIST_HEAD(script_specs); - -static struct script_spec *script_spec__new(const char *spec, - struct scripting_ops *ops) -{ - struct script_spec *s = malloc(sizeof(*s) + strlen(spec) + 1); - - if (s != NULL) { - strcpy(s->spec, spec); - s->ops = ops; - } - - return s; -} - -static void script_spec__add(struct script_spec *s) -{ - list_add_tail(&s->node, &script_specs); -} - -static struct script_spec *script_spec__find(const char *spec) -{ - struct script_spec *s; - - list_for_each_entry(s, &script_specs, node) - if (strcasecmp(s->spec, spec) == 0) - return s; - return NULL; -} - -static int script_spec_register(const char *spec, struct scripting_ops *ops) -{ - struct script_spec *s; - - s = script_spec__find(spec); - if (s) - return -1; - - s = script_spec__new(spec, ops); - if (!s) - return -1; - - script_spec__add(s); - return 0; -} - -struct scripting_ops *script_spec__lookup(const char *spec) -{ - struct script_spec *s = script_spec__find(spec); - - if (!s) - return NULL; - - return s->ops; -} - -int script_spec__for_each(int (*cb)(struct scripting_ops *ops, const char *spec)) -{ - struct script_spec *s; - int ret = 0; - - list_for_each_entry(s, &script_specs, node) { - ret = cb(s->ops, s->spec); - if (ret) - break; - } - return ret; -} - -void scripting_context__update(struct scripting_context *c, - union perf_event *event, - struct perf_sample *sample, - struct evsel *evsel, - struct addr_location *al, - struct addr_location *addr_al) -{ -#ifdef HAVE_LIBTRACEEVENT - const struct tep_event *tp_format = evsel__tp_format(evsel); - - c->pevent = tp_format ? tp_format->tep : NULL; -#else - c->pevent = NULL; -#endif - c->event_data = sample->raw_data; - c->event = event; - c->sample = sample; - c->evsel = evsel; - c->al = al; - c->addr_al = addr_al; -} - -static int flush_script_unsupported(void) -{ - return 0; -} - -static int stop_script_unsupported(void) -{ - return 0; -} - -static void process_event_unsupported(union perf_event *event __maybe_unused, - struct perf_sample *sample __maybe_unused, - struct evsel *evsel __maybe_unused, - struct addr_location *al __maybe_unused, - struct addr_location *addr_al __maybe_unused) -{ -} static void print_python_unsupported_msg(void) -{ - fprintf(stderr, "Python scripting not supported." - " Install libpython and rebuild perf to enable it.\n" - "For example:\n # apt-get install python-dev (ubuntu)" - "\n # yum install python-devel (Fedora)" - "\n etc.\n"); -} - -static int python_start_script_unsupported(const char *script __maybe_unused, - int argc __maybe_unused, - const char **argv __maybe_unused, - struct perf_session *session __maybe_unused) -{ - print_python_unsupported_msg(); - - return -1; -} - -static int python_generate_script_unsupported(struct tep_handle *pevent - __maybe_unused, - const char *outfile - __maybe_unused) -{ - print_python_unsupported_msg(); - - return -1; -} - -struct scripting_ops python_scripting_unsupported_ops = { - .name = "Python", - .dirname = "python", - .start_script = python_start_script_unsupported, - .flush_script = flush_script_unsupported, - .stop_script = stop_script_unsupported, - .process_event = process_event_unsupported, - .generate_script = python_generate_script_unsupported, -}; - -static void register_python_scripting(struct scripting_ops *scripting_ops) -{ - if (scripting_context == NULL) - scripting_context = malloc(sizeof(*scripting_context)); - - if (scripting_context == NULL || - script_spec_register("Python", scripting_ops) || - script_spec_register("py", scripting_ops)) { - pr_err("Error registering Python script extension: disabling it\n"); - zfree(&scripting_context); - } -} - -void setup_python_scripting(void) -{ - register_python_scripting(&python_scripting_unsupported_ops); -} - - -static const struct { - u32 flags; - const char *name; -} sample_flags[] = { - {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL, "call"}, - {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN, "return"}, - {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CONDITIONAL, "jcc"}, - {PERF_IP_FLAG_BRANCH, "jmp"}, - {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_INTERRUPT, "int"}, - {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_INTERRUPT, "iret"}, - {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_SYSCALLRET, "syscall"}, - {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_SYSCALLRET, "sysret"}, - {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_ASYNC, "async"}, - {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC | PERF_IP_FLAG_INTERRUPT, - "hw int"}, - {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TX_ABORT, "tx abrt"}, - {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_BEGIN, "tr strt"}, - {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_END, "tr end"}, - {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_VMENTRY, "vmentry"}, - {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_VMEXIT, "vmexit"}, - {0, NULL} -}; - -static const struct { - u32 flags; - const char *name; -} branch_events[] = { - {PERF_IP_FLAG_BRANCH_MISS, "miss"}, - {PERF_IP_FLAG_NOT_TAKEN, "not_taken"}, - {0, NULL} -}; - -static int sample_flags_to_name(u32 flags, char *str, size_t size) -{ - int i; - const char *prefix; - int pos = 0, ret, ev_idx = 0; - u32 xf = flags & PERF_ADDITIONAL_STATE_MASK; - u32 types, events; - char xs[16] = { 0 }; - - /* Clear additional state bits */ - flags &= ~PERF_ADDITIONAL_STATE_MASK; - - if (flags & PERF_IP_FLAG_TRACE_BEGIN) - prefix = "tr strt "; - else if (flags & PERF_IP_FLAG_TRACE_END) - prefix = "tr end "; - else - prefix = ""; - - ret = snprintf(str + pos, size - pos, "%s", prefix); - if (ret < 0) - return ret; - pos += ret; - - flags &= ~(PERF_IP_FLAG_TRACE_BEGIN | PERF_IP_FLAG_TRACE_END); - - types = flags & ~PERF_IP_FLAG_BRANCH_EVENT_MASK; - for (i = 0; sample_flags[i].name; i++) { - if (sample_flags[i].flags != types) - continue; - - ret = snprintf(str + pos, size - pos, "%s", sample_flags[i].name); - if (ret < 0) - return ret; - pos += ret; - break; - } - - events = flags & PERF_IP_FLAG_BRANCH_EVENT_MASK; - for (i = 0; branch_events[i].name; i++) { - if (!(branch_events[i].flags & events)) - continue; - - ret = snprintf(str + pos, size - pos, !ev_idx ? "/%s" : ",%s", - branch_events[i].name); - if (ret < 0) - return ret; - pos += ret; - ev_idx++; - } - - /* Add an end character '/' for events */ - if (ev_idx) { - ret = snprintf(str + pos, size - pos, "/"); - if (ret < 0) - return ret; - pos += ret; - } - - if (!xf) - return pos; - - snprintf(xs, sizeof(xs), "(%s%s%s)", - flags & PERF_IP_FLAG_IN_TX ? "x" : "", - flags & PERF_IP_FLAG_INTR_DISABLE ? "D" : "", - flags & PERF_IP_FLAG_INTR_TOGGLE ? "t" : ""); - - /* Right align the string if its length is less than the limit */ - if ((pos + strlen(xs)) < SAMPLE_FLAGS_STR_ALIGNED_SIZE) - ret = snprintf(str + pos, size - pos, "%*s", - (int)(SAMPLE_FLAGS_STR_ALIGNED_SIZE - ret), xs); - else - ret = snprintf(str + pos, size - pos, " %s", xs); - if (ret < 0) - return ret; - - return pos + ret; -} - -int perf_sample__sprintf_flags(u32 flags, char *str, size_t sz) -{ - const char *chars = PERF_IP_FLAG_CHARS; - const size_t n = strlen(PERF_IP_FLAG_CHARS); - size_t i, pos = 0; - int ret; - - ret = sample_flags_to_name(flags, str, sz); - if (ret > 0) - return ret; - - for (i = 0; i < n; i++, flags >>= 1) { - if ((flags & 1) && pos < sz) - str[pos++] = chars[i]; - } - for (; i < 32; i++, flags >>= 1) { - if ((flags & 1) && pos < sz) - str[pos++] = '?'; - } - if (pos < sz) - str[pos] = 0; - - return pos; -} diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index 7bdf44403e3a..19f22ac1faf3 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h @@ -7,15 +7,9 @@ #include #include -struct evlist; struct machine; -struct perf_sample; -union perf_event; -struct perf_tool; -struct thread; -struct tep_plugin_list; -struct evsel; struct tep_format_field; +struct tep_plugin_list; struct trace_event { struct tep_handle *pevent; @@ -79,73 +73,6 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs, int fd, bool temp); int tracing_data_put(struct tracing_data *tdata); - -struct addr_location; - -struct perf_session; -struct perf_stat_config; - -struct scripting_ops { - const char *name; - const char *dirname; /* For script path .../scripts//... */ - int (*start_script)(const char *script, int argc, const char **argv, - struct perf_session *session); - int (*flush_script) (void); - int (*stop_script) (void); - void (*process_event) (union perf_event *event, - struct perf_sample *sample, - struct evsel *evsel, - struct addr_location *al, - struct addr_location *addr_al); - void (*process_switch)(union perf_event *event, - struct perf_sample *sample, - struct machine *machine); - void (*process_auxtrace_error)(struct perf_session *session, - union perf_event *event); - void (*process_stat)(struct perf_stat_config *config, - struct evsel *evsel, u64 tstamp); - void (*process_stat_interval)(u64 tstamp); - void (*process_throttle)(union perf_event *event, - struct perf_sample *sample, - struct machine *machine); - int (*generate_script) (struct tep_handle *pevent, const char *outfile); -}; - -extern unsigned int scripting_max_stack; - -struct scripting_ops *script_spec__lookup(const char *spec); -int script_spec__for_each(int (*cb)(struct scripting_ops *ops, const char *spec)); - - -void setup_python_scripting(void); - -struct scripting_context { - struct tep_handle *pevent; - void *event_data; - union perf_event *event; - struct perf_sample *sample; - struct evsel *evsel; - struct addr_location *al; - struct addr_location *addr_al; - struct perf_session *session; -}; - -void scripting_context__update(struct scripting_context *scripting_context, - union perf_event *event, - struct perf_sample *sample, - struct evsel *evsel, - struct addr_location *al, - struct addr_location *addr_al); - -int common_pc(struct scripting_context *context); -int common_flags(struct scripting_context *context); -int common_lock_depth(struct scripting_context *context); - -#define SAMPLE_FLAGS_BUF_SIZE 64 -#define SAMPLE_FLAGS_STR_ALIGNED_SIZE 21 - -int perf_sample__sprintf_flags(u32 flags, char *str, size_t sz); - #if defined(LIBTRACEEVENT_VERSION) && LIBTRACEEVENT_VERSION >= MAKE_LIBTRACEEVENT_VERSION(1, 5, 0) #include -- 2.54.0.rc1.513.gad8abe7a5a-goog