debug.c File Reference

Debugging support. More...

#include "internal.h"
Include dependency graph for debug.c:

Go to the source code of this file.

Functions

void tm_msg_enable (const char *codes, int enable)
 Enable or disable messages.
void tm_msg (const char *format,...)
 Prints messages to tm_msg_file.
void tm_msg1 (const char *format,...)
 Format additional message data.
void _tm_assert (const char *expr, const char *file, int lineno)
 Format assertion error.
void tm_validate_lists ()
 Validate internal lists against bookkeeping stats.

Variables

const char * tm_color_name []
 Color names.
const char * tm_struct_name []
 Struct names.
const char * tm_phase_name []
 Phase names.
FILE * tm_msg_file = 0
 Debug message file handle.
const char * tm_msg_prefix = ""
const char * tm_msg_enable_default
 Default messaages to enable.
int tm_msg_enable_all = 0
 Enable all messages?



int _tm_sweep_is_error = 0
 If true and sweep occurs, raise a error.
void tm_stop ()
 Put a debugger break point here!
void tm_fatal ()
 Fatal, non-recoverable internal error.
void tm_abort ()
 Abort after printing stats.
int _tm_check_sweep_error ()
 Checks for a unexpected node sweep.

Detailed Description

Debugging support.

Definition in file debug.c.


Function Documentation

int _tm_check_sweep_error (  ) 

Checks for a unexpected node sweep.

If a sweep occured at this time, the mark phase created a free tm_node (tm_WHITE) when it should not have.

TM failed to mark all tm_nodes as in-use (tm_GREY, or tm_BLACK).

This can be considered a bug in:

  • The write barrier.
  • Mutators that failed to use the write barrier.
  • Locating nodes for potential pointers.
  • Other book-keeping or list management.

OK: A sweep is not considered an error.

OK: Nothing was left unmarked.

ERROR: There were some unmarked (tm_ECRU) tm_nodes.

Print each unmarked node.

Print stats.

Attempt to mark all roots.

Scan all marked nodes.

Was there still unmarked nodes?

Mark all the tm_ECRU nodes tm_BLACK

Start tm_UNMARK phase.

Assert there is no unmarked nodes.

Stop in debugger?

Clear worst alloc time.

Return 1 to signal an error.

Definition at line 343 of file debug.c.

References _tm_node_scan_all(), _tm_phase_init(), _tm_root_scan_all(), tm_type::color_list, tm_data::n, tm_type::n, tm_type::size, tm, tm_assert_test, tm_BLACK, tm_color_name, tm_ECRU, tm_list_LOOP, tm_list_LOOP_END, tm_msg(), tm_node_color, tm_node_set_color(), tm_node_to_block(), tm_node_to_ptr(), tm_print_stats(), tm_ROOT, tm_SCAN, tm_stop(), tm_UNMARK, tm_data::ts_alloc, tm_time_stat::tw, and tm_data::types.

Referenced by _tm_node_sweep_some().

