[Ltrace-devel] Array length expressions and types that might as well go

Petr Machata pmachata at redhat.com
Wed Nov 30 02:05:13 UTC 2011


Hi there,

in my last mail about the ABI support, I briefly mentioned the files
expr.c/expr.h that I created on the ABI branch.

The goal here is to somehow formalize the array-length expressions.  We
store them into a single int right now, which is not enough to encode
even the features that we promise.  For example, argN and eltN both
become the value -N, so when you request this:

  void f(int, struct(int, array(int,arg1)*))

it effectively becomes:

  void f(int, struct(int, array(int,emt1)*))

So we really need something richer, and expr.c is my take on it.

Once you have something capable of holding opcodes, you can invent
interesting expressions.  Like, we could actually _name_ arguments
(optionally), instead of having to refer to them by number.  But that's
for later.

One easy, low-hanging improvement is "zero" keyword.  You see, some
real-world arrays are NULL or 0 terminated.  "zero" would capture this.
You would say array(int, zero), and ltrace would know that the array is
NULL terminated.

The most obvious client of this is string.  For string is simply
array(char, zero)*.  There, that's ARGTYPE_STRING gone.  If you provide
"zero" keyword with optional length argument (array(char,zero(10))*),
you can remove ARGTYPE_STRING_N, too.  You just need a bit of logic in
the formatter, so that it knows to output char arrays as strings, like
what GHCi does.  Of course you still want to support all the "string*"
keywords.  Writing "string[20]" is much more user-friendly than having
to write "array(char, 20)*".  But it's all a syntactic sugar, the ltrace
proper (mainly back ends, really) doesn't have to care about that.

I believe this is all uncontroversial, and is actually on the ABI
branch.  The reason it's on ABI branch being that the back end needs to
do some dispatching based on type, and I noticed the mess.  If anyone
feels this belongs on a separate branch, I'll try to disentangle the two
again.

The following is not implemented and I don't plan on doing it right
away.  If anyone has opinions about any of these, I'd like to hear them.

For starters, we support ARGTYPE_OCTAL.  OCTAL is a format, not a width.
Why don't we have octal longs?  Really, ints and such should take
optional "lens" parameter, like int(oct), short(hex), or whatever.
Isn't ARGTYPE_ADDR just long with hex lens after all?

Really, isn't ARGTYPE_CHAR just ARGTYPE_INT8(char)?  This would allow
naturally extending into wide chars that would be ARGTYPE_INT(char).
(But maybe not, I'm not clear on this one.)

Finally, anyone knows what ARGTYPE_FILE is supposed to do?  Tracking
file names?  FILE* doesn't have to be bound to file (for example, see
open_memstream).  Besides, should we implement tracking, why do it for
files and not for arbitrary values?  Anyway, ARGTYPE_FILE is and always
has been in TODO status as far as I can tell.  Let's drop it until
someone comes up with a clear definition of what it should do.

This of course opens the can of worms that's called varargs.  We support
ARGTYPE_FORMAT, but that's just for printf.  Slight variations like
scanf are out of luck (%d here is int*, not int), as is strfmon, which
is just completely different.  Not no speak of execve, which has a
twist: the argument list is not even determined by format, it's
open-ended.

Bah, I guess I'm having one of those talking fits.  That's an exception
to my usual reclusive self.

Thanks,
PM



More information about the Ltrace-devel mailing list