Debugging support. More...
#include "internal.h"
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. |
Debugging support.
Definition in file debug.c.
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:
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 }
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 }
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().
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().
int _tm_sweep_is_error = 0 |
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[] |
{ "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[] |
{ "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[] |