00344 {
00345   tm_type *t;
00346   tm_node *n;
00347 
00348   /*! OK: A sweep is not considered an error. */
00349   if ( ! _tm_sweep_is_error ) {
00350     return 0;
00351   }
00352 
00353   /*! OK: Nothing was left unmarked. */
00354   if ( ! tm.n[tm_ECRU] ) {
00355     return 0;
00356   }
00357 
00358   /*! ERROR: There were some unmarked (tm_ECRU) tm_nodes. */
00359   tm_msg("Fatal %lu dead nodes; there should be no sweeping.\n", tm.n[tm_ECRU]);
00360   tm_stop();
00361   // tm_validate_lists();
00362   
00363   /*! Print each unmarked node. */
00364   tm_list_LOOP(&tm.types, t);
00365   {
00366     tm_list_LOOP(&t->color_list[tm_ECRU], n);
00367     {
00368       tm_assert_test(tm_node_color(n) == tm_ECRU);
00369       tm_msg("Fatal node %p color %s size %lu should not be sweeped!\n", 
00370              (void*) n, 
00371              tm_color_name[tm_node_color(n)], 
00372              (unsigned long) t->size);
00373       {
00374         void ** vpa = tm_node_to_ptr(n);
00375         tm_msg("Fatal cons (%d, %p)\n", ((long) vpa[0]) >> 2, vpa[1]);
00376       }
00377     }
00378     tm_list_LOOP_END;
00379   }
00380   tm_list_LOOP_END;
00381   
00382   /*! Print stats. */
00383   tm_print_stats();
00384   
00385   /*! Attempt to mark all roots. */
00386   _tm_phase_init(tm_ROOT);
00387   _tm_root_scan_all();
00388   
00389   /*! Scan all marked nodes. */
00390   _tm_phase_init(tm_SCAN);
00391   _tm_node_scan_all();
00392   
00393   /*! Was there still unmarked nodes? */
00394   if ( tm.n[tm_ECRU] ) {
00395     tm_msg("Fatal after root mark: still missing %lu references.\n",
00396            (unsigned long) tm.n[tm_ECRU]);
00397   } else {
00398     tm_msg("Fatal after root mark: OK, missing references found!\n");
00399   }
00400   
00401   /*! Mark all the tm_ECRU nodes tm_BLACK */
00402   tm_list_LOOP(&tm.types, t);
00403   {
00404     tm_list_LOOP(&t->color_list[tm_ECRU], n);
00405     {
00406       tm_node_set_color(n, tm_node_to_block(n), tm_BLACK);
00407     }
00408     tm_list_LOOP_END;
00409   }
00410   tm_list_LOOP_END;
00411   
00412   /*! Start tm_UNMARK phase. */
00413   _tm_phase_init(tm_UNMARK);
00414   
00415   /*! Assert there is no unmarked nodes. */
00416   tm_assert_test(tm.n[tm_ECRU] == 0);
00417   
00418   /*! Stop in debugger? */
00419   tm_stop();
00420   
00421   /*! Clear worst alloc time. */
00422   memset(&tm.ts_alloc.tw, 0, sizeof(tm.ts_alloc.tw));
00423   
00424   /*! Return 1 to signal an error. */
00425   return 1;
00426 }

Here is the call graph for this function:

Here is the caller graph for this function:

void tm_abort (  ) 

Abort after printing stats.

Definition at line 194 of file debug.c.

References tm_data::inited, tm, tm_fatal(), and tm_print_stats().

Referenced by _tm_alloc_type_inner(), _tm_node_mark(), _tm_os_alloc_(), _tm_print_utilization(), tm_node_iterator_next(), tm_root_subtract(), and tm_write_barrier_node().

00195 {
00196   static int in_abort; /* THREAD? */
00197 
00198   ++ in_abort;
00199 
00200   if ( in_abort == 1 && tm.inited ) {
00201     tm_print_stats();
00202   }
00203 
00204   -- in_abort;
00205 
00206   tm_fatal();
00207 }

Here is the call graph for this function:

Here is the caller graph for this function:

void tm_fatal (  ) 

Fatal, non-recoverable internal error.

Definition at line 182 of file debug.c.

References tm_msg(), and tm_stop().

Referenced by _tm_phase_init(), and tm_abort().

00183 {
00184   tm_msg("Fatal Aborting!\n");
00185 
00186   tm_stop();
00187 
00188   abort();
00189 }

Here is the call graph for this function:

Here is the caller graph for this function:

void tm_stop (  ) 

Put a debugger break point here!

Definition at line 175 of file debug.c.

Referenced by _tm_alloc_type_inner(), _tm_check_sweep_error(), _tm_phase_init(), and tm_fatal().

00176 {
00177 }

Here is the caller graph for this function:


Variable Documentation

If true and sweep occurs, raise a error.

Definition at line 326 of file debug.c.

Referenced by _tm_gc_full_type_inner().

const char* tm_color_name[]
Initial value:
 {
  "WHITE", 
  "ECRU",  
  "GREY",  
  "BLACK", 

  "TOTAL", 

  "b",     
  "n",     
  "u",     
  "p",     

  "O",     
  "o",     
  "P",     
  "p",     
  0
}

Color names.

Definition at line 10 of file debug.c.

Referenced by _tm_check_sweep_error(), _tm_print_utilization(), tm_node_iterator_next(), tm_print_block_stats(), and tm_print_color_transition_stats().

const char* tm_phase_name[]
Initial value:
 {
  "ALLOC",  
  "UNMARK", 
  "ROOTS",  
  "SCAN",   
  "SWEEP",  
  "Total",  
}

Phase names.

Definition at line 40 of file debug.c.

Referenced by _tm_phase_init(), tm_init(), and tm_print_phase_transition_stats().

const char* tm_struct_name[]
Initial value:
 {
  "FREE_BLOCK",
  "LIVE_BLOCK",
  "FREE_TYPE",
  "LIVE_TYPE",
  0
}

Struct names.

Definition at line 31 of file debug.c.


Generated on Mon Jan 25 06:33:12 2010 for TM(tredmill) by  doxygen 1.6.1