ltrace.conf.5 13.9 KB
Newer Older
.\" -*-nroff-*-
.\" Copyright (c) 2012, 2013 Petr Machata, Red Hat Inc.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
.\" Copyright (c) 1997-2005 Juan Cespedes <[email protected]>
.\" This program is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU General Public License as
.\" published by the Free Software Foundation; either version 2 of the
.\" License, or (at your option) any later version.
.\" This program is distributed in the hope that it will be useful, but
.\" WITHOUT ANY WARRANTY; without even the implied warranty of
.\" General Public License for more details.
.\" You should have received a copy of the GNU General Public License
.\" along with this program; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
.\" 02110-1301 USA
Petr Machata's avatar
Petr Machata committed
.TH ltrace.conf "5" "October 2012" "" "ltrace configuration file"
21 22 23 24 25 26 27 28 29 30 31 32
\fBltrace.conf\fR \- Configuration file for \fBltrace(1)\fR.


This manual page describes \fBltrace.conf\fR, a file that describes
prototypes of functions in binaries for \fBltrace(1)\fR to use.
Ltrace needs this information to display function call arguments.

Each line of a configuration file describes at most a single item.
Lines composed entirely of white space are ignored, as are lines
Juan Cespedes's avatar
Juan Cespedes committed
33 34 35
starting with semicolon or hash characters (comment lines).  Described
items can be either function prototypes, or definitions of type
36 37 38 39 40 41 42


A prototype describes return type and parameter types of a single
function.  The syntax is as follows:

[\fBfunction\fR] \fILENS\fR \fINAME\fR \fB(\fR[\fILENS\fR{,\fILENS\fR}]\fB);\fR
44 45 46

\fINAME\fR is the (mangled) name of a symbol.  In the elementary case,
\fILENS\fR is simply a type.  Both lenses and types are described
48 49 50 51 52 53
below.  The \fBfunction\fR keyword, if present, has no effect.  It can be
used to force a line to be interpreted as a function prototype when the
return type is a keyword that would start a different type of line
(such as \fBimport\fR).

For example, a simple function prototype might look like this:
54 55 56 57 58 59 60

.B int\fR kill\fB(int,int);

Despite the apparent similarity with C, \fBltrace.conf\fR is really
its own language that's only somewhat inspired by C.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79


Ltrace understands a range of primitive types.  Those are interpreted
according to C convention native on a given architecture.
E.g. \fBulong\fR is interpreted as 4-byte unsigned integer on 32-bit
GNU/Linux machine, but 8-byte unsigned integer on 64-bit GNU/Linux

.B void
Denotes that a function does not return anything.  Can be also used to
construct a generic pointer, i.e. pointer-sized number formatted in
hexadecimal format.
.B char
8-bit quantity rendered as a character
.B ushort,short
Petr Machata's avatar
Petr Machata committed
Denotes unsigned or signed short integer.
81 82
.B uint,int
Petr Machata's avatar
Petr Machata committed
Denotes unsigned or signed integer.
84 85
.B ulong,long
Petr Machata's avatar
Petr Machata committed
Denotes unsigned or signed long integer.
87 88
.B float
Petr Machata's avatar
Petr Machata committed
Denotes floating point number with single precision.
90 91
.B double
Petr Machata's avatar
Petr Machata committed
Denotes floating point number with double precision.

95 96 97
Besides primitive types, the following composed types are possible:

98 99 100 101 102 103 104 105
.B struct(\fR[\fILENS\fR{,\fILENS\fR}]\fB)\fR
Describes a structure with given types as fields,
e.g. \fBstruct(int,int,float)\fR.

Alignment is computed as customary on the architecture.  Custom
alignment (e.g. packed structs) and bit-fields are not supported.
It's also not possible to differentiate between structs and non-POD
C++ classes, for arches where it makes a difference.
106 107

