UFTRACE-SCRIPT(1)
πΈ uftrace-script β bestie edition π
okay so this is a page from the General Commands Manual, and the star of the show is uftrace-script. That's the tool that runs a lil script over your recorded function trace. Get comfy, we're doing this together π«Ά
β¨ NAME β¨
uftrace-script β run a script for recorded function trace. yes that's the whole vibe, it's literally that π
β¨ SYNOPSIS β¨
uftrace script (-S|βscript) [options] uftrace script (-S|βscript)
[options] βrecord COMMAND
β¨ DESCRIPTION β¨
So! This command runs a script on trace data that you already recorded with the uftrace-record(1) command. That's it, that's the job. You bring the data, she brings the script. iconic behavior tbh π
π SCRIPT OPTIONS π
-S SCRIPT_PATH,--script=SCRIPT_PATHβ run the script you hand her, so it can do extra work at the entry and exit of a function while she's chewing through the recorded trace data. How does she know what kind of script it is? File extension, bestie. Like.pyfor python and.luafor lua 5.1. Go read SCRIPT EXECUTION for the deets β¨--record COMMAND [command-options]β records a whole new trace before running the script you gave her. two things at once, main character energy π--no-argsβ do not show function arguments and return value. keep it mysterious π
π COMMON OPTIONS π
-F FUNC,--filter=FUNCβ set a filter to trace selected functions and their children functions. you can use this option more than once, she doesn't mind.uftrace-replay(1)explains what filters even are.-N FUNC,--notrace=FUNCβ opposite vibe: set a filter to not trace selected functions and their children functions. also usable more than once. again,uftrace-replay(1)for the filter lore.-C FUNC,--caller-filter=FUNCβ set a filter to trace callers of selected functions only. use it more than once if you want.uftrace-replay(1)has the explanation, as always.-T TRG,--trigger=TRGβ set a trigger on selected functions. usable more than once.uftrace-replayhas the details, go look π-D DEPTH,--depth DEPTHβ set the trace limit in nesting level. don't go too deep, it gets scary down there π-t TIME,--time-filter=TIMEβ do not run the script for functions that run under the time threshold. but! if some functions explicitly have thetracetrigger applied, those are always traced regardless of execution time. no skipping those, periodt.-Z SIZE,--size-filter=SIZEβ do not show functions smaller than SIZE bytes. small functions found shaking π-L LOCATION,--loc-filter=LOCATIONβ set a filter to trace selected source locations. more than once? yes ma'am, allowed.--no-libcallβ do not run the script for library calls. skip β¨--match=TYPEβ use pattern match with TYPE. possible types areregexandglob. default isregex.--with-syms=DIRβ read symbol data from the.symfiles in theDIRdirectory instead of from the binary. super useful for dealing with stripped binaries. important tho: the file name of the main binary should be the same when saved and used. don't rename things mid-way, she will not know who anyone is π«
π COMMON ANALYSIS OPTIONS π
-H FUNC,--hide=FUNCβ set a filter to not trace selected functions. key difference: it doesn't affect their subtrees, it hides only the given functions. use it more than once.uftrace-replay(1)explains filters if you're lost.--kernel-fullβ run the script on all kernel functions and events that occurred outside of user functions. the whole kernel situation, no cap.--kernel-onlyβ run the script on kernel functions only, no user functions at all. strictly kernel business π--tid=TID[,TID,...]β run the script only for functions called by the given tasks. wanna see the list of tasks in the data file? useuftrace report --taskoruftrace info. and yes, this option can also be used more than once.--demangle=TYPEβ use demangled C++ symbol names for filters, triggers, arguments and/or return values. possible values are βfullβ, βsimpleβ and βnoβ. default is βsimpleβ, which ignores function arguments and template parameters. cute and simple, love that for her π-r RANGE,--time-range=RANGEβ run the script only for functions executed within the timeRANGE. the RANGE can be<start>~<stop>(separated by β~β) and one of<start>and<stop>can be omitted.<start>and<stop>are timestamp or elapsed time if they have a<time_unit>postfix, for example100us. and you can see that timestamp or elapsed time with the-f timeor-f elapsedoption respectively inuftrace replay(1). so many units, so little time π¦
π§ SCRIPT EXECUTION π§
okay this is the fun part, sit down.
The uftrace tool supports script execution for each function entry and exit. The supported script types are Python 2.7, Python 3 and Lua 5.1 as of now. (yes, Python 2.7 is still invited to the party, we don't judge here.)
The user can write five functions. uftrace_entry and uftrace_exit are executed whenever each function is executed at the entry and exit. However uftrace_begin and uftrace_end are only executed once when the target program begins and ends. uftrace_event is called when it sees an event. five besties, five jobs πΈ
$ cat scripts/simple.py
def uftrace_begin(ctx):
print("program begins...")
def uftrace_entry(ctx):
func = ctx["name"]
print("entry : " + func + "()")
def uftrace_exit(ctx):
func = ctx["name"]
print("exit : " + func + "()")
def uftrace_event(ctx):
name = ctx["name"]
print("event : " + name)
def uftrace_end():
print("program is finished")
The ctx variable is a dictionary type that contains the below information. yes, she's handing you the whole dictionary, take it π
/* context information passed to uftrace_entry(ctx) and uftrace_exit(ctx) */
script_context = {
int tid;
int depth;
long timestamp;
long duration; # exit only
long address;
string name;
list args; # entry only (if available)
value retval; # exit only (if available)
};
/* context information passed to uftrace_begin(ctx) */
script_context = {
bool record; # True if it runs at record time, otherwise False
string version; # uftrace version info
list cmds; # execution commands
};
The above script can be executed while reading the recorded data. The usage is as follows. look how clean the output is, I'm obsessed ππ
$ uftrace record -F main tests/t-abc
$ uftrace script -S scripts/simple.py
program begins...
entry : main()
entry : a()
entry : b()
entry : c()
entry : getpid()
exit : getpid()
exit : c()
exit : b()
exit : a()
exit : main()
program is finished
The below is another example that shows the different output compared to previous one for the same recorded data. The output looks similar to uftrace replay this time. same data, different fit, she contains multitudes β¨
$ uftrace script -S scripts/replay.py
# DURATION TID FUNCTION
[25794] | main() {
[25794] | a() {
[25794] | b() {
[25794] | c() {
[25794] | getpid() {
11.037 us [25794] | } /* getpid */
44.752 us [25794] | } /* c */
70.924 us [25794] | } /* b */
98.191 us [25794] | } /* a */
124.329 us [25794] | } /* main */
The script above can be modified to do more output customization. go wild, customize away π
A script can have an optional βUFTRACE_FUNCSβ list which can have name (or pattern depending on the βmatch option) of functions to run the script. If it exists, only matched functions will run the script. For example, if you add following lines to the script, it will run only for functions with a single letter name. one letter names only, a-listers only π
$ echo 'UFTRACE_FUNCS = [ "^.$" ]' >> replay.py
$ uftrace script -S replay.py
# DURATION TID FUNCTION
[25794] | a() {
[25794] | b() {
[25794] | c() {
44.752 us [25794] | } /* c */
70.924 us [25794] | } /* b */
98.191 us [25794] | } /* a */
Also a script can have options for record if it requires some form of data (i.e. function argument or return value). A comment line started with βuftrace-option:β will provide (a part of) such options when recording. yes, your script can place an order π
$ cat arg.py
#
# uftrace-option: -A a@arg1 -R b@retval
#
def uftrace_entry(ctx):
if "args" in ctx:
print(ctx["name"] + " has args")
def uftrace_exit(ctx):
if "retval" in ctx:
print(ctx["name"] + " has retval")
$ uftrace record -S arg.py abc
a has args
b has retval
$ uftrace script -S arg.py
a has args
b has retval
Also a script can handle event records and optional event data in βargsβ. The argument is a string containing KEY=VALUE pairs. Currently it only works with uftrace script and not for record. heads up, this is a script-only situation, no cap. π₯
$ cat event.py
def uftrace_entry(ctx):
pass
def uftrace_exit(ctx):
pass
def uftrace_event(ctx):
if "args" in ctx:
print(ctx["name"] + " ::: " + ctx["args"])
else:
print(ctx["name"])
$ uftrace record -T a@read=proc/statm abc
$ uftrace script -S event.py
read:proc/statm ::: vmsize=31060KB vmrss=15412KB shared=11064KB
diff:proc/statm ::: vmsize=+0KB vmrss=+0KB shared=+0KB
π« SEE ALSO π«
uftrace(1), uftrace-record(1), uftrace-replay(1), uftrace-live(1)
go read the whole family, they're all slaying π«Ά
π AUTHORS π
Honggyu Kim <honggyu.kp@gmail.com>, Namhyung Kim <namhyung@gmail.com>
thank you kings for your service π«‘π
and that's the page bestie!! this came out of the Uftrace User Manuals, dated Sep, 2018. yeah she's an older queen but she still ate, fr fr. mwah π β¨πΈπ
π¦ where this page comes from
- nixos 26.05: uftrace 0.19
- ubuntu stonking: uftrace 0.19-1 Β· GPL-2.0-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms