TODO revision 4d73ff5feef8e5224db630ed36e74fbf6b6accd6
1-*-org-*-
2* TODO
3** Automatic prototype discovery:
4*** Use debuginfo if available
5    Alternatively, use debuginfo to generate configure file.
6*** Demangled identifiers contain partial prototypes themselves
7** Automatically update list of syscalls?
8** Update /etc/ltrace.conf
9   In particular, we could use a config directory, where packages
10   would install their ltrace config scripts.  The config file could
11   be named after SONAME, and automatically read when corresponding
12   library is mapped.
13** More operating systems (solaris?)
14** Get rid of EVENT_ARCH_SYSCALL and EVENT_ARCH_SYSRET
15** Implement displaced tracing
16   A technique used in GDB (and in uprobes, I believe), whereby the
17   instruction under breakpoint is moved somewhere else, and followed
18   by a jump back to original place.  When the breakpoint hits, the IP
19   is moved to the displaced instruction, and the process is
20   continued.  We avoid all the fuss with singlestepping and
21   reenablement.
22** Create different ltrace processes to trace different children
23** Config file syntax
24*** typedef should be able to assign a lens to a name
25*** named arguments
26    This would be useful for replacing the arg1, emt2 etc.
27
28*** parameter pack improvements
29    The above format tweaks require that packs that expand to no types
30    at all be supported.  If this works, then it should be relatively
31    painless to implement conditionals:
32
33    | void ptrace(REQ=enum(PTRACE_TRACEME=0,...),
34    |             if[REQ==0](pack(),pack(pid_t, void*, void *)))
35
36    This is of course dangerously close to a programming language, and
37    I think ltrace should be careful to stay as simple as possible.
38    (We can hook into Lua, or TinyScheme, or some such if we want more
39    general scripting capabilities.  Implementing something ad-hoc is
40    undesirable.)  But the above can be nicely expressed by pattern
41    matching:
42
43    | void ptrace(REQ=enum[int](...)):
44    |   [REQ==0] => ()
45    |   [REQ==1 or REQ==2] => (pid_t, void*)
46    |   [true] => (pid_t, void*, void*);
47
48    Or:
49
50    | int open(string, FLAGS=flags[int](O_RDONLY=00,...,O_CREAT=0100,...)):
51    |   [(FLAGS & 0100) != 0] => (flags[int](S_IRWXU,...))
52
53    This would still require pretty complete expression evaluation.
54    _Including_ pointer dereferences and such.  And e.g. in accept, we
55    need subtraction:
56
57    | int accept(int, +struct(short, +array(hex(char), X-2))*, (X=uint)*);
58
59    Perhaps we should hook to something after all.
60
61*** errno tracking
62    Some calls result in setting errno.  Somehow mark those, and on
63    failure, show errno.
64
65*** second conversions?
66    This definitely calls for some general scripting.  The goal is to
67    have seconds in adjtimex calls show as e.g. 10s, 1m15s or some
68    such.
69
70*** format should take arguments like string does
71    Format should take value argument describing the value that should
72    be analyzed.  The following overwriting rules would then apply:
73
74    | format       | format(array(char, zero)*) |
75    | format(LENS) | X=LENS, format[X]          |
76
77    The latter expanded form would be canonical.
78
79    This depends on named arguments and parameter pack improvements
80    (we need to be able to construct parameter packs that expand to
81    nothing).
82
83*** More fine-tuned control of right arguments
84    Combination of named arguments and some extensions could take care
85    of that:
86
87    | void func(X=hide(int*), long*, +pack(X)); |
88
89    This would show long* as input argument (i.e. the function could
90    mangle it), and later show the pre-fetched X.  The "pack" syntax is
91    utterly undeveloped as of now.  The general idea is to produce
92    arguments that expand to some mix of types and values.  But maybe
93    all we need is something like
94
95    | void func(out int*, long*); |
96
97    ltrace would know that out/inout/in arguments are given in the
98    right order, but left pass should display in and inout arguments
99    only, and right pass then out and inout.  + would be
100    backward-compatible syntactic sugar, expanded like so:
101
102    | void func(int*, int*, +long*, long*);              |
103    | void func(in int*, in int*, out long*, out long*); |
104
105    But sometimes we may want to see a different type on the way in and
106    on the way out.  E.g. in asprintf, what's interesting on the way in
107    is the address, but on the way out we want to see buffer contents.
108    Does something like the following make sense?
109
110    | void func(X=void*, long*, out string(X)); |
111
112** Support for functions that never return
113   This would be useful for __cxa_throw, presumably also for longjmp
114   (do we handle that at all?) and perhaps a handful of others.
115
116** Support flag fields
117   enum-like syntax, except disjunction of several values is assumed.
118** Support long long
119   We currently can't define time_t on 32bit machines.  That mean we
120   can't describe a range of time-related functions.
121
122* BUGS
123** After a clone(), syscalls may be seen as sysrets in s390 (see trace.c:syscall_p())
124