.B array(\fR\fILENS\fR\fB,\fIEXPR\fR\fB)
Describes array of length \fIEXPR\fR, which is composed of types
110 111 112 113 114 115
described by \fILENS\fR, e.g. \fBarray(int, \fR6\fB)\fR.

Note that in C, arrays in role of function argument decay into
pointers.  Ltrace currently handles this automatically, but for full
formal correctness, any such arguments should be described as pointers
to arrays.
116 117

118 119 120 121 122
.I LENS\fR\fB*
Describes a pointer to a given type, e.g. \fBchar*\fR or \fBint***\fR.
Note that the former example actually describes a pointer to a
character, not a string.  See below for \fBstring\fR lens, which is
applicable to these cases.
123 124 125 126 127 128 129 130


Lenses change the way that types are described.  In the simplest case,
a lens is directly a type.  Otherwise a type is decorated by the lens.
Ltrace understands the following lenses:

.B oct(\fITYPE\fB)
132 133 134 135
The argument, which should be an integer type, is formatted in base-8.

.B hex(\fITYPE\fB)
136 137 138
The argument, which should be an integer or floating point type, is
formatted in base-16.  Floating point arguments are converted to
double and then displayed using the \fB%a\fR fprintf modifier.
139 140 141 142 143 144 145

.B hide(\fITYPE\fB)
The argument is not shown in argument list.

.B bool(\fITYPE\fB)
Arguments with zero value are shown as "false", others are shown as
147 148

149 150 151 152 153 154 155 156 157 158
.B bitvec(\fITYPE\fB)
Underlying argument is interpreted as a bit vector and a summary of
bits set in the vector is displayed.  For example if bits 3,4,5 and 7
of the bit vector are set, ltrace shows <3-5,7>.  Empty bit vector is
displayed as <>.  If there are more bits set than unset, inverse is
shown instead: e.g. ~<0> when a number 0xfffffffe is displayed.  Full
set is thus displayed ~<>.

If the underlying type is integral, then bits are shown in their
natural big-endian order, with LSB being bit 0.
160 161 162 163 164 165 166 167 168 169 170
E.g. \fBbitvec(ushort)\fR with value 0x0102 would be displayed as
<1,8>, irrespective of underlying byte order.

For other data types (notably structures and arrays), the underlying
data is interpreted byte after byte.  Bit 0 of first byte has number
0, bit 0 of second byte number 8, and so on.  Thus
\fBbitvec(struct(int))\fR is endian sensitive, and will show bytes
comprising the integer in their memory order.  Pointers are first
dereferenced, thus \fBbitvec(array(char, \fR32\fB)*)\fR is actually a
pointer to 256-bit bit vector.

Petr Machata's avatar
Petr Machata committed
172 173 174 175 176 177 178 179
.B string(\fITYPE\fB)
.B string[\fIEXPR\fB]
.B string
The first form of the argument is canonical, the latter two are
syntactic sugar.  In the canonical form, the function argument is
180 181 182 183 184 185 186 187 188 189
formatted as string.  The \fITYPE\fR can have either of the following
forms: \fIX\fB*\fR, or \fBarray(\fIX\fB,\fIEXPR\fB)\fR, or
\fBarray(\fIX\fB,\fIEXPR\fB)*\fR.  \fIX\fR is either \fBchar\fR for
normal strings, or an integer type for wide-character strings.

