Tracing

When debugging we quite often want to trace a particular instance of a data-structure. For instance, we know that an int_stack allocated at address 0x100480 is erroneously returning a 5 at some point; but we don't know where it was pushed. While it is possible to trace data-structures using a debugger, if the program is large enough, it can be very time consuming. In such cases it makes sense to build it into the program.

To start off, we define a function trace() that is used to output the tracing messages.


	#include <stdarg.h>
	#include <stdio.h>

	void
	trace(
		const char *	file,
		int		line,
		const void *	pointer,
		const char *	fmt,
		...
		)
	{
	  va_list	args;
	  static int	count;

	  fprintf(stderr, "TRACE %d: [%s %d]: %p: ",
	  	count, file, line, pointer);
	  va_start(args, fmt);
	  vfprintf(stderr, fmt, args);
	  va_end(args);
	  fputc('\n', stderr);
	  count++;
	}

We could output the tracing messages from the ADT itself; however, the trace() function allows us to have a convenient place to set breakpoints in the debugger. The count variable allows tracing points that not interesting to be skipped, either through the use of conditional debugging, or by counted continue.

To implement tracing in the ADT, we first need to be able to define the instance that is traced. This is stored in lcl_trace_int_stack.



	static int_stack	lcl_trace_int_stack = 0;

	void
	setup_trace_int_stack(
		int_stack	stack
		)
	{
	  lcl_trace_int_stack = stack;
	}

Then we need to add the tracing code. Here are a few examples.


	int_stack
	make_int_stack(void)
	{
	  /* ... */

	  if( stack == lcl_trace_int_stack ) {
	    monitor(__FILE__, __LINE__, stack, "make_int_stack");
	  }
	  return stack;
	}

	void
	push_int_stack(
		int_stack	stack,
		int		val
		)
	{
	  /* ... */

	  if( stack == lcl_trace_int_stack ) {
	    monitor(__FILE__, __LINE__, stack, "push_int_stack %d", val);
	  }

	  /* ... */
	}


Next Prev Main Top Feedback