14. DEBUGGING WITH ORGANIZED C

14.1 Using a Regular Debugger
14.2 Interactive Browser

14.1 Using a Regular Debugger

All OrgC++ calls, whether they are macros or compiled functions, are encapsulated in hyper-classes. You can use your regular debugger to debug the program. You should not debug OrgC++ functions just as you do not debug a C++ runtime library. If you step through the program, skip over calls with the prefix ZZ.

If you insist on looking inside ZZ macros, read Chap.16; it explains the whole setup.

Automatically generated pointers that hide under ZZ_EXT_ statements cannot be accessed from the outside - they are in the private part of your classes. Even though you can find the names of these pointers in zzincl.h, do not try to access them directly. For example, if you want, as part of your debugging, to find the next object on a ring, use the function fwd() and not a direct pointer jump. Always use only OrgC++ calls to access the data, even when you are debugging.

For an experienced C or C++ programmer who is used to working with pointers all the time this may be shocking news. Not use pointers, even when debugging? Simply consider the pointers that form the data organization to be off-limits. The library has been debugged and well tested. As you will see with time, if you get any errors, they will be most likely in your code or in how you call OrgC++ functions, not inside them. If you find anything wrong or strange, call Code Farms.

It is a good strategy to design your program with testing in mind. As you code the program, prepare utility functions that print subsets of your data, and insert calls to these functions as needed during debugging. With all the iterators that OrgC++ provides, coding such functions is trivial.

This strategy is usually more effective than stepping through the code and checking individual pointers. Remember that, when using OrgC++, you work with data of a much higher level. You should not be concerned about individual pointers.

All this advice assumes, of course, that you are debugging a program which uses the existing OrgC++ library. If you are testing a new organization or functions that you developed yourself and added to the library, the situation is different. Chap.16.5 describes how to proceed in such a situation.

14.2 Interactive Browser

Organized C allows you to display internal data and traverse it object by object. This can be done either in standalone mode, for example when examining disk files, or from inside your program as part of debugging.

As we explained above, there should never be a situation which would require you to debug individual relations between the data. However, for the debugging of your application, it may sometimes be useful to browse through the data.

Using this feature is very simple. You need

#define ZZascii

and a ZZ_FORMAT() statement for each class that has ZZ_EXT.

If your program saves in binary format, use util.mode(0,..) before any calls to save() or open().

At the place where you want to invoke interactive debugging, call void util.debug(void *ptr,char *type). For example, the sample printout below comes from a program which deals with classes Block, Net and Pin.

ZZ_HYPER_UTILITIES(util) 
Block *bp;
...
util.debug(bp,"Block");

This call puts you into an interactive mode where, starting from a given object, you can traverse the adjacent objects by typing the code number of the pointer. Code -1 returns you to the previous object (reverse move), and can be repeated any number of times. Code 0 exits the interactive part and transfers control back to your program.

As you can see from the example below, the program displays both the pointers and the attributes of the objects.

The first letter of each pointer name indicates its purpose - it matches the character used in the tables from the 'zzmaster' file. For example, c=child, p=parent, f=forward, b=backward, n=name, and so on. The second part of each name is the name of the organization, as declared in the ZZ_HYPER_.. statement. The arrow indicates to what object type the pointer is leading.

The following example corresponds to the problem from test0d.c, where objects Block, Net and Pin are connected in a netlist:

object=151755162 type=Block:
1: 1517551652 cbyBlock->Pin
2: 1517552080 fbChain->Block
3: 1517551648 nbName name=B1
x1=10 y1=0 x2=15 y2=5
select pointer(-1 retrace, 0 exit):1

object=1517551652 type=Pin:
1: 1517551760 sbyNet->Pin
2: 1517551692 sbyBlock->Pin
3: 1517551676 pbyNet->Net
4: 1517551624 pbyBlock->Block
x1=5 y1=2 x2=5 y2=2
select pointer(-1 retrace, 0 exit):3

object=1517551676 type=Net:
1: 1517551652 cbyNet->Pin
2: 1517551940 fnChain->Net
3: 1517551688 nnName name=N1
select pointer(-1 retrace, 0 exit):-1

object=1517551652 type=Pin:
1: 1517551760 sbyNet->Pin
2: 1517551692 sbyBlock->Pin
3: 1517551676 pbyNet->Net
4: 1517551624 pbyBlock->Block
|x1=5 y1=2 x2=5 y2=2
select pointer(-1 retrace, 0 exit):4

object=1517551624 type=Block:
1: 1517551652 cbyBlock->Pin
2: 1517552080 fbChain->Block
3: 1517551648 nbName name=B1
x1=10 y1=0 x2=15 y2=5
select pointer(-1 retrace, 0 exit):0

Example:

The use of the browser is the same in C and C++. For an example in C, look at test24.c.

 

Chapter 13: Memory Management and Saving on Disk Chapter 15: Reporting Errors