Doth quoth the DaveM

Using MDB to figure out mysterious program behavior

Wednesday Jun 23, 2004

In working with Tcl and SWIG, I was trying to write a typemap to convert between a Tcl list and a C global char *foo[1024]. I kept having problems when I would try to append to the list foo, i.e. I'd try set foo bar lappend foo bletch set foo and instead of getting the list bar bletch as I expected, I'd see something like bletch bletch. Really strange.

I decided to use Solaris' mdb debugger to figure out what was going on by setting watchpoints. First I set a watchpoint on the first part of foo, since I knew I'd be changing that, i.e. I ran foo:w This was changing as I expected. Then I examined foo and set a watchpoint at the address at the first word in foo. At this point, I discovered this address being used in malloc() and free(). Ah ha, something was freeing this.

What I narrowed this down to was the fact that I was using the underlying Tcl_Obj string representation as my char *'s, but Tcl didn't know that and was freeing them. I realized I needed to allocate my own memory for copies of the strings and copy them over from the Tcl objects to my memory. Once I did that, things worked. I had scratched my head for a while, but mdb made it really easy to figure out what was going on.

Like this post? del.icio.us | furl | slashdot | technorati | digg

Scripting with Tcl and SWIG

Wednesday Jun 23, 2004

Lately I've been on a mission to provide a scripting interface to a test program that has a curses-based configuration tool that for some reason I have a lot of trouble with. I guess the designer and I have different ideas of how to design a curses-based configuration tool. Alos, the tool produces configuration files that, while they are in ASCII and can be read, they're not easily modified, so difficult to use for scripting.

I'm a fan of Tcl/Tk and also [incr Tcl], which is an object oriented extension to Tcl. [incr Tcl] seems ideal for dealing with structures and things you might want to do to them, or, in object oriented speak, methods you want them to do to themselves, I suppose. Well, how do you connect an existing program with a scripting language like Tcl? Particularly since Tcl doesn't understand what to do with C structures? There's this really cool tool called SWIG, or Simplified Wrapper and Interface Generator. Not only can it generate Tcl and [incr Tcl] code to interface with a program or libraries data structures, but it can handle many other scripting language, including Perl, Python, Ruby, and PHP. Since the only one of these languages I really know is Tcl (I know, it's a hole in my personal knowledge base), I'm using SWIG to generate Tcl and [incr Tcl] code. SWIG is pretty good at understanding structures with relatively basic types, like int, double, char, etc., and simple pointers types. But when it gets to something like char *foo[1024], i.e. an array of 1024 pointers to char, it needs some help. That's where you start using typemaps to convert from C types to scripting language types and back. While Tcl has arrays, they're associative arrays, i.e. their indices can be any string. C's arrays have numeric indices starting at 0. While it seems to me conceivable that you could map those numeric indices to their string counterparts, i.e. 0 to "0", 1 to "1", etc., SWIG doesn't seem to have a way to do that. At any rate, I decided to convert my global char *foo[1024] to a Tcl list when foo is referenced, and convert from a Tcl list to the C array when setting. Works really well, when it works. I'll have another posting about using MDB to figure out why it wasn't working! So what would be the alternative to SWIG? Write your own interfaces to the various structures. SWIG makes this really easy and is a big productivity booster.

Like this post? del.icio.us | furl | slashdot | technorati | digg