NAME
ltrace.conf - Configuration file for ltrace(1).DESCRIPTION
This manual page describes ltrace.conf, a file that describes prototypes of functions in binaries for ltrace(1) to use. Ltrace needs this information to display function call arguments.PROTOTYPES
A prototype describes return type and parameter types of a single function. The syntax is as follows:
LENS NAME
([LENS{,LENS}]);
int kill(int,int);
TYPES
Ltrace understands a range of primitive types. Those are interpreted according to C convention native on a given architecture. E.g. ulong is interpreted as 4-byte unsigned integer on 32-bit GNU/Linux machine, but 8-byte unsigned integer on 64-bit GNU/Linux machine.- 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.
- char
- 8-bit quantity rendered as a character
- ushort,short
- Denotes unsigned or signed short integer.
- uint,int
- Denotes unsigned or signed integer.
- ulong,long
- Denotes unsigned or signed long integer.
- float
- Denotes floating point number with single precision.
- double
- Denotes floating point number with double precision.
- struct([LENS{,LENS}])
- Describes a structure with given types as fields, e.g. struct(int,int,float). 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.
- array(LENS,EXPR)
- Describes array of length EXPR, which is composed of types described by LENS, e.g. array(int, 6). 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.
- LENS*
- Describes a pointer to a given type, e.g. char* or int***. Note that the former example actually describes a pointer to a character, not a string. See below for string lens, which is applicable to these cases.
LENSES
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:- oct(TYPE)
- The argument, which should be an integer type, is formatted in base-8.
- hex(TYPE)
- 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 %a fprintf modifier.
- hide(TYPE)
- The argument is not shown in argument list.
- bool(TYPE)
- Arguments with zero value are shown as "false", others are shown as "true".
- bitvec(TYPE)
- 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. E.g. bitvec(ushort) 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 bitvec(struct(int)) is endian sensitive, and will show bytes comprising the integer in their memory order. Pointers are first dereferenced, thus bitvec(array(char, 32)*) is actually a pointer to 256-bit bit vector.
The first form of the argument is canonical,
the latter two are syntactic sugar. In the canonical form, the function
argument is formatted as string. The TYPE shall be either a
char*, or array(char,EXPR), or
array(char,EXPR)*. If an array is given, the length will
typically be a zero 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 struct(string(array(char, 6))), which
describes the C type struct {char s[6];}.
Because simple C-like strings are pretty common, there are two shorthand forms.
The first shorthand form (with brackets) means the same as
string(array(char, EXPR)*). Plain string without
an argument is then taken to mean the same as string[zero].
Note that char* by itself describes a pointer to a char. Ltrace will
dereference the pointer, and read and display the single character that it
points to.
This describes an enumeration lens. If an
argument has any of the given values, it is instead shown as the corresponding
NAME. If a VALUE is omitted, the next consecutive value
following after the previous VALUE is taken instead. If the first
VALUE is omitted, it's 0 by default.
TYPE, if given, is the underlying type. It is thus possible to create
enums over shorts or longs—arguments that are themselves plain,
non-enum types in C, but whose values can be meaningfully described as
enumerations. If omitted, TYPE is taken to be int.
TYPE ALIASES
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:
typedef NAME =
LENS ;
RECURSIVE STRUCTURES
Ltrace allows you to express recursive structures. Such structures are expanded to the depth described by the parameter -A. To declare a 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:
typedef NAME = struct;
typedef NAME = struct(NAME can be used
here)
typedef int_list = struct;
typedef int_list = struct(int, int_list*);
void ll(int_list*);
ll({ 9, { 8, { 7, { 6, ... } } } }) =
<void>
typedef int_list = struct;
typedef int_list = struct(int, int_list*,
int_list*);
ll({ 9, { 8, { 7, { 6, ..., ... }, recurse^ },
recurse^ }, nil })
ll({ 9, nil, { 8, recurse^, { 7, recurse^, {
6, ..., ... } } } })
EXPRESSIONS
Ltrace has support for some elementary expressions. Each expression can be either of the following:- NUM
- An integer number.
- argNUM
- Value of NUM-th argument. The expression has the same value as the corresponding argument. arg1 refers to the first argument, arg0 to the return value of the given function.
- retval
- Return value of function, same as arg0.
- eltNUM
- Value of NUM-th element of the surrounding structure type. E.g. struct(ulong,array(int,elt1)) describes a structure whose first element is a length, and second element an array of ints of that length.
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 array. If NUL terminator is not found earlier, that's where the
array ends.
PARAMETER PACKS
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:- format
- When format 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 format was replaced by string, string, int.
RETURN ARGUMENTS
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.int asprintf(+string*,
format);
a.out->asprintf( <unfinished ...>
libc.so.6->malloc(100) = 0x245b010
[... more calls here ...]
<... asprintf resumed> "X=1", "X=%d", 1) = 5
EXAMPLES
In the following, the first is the C prototype, and following that is ltrace configuration line.- void func_charp_string(char str[]);
- void func_charp_string(string);
void
func_enum(enum(RED,GREEN,BLUE));
void func_enum(e_foo);
- or -
typedef e_foo = enum(RED,GREEN,BLUE);
- void func_arrayi(int arr[], int len);
- void func_arrayi(array(int,arg2)*,int);
struct(float,char,char)
func_struct_2(int, struct(string(array(char, 6 )),float),
double);
AUTHOR
Petr Machata <[email protected]>October 2012 |