If an array is given, the length will typically be a \fBzero\fR
expression (but doesn't have to be).  Using argument that is plain
array (i.e. not a pointer to array) makes sense e.g. in C structs, in
cases like \fBstruct(string(array(char, \fR6\fB)))\fR, which describes
the C type \fBstruct {char \fRs\fB[\fR6\fB];}\fR.
Petr Machata's avatar
Petr Machata committed
190 191 192 193 194 195 196 197 198 199 200 201

Because simple C-like strings are pretty common, there are two
shorthand forms.  The first shorthand form (with brackets) means the
same as \fBstring(array(char, \fIEXPR\fB)*)\fR.  Plain \fBstring\fR
without an argument is then taken to mean the same as

Note that \fBchar*\fR by itself describes a pointer to a char.  Ltrace
will dereference the pointer, and read and display the single
character that it points to.

202 203 204 205
.B enum(\fINAME\fR[\fB=\fIVALUE\fR]{,\fINAME\fR[\fB=\fIVALUE\fR]}\fB)
.B enum[\fITYPE\fB]\fB(\fINAME\fR[\fB=\fIVALUE\fR]{,\fINAME\fR[\fB=\fIVALUE\fR]}\fB)
206 207 208 209 210
This describes an enumeration lens.  If an argument has any of the
given values, it is instead shown as the corresponding \fINAME\fR.  If
a \fIVALUE\fR is omitted, the next consecutive value following after
the previous \fIVALUE\fR is taken instead.  If the first \fIVALUE\fR
is omitted, it's \fB0\fR by default.
211 212

\fITYPE\fR, if given, is the underlying type.  It is thus possible to
create enums over shorts or longs\(emarguments that are themselves
plain, non-enum types in C, but whose values can be meaningfully
215 216 217 218 219 220 221 222 223 224 225 226
described as enumerations.  If omitted, \fITYPE\fR is taken to be


A line in config file can, instead of describing a prototype, create a
type alias.  Instead of writing the same enum or struct on many places
(and possibly updating when it changes), one can introduce a name for
such type, and later just use that name:

Petr Machata's avatar
Petr Machata committed
\fBtypedef \fINAME\fB = \fILENS\fB;\fR
228 229

230 231 232 233 234 235 236 237 238 239 240 241 242 243

It's possible for config files to import definitions from other config
files.  A line of the form:

\fBimport "\fIFILENAME\fB";\fR

will make all definitions from \fIFILENAME\fR.conf available in the current
file.  The imported file is searched for in the same directories as when
looking up a config file corresponding to a library; see \fBltrace(1)\fR
for details.

244 245 246

Ltrace allows you to express recursive structures.  Such structures
Juan Cespedes's avatar
Juan Cespedes committed
are expanded to the depth described by the parameter \-A.  To declare a
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
recursive type, you first have to introduce the type to ltrace by
using forward declaration.  Then you can use the type in other type
definitions in the usual way:

.B typedef \fINAME\fB = struct;
.B typedef \fINAME\fB = struct(\fINAME\fR can be used here\fB)

For example, consider the following singy-linked structure and a
function that takes such list as an argument:

.B typedef\fR int_list \fB= struct;
.B typedef\fR int_list \fB= struct(int,\fR int_list\fB*);
.B void\fR ll\fB(\fRint_list\fB*);

Such declarations might lead to an output like the following:

ll({ 9, { 8, { 7, { 6, ... } } } }) = <void>

Ltrace detects recursion and will not expand already-expanded
structures.  Thus a doubly-linked list would look like the following:

.B typedef\fR int_list \fB= struct;
.B typedef\fR int_list \fB= struct(int,\fR int_list\fB*,\fR int_list\fB*);

With output e.g. like:

ll({ 9, { 8, { 7, { 6, ..., ... }, recurse^ }, recurse^ }, nil })

The "recurse^" tokens mean that given pointer points to a structure
that was expanded in the previous layer.  Simple "recurse" would mean
that it points back to this object.  E.g. "recurse^^^" means it points
to a structure three layers up.  For doubly-linked list, the pointer
to the previous element is of course the one that has been just
expanded in the previous round, and therefore all of them are either
recurse^, or nil.  If the next and previous pointers are swapped, the
output adjusts correspondingly:

ll({ 9, nil, { 8, recurse^, { 7, recurse^, { 6, ..., ... } } } })

304 305

306 307 308 309 310 311 312 313 314 315 316 317 318
Ltrace has support for some elementary expressions.  Each expression
can be either of the following:

An integer number.

.B arg\fINUM
Value of \fINUM\fR-th argument.  The expression has the same value as
the corresponding argument.  \fBarg1\fR refers to the first argument,
\fBarg0\fR to the return value of the given function.

Petr Machata's avatar
Petr Machata committed
320 321 322
.B retval
Return value of function, same as \fBarg0\fR.

Petr Machata's avatar
Petr Machata committed
.B elt\fINUM
325 326 327 328 329 330 331 332 333 334 335
Value of \fINUM\fR-th element of the surrounding structure type.  E.g.
\fBstruct(ulong,array(int,elt1))\fR describes a structure whose first
element is a length, and second element an array of ints of that

.B zero
.B zero(\fIEXPR\fB)
Describes array which extends until the first element, whose each byte
is 0.  If an expression is given, that is the maximum length of the
337 338 339
array.  If NUL terminator is not found earlier, that's where the array
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357


Sometimes the actual function prototype varies slightly depending on
the exact parameters given.  For example, the number and types of
printf parameters are not known in advance, but ltrace might be able
to determine them in runtime.  This feature has wider applicability,
but currently the only parameter pack that ltrace supports is
printf-style format string itself:

.B format
When \fBformat\fR is seen in the parameter list, the underlying string
argument is parsed, and GNU-style format specifiers are used to
determine what the following actual arguments are.  E.g. if the format
string is "%s %d\\n", it's as if the \fBformat\fR was replaced by
\fBstring, string, int\fR.

358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392

C functions often use one or more arguments for returning values back
to the caller.  The caller provides a pointer to storage, which the
called function initializes.  Ltrace has some support for this idiom.

When a traced binary hits a function call, ltrace first fetches all
arguments.  It then displays \fIleft\fR portion of the argument list.
Only when the function returns does ltrace display \fIright\fR portion
as well.  Typically, left portion takes up all the arguments, and
right portion only contains return value.  But ltrace allows you to
configure where exactly to put the dividing line by means of a \fB+\fR
operator placed in front of an argument:

.B int\fR asprintf\fB(+string*, format);

Here, the first argument to asprintf is denoted as return argument,
which means that displaying the whole argument list is delayed until
the function returns:

a.out->asprintf( <unfinished ...>
.br>malloc(100)                   = 0x245b010
[... more calls here ...]
<... asprintf resumed> "X=1", "X=%d", 1) = 5

It is currently not possible to have an "inout" argument that passes
information in both directions.

393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426

In the following, the first is the C prototype, and following that is
ltrace configuration line.

.B void\fR func_charp_string\fB(char\fR str\fB[]);
.B void\fR func_charp_string\fB(string);

.B enum\fR e_foo \fB{\fRRED\fB, \fRGREEN\fB, \fRBLUE\fB};
.B void\fR func_enum\fB(enum\fR e_foo bar\fB);\fR
.B void\fR func_enum\fB(enum(\fRRED\fB,\fRGREEN\fB,\fRBLUE\fB));\fR
- or -
.B typedef\fR e_foo \fB= enum(\fRRED\fB,\fRGREEN\fB,\fRBLUE\fB);\fR
.B void\fR func_enum\fB(\fRe_foo\fB);\fR

.B void\fR func_arrayi\fB(int\fR arr\fB[],\fR int len\fB);
.B void\fR func_arrayi\fB(array(int,arg2)*,int);

.B struct\fR S1 \fB{float\fR f\fB; char\fR a\fB; char \fRb\fB;};
.B struct\fR S2 \fB{char\fR str\fB[\fR6\fB]; float\fR f\fB;};
.B struct\fR S1 func_struct\fB(int \fRa\fB, struct \fRS2\fB, double \fRd\fB);
Juan Cespedes's avatar
Juan Cespedes committed
.B struct(float,char,char)\fR func_struct\fB(int, struct(string(array(char, \fR6\fB)),float), double);
428 429 430 431

Petr Machata <[email protected]>