diff options
Diffstat (limited to 'src/third_party/wiredtiger/src/btree/bt_debug.c')
-rw-r--r-- | src/third_party/wiredtiger/src/btree/bt_debug.c | 473 |
1 files changed, 250 insertions, 223 deletions
diff --git a/src/third_party/wiredtiger/src/btree/bt_debug.c b/src/third_party/wiredtiger/src/btree/bt_debug.c index b1579d25dc6..c1560150435 100644 --- a/src/third_party/wiredtiger/src/btree/bt_debug.c +++ b/src/third_party/wiredtiger/src/btree/bt_debug.c @@ -12,45 +12,47 @@ /* * We pass around a session handle and output information, group it together. */ -typedef struct { +typedef struct __wt_dbg WT_DBG; +struct __wt_dbg { WT_SESSION_IMPL *session; /* Enclosing session */ /* * When using the standard event handlers, the debugging output has to * do its own message handling because its output isn't line-oriented. */ - FILE *fp; + FILE *fp; /* Optional file handle */ WT_ITEM *msg; /* Buffered message */ + int (*f)(WT_DBG *, const char *, ...) /* Function to write */ + WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 2, 3))); + WT_ITEM *tmp; /* Temporary space */ -} WT_DBG; +}; static const /* Output separator */ char * const sep = "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; -static int __debug_cell(WT_DBG *, const WT_PAGE_HEADER *, WT_CELL_UNPACK *); -static int __debug_cell_data( +static int __debug_cell(WT_DBG *, const WT_PAGE_HEADER *, WT_CELL_UNPACK *); +static int __debug_cell_data( WT_DBG *, WT_PAGE *, int type, const char *, WT_CELL_UNPACK *); -static void __debug_col_skip(WT_DBG *, WT_INSERT_HEAD *, const char *, bool); -static int __debug_config(WT_SESSION_IMPL *, WT_DBG *, const char *); -static int __debug_dsk_cell(WT_DBG *, const WT_PAGE_HEADER *); -static void __debug_dsk_col_fix(WT_DBG *, const WT_PAGE_HEADER *); -static void __debug_item(WT_DBG *, const char *, const void *, size_t); -static int __debug_page(WT_DBG *, WT_REF *, uint32_t); -static void __debug_page_col_fix(WT_DBG *, WT_REF *); -static int __debug_page_col_int(WT_DBG *, WT_PAGE *, uint32_t); -static int __debug_page_col_var(WT_DBG *, WT_REF *); -static int __debug_page_metadata(WT_DBG *, WT_REF *); -static int __debug_page_row_int(WT_DBG *, WT_PAGE *, uint32_t); -static int __debug_page_row_leaf(WT_DBG *, WT_PAGE *); -static void __debug_ref(WT_DBG *, WT_REF *); -static void __debug_row_skip(WT_DBG *, WT_INSERT_HEAD *); -static int __debug_tree( +static int __debug_col_skip(WT_DBG *, WT_INSERT_HEAD *, const char *, bool); +static int __debug_config(WT_SESSION_IMPL *, WT_DBG *, const char *); +static int __debug_dsk_cell(WT_DBG *, const WT_PAGE_HEADER *); +static int __debug_dsk_col_fix(WT_DBG *, const WT_PAGE_HEADER *); +static int __debug_item(WT_DBG *, const char *, const void *, size_t); +static int __debug_page(WT_DBG *, WT_REF *, uint32_t); +static int __debug_page_col_fix(WT_DBG *, WT_REF *); +static int __debug_page_col_int(WT_DBG *, WT_PAGE *, uint32_t); +static int __debug_page_col_var(WT_DBG *, WT_REF *); +static int __debug_page_metadata(WT_DBG *, WT_REF *); +static int __debug_page_row_int(WT_DBG *, WT_PAGE *, uint32_t); +static int __debug_page_row_leaf(WT_DBG *, WT_PAGE *); +static int __debug_ref(WT_DBG *, WT_REF *); +static int __debug_row_skip(WT_DBG *, WT_INSERT_HEAD *); +static int __debug_tree( WT_SESSION_IMPL *, WT_BTREE *, WT_REF *, const char *, uint32_t); -static void __debug_update(WT_DBG *, WT_UPDATE *, bool); -static void __dmsg(WT_DBG *, const char *, ...) - WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 2, 3))); -static void __dmsg_wrapup(WT_DBG *); +static int __debug_update(WT_DBG *, WT_UPDATE *, bool); +static int __dmsg_wrapup(WT_DBG *); /* * __wt_debug_set_verbose -- @@ -71,10 +73,80 @@ __wt_debug_set_verbose(WT_SESSION_IMPL *session, const char *v) * __debug_hex_byte -- * Output a single byte in hex. */ -static inline void +static inline int __debug_hex_byte(WT_DBG *ds, uint8_t v) { - __dmsg(ds, "#%c%c", __wt_hex[(v & 0xf0) >> 4], __wt_hex[v & 0x0f]); + return (ds->f( + ds, "#%c%c", __wt_hex[(v & 0xf0) >> 4], __wt_hex[v & 0x0f])); +} + +/* + * __dmsg_event -- + * Send a debug message to the event handler. + */ +static int +__dmsg_event(WT_DBG *ds, const char *fmt, ...) +{ + WT_ITEM *msg; + WT_SESSION_IMPL *session; + size_t len, space; + va_list ap; + char *p; + + session = ds->session; + + /* + * Debug output chunks are not necessarily terminated with a newline + * character. It's easy if we're dumping to a stream, but if we're + * dumping to an event handler, which is line-oriented, we must buffer + * the output chunk, and pass it to the event handler once we see a + * terminating newline. + */ + msg = ds->msg; + for (;;) { + p = (char *)msg->mem + msg->size; + space = msg->memsize - msg->size; + va_start(ap, fmt); + len = (size_t)vsnprintf(p, space, fmt, ap); + va_end(ap); + + /* Check if there was enough space. */ + if (len < space) { + msg->size += len; + break; + } + + /* + * There's not much to do on error without checking for + * an error return on every single printf. Anyway, it's + * pretty unlikely and this is debugging output, I'm not + * going to worry about it. + */ + WT_RET(__wt_buf_grow(session, msg, msg->memsize + len + 128)); + } + if (((uint8_t *)msg->mem)[msg->size - 1] == '\n') { + ((uint8_t *)msg->mem)[msg->size - 1] = '\0'; + WT_RET(__wt_msg(session, "%s", (char *)msg->mem)); + msg->size = 0; + } + + return (0); +} + +/* + * __dmsg_file -- + * Send a debug message to a file. + */ +static int +__dmsg_file(WT_DBG *ds, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + (void)vfprintf(ds->fp, fmt, ap); + va_end(ap); + + return (0); } /* @@ -94,12 +166,15 @@ __debug_config(WT_SESSION_IMPL *session, WT_DBG *ds, const char *ofile) * If we weren't given a file, we use the default event handler, and * we'll have to buffer messages. */ - if (ofile == NULL) - return (__wt_scr_alloc(session, 512, &ds->msg)); - - if ((ds->fp = fopen(ofile, "w")) == NULL) - return (EIO); - __wt_stream_set_line_buffer(ds->fp); + if (ofile == NULL) { + WT_RET(__wt_scr_alloc(session, 512, &ds->msg)); + ds->f = __dmsg_event; + } else { + if ((ds->fp = fopen(ofile, "w")) == NULL) + return (EIO); + __wt_stream_set_line_buffer(ds->fp); + ds->f = __dmsg_file; + } return (0); } @@ -108,7 +183,7 @@ __debug_config(WT_SESSION_IMPL *session, WT_DBG *ds, const char *ofile) * __dmsg_wrapup -- * Flush any remaining output, release resources. */ -static void +static int __dmsg_wrapup(WT_DBG *ds) { WT_SESSION_IMPL *session; @@ -125,72 +200,15 @@ __dmsg_wrapup(WT_DBG *ds) */ if (msg != NULL) { if (msg->size != 0) - (void)__wt_msg(session, "%s", (char *)msg->mem); + WT_RET(__wt_msg(session, "%s", (char *)msg->mem)); __wt_scr_free(session, &ds->msg); } /* Close any file we opened. */ if (ds->fp != NULL) (void)fclose(ds->fp); -} -/* - * __dmsg -- - * Debug message. - */ -static void -__dmsg(WT_DBG *ds, const char *fmt, ...) -{ - va_list ap; - WT_ITEM *msg; - WT_SESSION_IMPL *session; - size_t len, space; - char *p; - - session = ds->session; - - /* - * Debug output chunks are not necessarily terminated with a newline - * character. It's easy if we're dumping to a stream, but if we're - * dumping to an event handler, which is line-oriented, we must buffer - * the output chunk, and pass it to the event handler once we see a - * terminating newline. - */ - if (ds->fp == NULL) { - msg = ds->msg; - for (;;) { - p = (char *)msg->mem + msg->size; - space = msg->memsize - msg->size; - va_start(ap, fmt); - len = (size_t)vsnprintf(p, space, fmt, ap); - va_end(ap); - - /* Check if there was enough space. */ - if (len < space) { - msg->size += len; - break; - } - - /* - * There's not much to do on error without checking for - * an error return on every single printf. Anyway, it's - * pretty unlikely and this is debugging output, I'm not - * going to worry about it. - */ - if (__wt_buf_grow( - session, msg, msg->memsize + len + 128) != 0) - return; - } - if (((uint8_t *)msg->mem)[msg->size - 1] == '\n') { - ((uint8_t *)msg->mem)[msg->size - 1] = '\0'; - (void)__wt_msg(session, "%s", (char *)msg->mem); - msg->size = 0; - } - } else { - va_start(ap, fmt); - (void)vfprintf(ds->fp, fmt, ap); - va_end(ap); - } + return (0); } /* @@ -314,69 +332,66 @@ __wt_debug_disk( WT_SESSION_IMPL *session, const WT_PAGE_HEADER *dsk, const char *ofile) { WT_DBG *ds, _ds; - WT_DECL_RET; ds = &_ds; WT_RET(__debug_config(session, ds, ofile)); - __dmsg(ds, "%s page", __wt_page_type_string(dsk->type)); + WT_RET(ds->f(ds, "%s page", __wt_page_type_string(dsk->type))); switch (dsk->type) { case WT_PAGE_BLOCK_MANAGER: break; case WT_PAGE_COL_FIX: case WT_PAGE_COL_INT: case WT_PAGE_COL_VAR: - __dmsg(ds, ", recno %" PRIu64, dsk->recno); + WT_RET(ds->f(ds, ", recno %" PRIu64, dsk->recno)); /* FALLTHROUGH */ case WT_PAGE_ROW_INT: case WT_PAGE_ROW_LEAF: - __dmsg(ds, ", entries %" PRIu32, dsk->u.entries); + WT_RET(ds->f(ds, ", entries %" PRIu32, dsk->u.entries)); break; case WT_PAGE_OVFL: - __dmsg(ds, ", datalen %" PRIu32, dsk->u.datalen); + WT_RET(ds->f(ds, ", datalen %" PRIu32, dsk->u.datalen)); break; WT_ILLEGAL_VALUE(session); } if (F_ISSET(dsk, WT_PAGE_COMPRESSED)) - __dmsg(ds, ", compressed"); + WT_RET(ds->f(ds, ", compressed")); if (F_ISSET(dsk, WT_PAGE_ENCRYPTED)) - __dmsg(ds, ", encrypted"); + WT_RET(ds->f(ds, ", encrypted")); if (F_ISSET(dsk, WT_PAGE_EMPTY_V_ALL)) - __dmsg(ds, ", empty-all"); + WT_RET(ds->f(ds, ", empty-all")); if (F_ISSET(dsk, WT_PAGE_EMPTY_V_NONE)) - __dmsg(ds, ", empty-none"); + WT_RET(ds->f(ds, ", empty-none")); if (F_ISSET(dsk, WT_PAGE_LAS_UPDATE)) - __dmsg(ds, ", LAS-update"); + WT_RET(ds->f(ds, ", LAS-update")); - __dmsg(ds, ", generation %" PRIu64 "\n", dsk->write_gen); + WT_RET(ds->f(ds, ", generation %" PRIu64 "\n", dsk->write_gen)); switch (dsk->type) { case WT_PAGE_BLOCK_MANAGER: break; case WT_PAGE_COL_FIX: - __debug_dsk_col_fix(ds, dsk); + WT_RET(__debug_dsk_col_fix(ds, dsk)); break; case WT_PAGE_COL_INT: case WT_PAGE_COL_VAR: case WT_PAGE_ROW_INT: case WT_PAGE_ROW_LEAF: - ret = __debug_dsk_cell(ds, dsk); + WT_RET(__debug_dsk_cell(ds, dsk)); break; default: break; } - __dmsg_wrapup(ds); - - return (ret); + return (__dmsg_wrapup(ds)); } /* * __debug_dsk_col_fix -- * Dump a WT_PAGE_COL_FIX page. */ -static void +static int __debug_dsk_col_fix(WT_DBG *ds, const WT_PAGE_HEADER *dsk) { WT_BTREE *btree; @@ -388,10 +403,11 @@ __debug_dsk_col_fix(WT_DBG *ds, const WT_PAGE_HEADER *dsk) btree = S2BT(ds->session); WT_FIX_FOREACH(btree, dsk, v, i) { - __dmsg(ds, "\t{"); - __debug_hex_byte(ds, v); - __dmsg(ds, "}\n"); + WT_RET(ds->f(ds, "\t{")); + WT_RET(__debug_hex_byte(ds, v)); + WT_RET(ds->f(ds, "}\n")); } + return (0); } /* @@ -444,7 +460,7 @@ __debug_tree_shape_info(WT_PAGE *page) * __debug_tree_shape_worker -- * Dump information about the current page and descend. */ -static void +static int __debug_tree_shape_worker(WT_DBG *ds, WT_PAGE *page, int level) { WT_REF *ref; @@ -453,16 +469,17 @@ __debug_tree_shape_worker(WT_DBG *ds, WT_PAGE *page, int level) session = ds->session; if (WT_PAGE_IS_INTERNAL(page)) { - __dmsg(ds, "%*s" "I" "%d %s\n", - level * 3, " ", level, __debug_tree_shape_info(page)); + WT_RET(ds->f(ds, "%*s" "I" "%d %s\n", + level * 3, " ", level, __debug_tree_shape_info(page))); WT_INTL_FOREACH_BEGIN(session, page, ref) { if (ref->state == WT_REF_MEM) - __debug_tree_shape_worker( - ds, ref->page, level + 1); + WT_RET(__debug_tree_shape_worker( + ds, ref->page, level + 1)); } WT_INTL_FOREACH_END; } else - __dmsg(ds, "%*s" "L" " %s\n", - level * 3, " ", __debug_tree_shape_info(page)); + WT_RET(ds->f(ds, "%*s" "L" " %s\n", + level * 3, " ", __debug_tree_shape_info(page))); + return (0); } /* @@ -474,6 +491,7 @@ __wt_debug_tree_shape( WT_SESSION_IMPL *session, WT_PAGE *page, const char *ofile) { WT_DBG *ds, _ds; + WT_DECL_RET; WT_ASSERT(session, S2BT_SAFE(session) != NULL); @@ -484,10 +502,11 @@ __wt_debug_tree_shape( if (page == NULL) page = S2BT(session)->root.page; - WT_WITH_PAGE_INDEX(session, __debug_tree_shape_worker(ds, page, 1)); + WT_WITH_PAGE_INDEX(session, + ret = __debug_tree_shape_worker(ds, page, 1)); + WT_RET(ret); - __dmsg_wrapup(ds); - return (0); + return (__dmsg_wrapup(ds)); } #define WT_DEBUG_TREE_LEAF 0x01 /* Debug leaf pages */ @@ -530,18 +549,15 @@ int __wt_debug_page(WT_SESSION_IMPL *session, WT_REF *ref, const char *ofile) { WT_DBG *ds, _ds; - WT_DECL_RET; WT_ASSERT(session, S2BT_SAFE(session) != NULL); ds = &_ds; WT_RET(__debug_config(session, ds, ofile)); - ret = __debug_page(ds, ref, WT_DEBUG_TREE_LEAF); - - __dmsg_wrapup(ds); + WT_RET(__debug_page(ds, ref, WT_DEBUG_TREE_LEAF)); - return (ret); + return (__dmsg_wrapup(ds)); } /* @@ -567,10 +583,9 @@ __debug_tree(WT_SESSION_IMPL *session, ref = &btree->root; WT_WITH_BTREE(session, btree, ret = __debug_page(ds, ref, flags)); + WT_RET(ret); - __dmsg_wrapup(ds); - - return (ret); + return (__dmsg_wrapup(ds)); } /* @@ -593,7 +608,7 @@ __debug_page(WT_DBG *ds, WT_REF *ref, uint32_t flags) switch (ref->page->type) { case WT_PAGE_COL_FIX: if (LF_ISSET(WT_DEBUG_TREE_LEAF)) - __debug_page_col_fix(ds, ref); + WT_RET(__debug_page_col_fix(ds, ref)); break; case WT_PAGE_COL_INT: WT_WITH_PAGE_INDEX(session, @@ -636,20 +651,20 @@ __debug_page_metadata(WT_DBG *ds, WT_REF *ref) page = ref->page; mod = page->modify; - __dmsg(ds, "%p", (void *)page); + WT_RET(ds->f(ds, "%p", (void *)page)); switch (page->type) { case WT_PAGE_COL_INT: - __dmsg(ds, " recno %" PRIu64, ref->ref_recno); + WT_RET(ds->f(ds, " recno %" PRIu64, ref->ref_recno)); WT_INTL_INDEX_GET(session, page, pindex); entries = pindex->entries; break; case WT_PAGE_COL_FIX: - __dmsg(ds, " recno %" PRIu64, ref->ref_recno); + WT_RET(ds->f(ds, " recno %" PRIu64, ref->ref_recno)); entries = page->pg_fix_entries; break; case WT_PAGE_COL_VAR: - __dmsg(ds, " recno %" PRIu64, ref->ref_recno); + WT_RET(ds->f(ds, " recno %" PRIu64, ref->ref_recno)); entries = page->pg_var_entries; break; case WT_PAGE_ROW_INT: @@ -662,48 +677,50 @@ __debug_page_metadata(WT_DBG *ds, WT_REF *ref) WT_ILLEGAL_VALUE(session); } - __dmsg(ds, ": %s\n", __wt_page_type_string(page->type)); - __dmsg(ds, - "\t" "disk %p, entries %" PRIu32, (void *)page->dsk, entries); - __dmsg(ds, ", %s", __wt_page_is_modified(page) ? "dirty" : "clean"); - __dmsg(ds, ", %s", __wt_fair_islocked( - session, &page->page_lock) ? "locked" : "unlocked"); + WT_RET(ds->f(ds, ": %s\n", __wt_page_type_string(page->type))); + WT_RET(ds->f(ds, + "\t" "disk %p, entries %" PRIu32, (void *)page->dsk, entries)); + WT_RET(ds->f(ds, + ", %s", __wt_page_is_modified(page) ? "dirty" : "clean")); + WT_RET(ds->f(ds, ", %s", __wt_rwlock_islocked( + session, &page->page_lock) ? "locked" : "unlocked")); if (F_ISSET_ATOMIC(page, WT_PAGE_BUILD_KEYS)) - __dmsg(ds, ", keys-built"); + WT_RET(ds->f(ds, ", keys-built")); if (F_ISSET_ATOMIC(page, WT_PAGE_DISK_ALLOC)) - __dmsg(ds, ", disk-alloc"); + WT_RET(ds->f(ds, ", disk-alloc")); if (F_ISSET_ATOMIC(page, WT_PAGE_DISK_MAPPED)) - __dmsg(ds, ", disk-mapped"); + WT_RET(ds->f(ds, ", disk-mapped")); if (F_ISSET_ATOMIC(page, WT_PAGE_EVICT_LRU)) - __dmsg(ds, ", evict-lru"); + WT_RET(ds->f(ds, ", evict-lru")); if (F_ISSET_ATOMIC(page, WT_PAGE_OVERFLOW_KEYS)) - __dmsg(ds, ", overflow-keys"); + WT_RET(ds->f(ds, ", overflow-keys")); if (F_ISSET_ATOMIC(page, WT_PAGE_SPLIT_BLOCK)) - __dmsg(ds, ", split-block"); + WT_RET(ds->f(ds, ", split-block")); if (F_ISSET_ATOMIC(page, WT_PAGE_SPLIT_INSERT)) - __dmsg(ds, ", split-insert"); + WT_RET(ds->f(ds, ", split-insert")); if (F_ISSET_ATOMIC(page, WT_PAGE_UPDATE_IGNORE)) - __dmsg(ds, ", update-ignore"); + WT_RET(ds->f(ds, ", update-ignore")); if (mod != NULL) switch (mod->rec_result) { case WT_PM_REC_EMPTY: - __dmsg(ds, ", empty"); + WT_RET(ds->f(ds, ", empty")); break; case WT_PM_REC_MULTIBLOCK: - __dmsg(ds, ", multiblock"); + WT_RET(ds->f(ds, ", multiblock")); break; case WT_PM_REC_REPLACE: - __dmsg(ds, ", replaced"); + WT_RET(ds->f(ds, ", replaced")); break; case 0: break; WT_ILLEGAL_VALUE(session); } if (mod != NULL) - __dmsg(ds, ", write generation=%" PRIu32, mod->write_gen); - __dmsg(ds, "\n"); + WT_RET( + ds->f(ds, ", write generation=%" PRIu32, mod->write_gen)); + WT_RET(ds->f(ds, "\n")); return (0); } @@ -712,7 +729,7 @@ __debug_page_metadata(WT_DBG *ds, WT_REF *ref) * __debug_page_col_fix -- * Dump an in-memory WT_PAGE_COL_FIX page. */ -static void +static int __debug_page_col_fix(WT_DBG *ds, WT_REF *ref) { WT_BTREE *btree; @@ -735,16 +752,15 @@ __debug_page_col_fix(WT_DBG *ds, WT_REF *ref) if (dsk != NULL) { ins = WT_SKIP_FIRST(WT_COL_UPDATE_SINGLE(page)); WT_FIX_FOREACH(btree, dsk, v, i) { - __dmsg(ds, "\t%" PRIu64 "\t{", recno); - __debug_hex_byte(ds, v); - __dmsg(ds, "}\n"); + WT_RET(ds->f(ds, "\t%" PRIu64 "\t{", recno)); + WT_RET(__debug_hex_byte(ds, v)); + WT_RET(ds->f(ds, "}\n")); /* Check for a match on the update list. */ if (ins != NULL && WT_INSERT_RECNO(ins) == recno) { - __dmsg(ds, - "\tupdate %" PRIu64 "\n", - WT_INSERT_RECNO(ins)); - __debug_update(ds, ins->upd, true); + WT_RET(ds->f(ds, "\tupdate %" PRIu64 "\n", + WT_INSERT_RECNO(ins))); + WT_RET(__debug_update(ds, ins->upd, true)); ins = WT_SKIP_NEXT(ins); } ++recno; @@ -752,14 +768,16 @@ __debug_page_col_fix(WT_DBG *ds, WT_REF *ref) } if (WT_COL_UPDATE_SINGLE(page) != NULL) { - __dmsg(ds, "%s", sep); - __debug_col_skip( - ds, WT_COL_UPDATE_SINGLE(page), "update", true); + WT_RET(ds->f(ds, "%s", sep)); + WT_RET(__debug_col_skip( + ds, WT_COL_UPDATE_SINGLE(page), "update", true)); } if (WT_COL_APPEND(page) != NULL) { - __dmsg(ds, "%s", sep); - __debug_col_skip(ds, WT_COL_APPEND(page), "append", true); + WT_RET(ds->f(ds, "%s", sep)); + WT_RET(__debug_col_skip(ds, + WT_COL_APPEND(page), "append", true)); } + return (0); } /* @@ -775,14 +793,14 @@ __debug_page_col_int(WT_DBG *ds, WT_PAGE *page, uint32_t flags) session = ds->session; WT_INTL_FOREACH_BEGIN(session, page, ref) { - __dmsg(ds, "\trecno %" PRIu64 "\n", ref->ref_recno); - __debug_ref(ds, ref); + WT_RET(ds->f(ds, "\trecno %" PRIu64 "\n", ref->ref_recno)); + WT_RET(__debug_ref(ds, ref)); } WT_INTL_FOREACH_END; if (LF_ISSET(WT_DEBUG_TREE_WALK)) WT_INTL_FOREACH_BEGIN(session, page, ref) { if (ref->state == WT_REF_MEM) { - __dmsg(ds, "\n"); + WT_RET(ds->f(ds, "\n")); WT_RET(__debug_page(ds, ref, flags)); } } WT_INTL_FOREACH_END; @@ -823,13 +841,14 @@ __debug_page_col_var(WT_DBG *ds, WT_REF *ref) __debug_cell_data(ds, page, WT_PAGE_COL_VAR, tag, unpack)); if ((update = WT_COL_UPDATE(page, cip)) != NULL) - __debug_col_skip(ds, update, "update", false); + WT_RET(__debug_col_skip(ds, update, "update", false)); recno += rle; } if (WT_COL_APPEND(page) != NULL) { - __dmsg(ds, "%s", sep); - __debug_col_skip(ds, WT_COL_APPEND(page), "append", false); + WT_RET(ds->f(ds, "%s", sep)); + WT_RET(__debug_col_skip(ds, + WT_COL_APPEND(page), "append", false)); } return (0); @@ -851,14 +870,14 @@ __debug_page_row_int(WT_DBG *ds, WT_PAGE *page, uint32_t flags) WT_INTL_FOREACH_BEGIN(session, page, ref) { __wt_ref_key(page, ref, &p, &len); - __debug_item(ds, "K", p, len); - __debug_ref(ds, ref); + WT_RET(__debug_item(ds, "K", p, len)); + WT_RET(__debug_ref(ds, ref)); } WT_INTL_FOREACH_END; if (LF_ISSET(WT_DEBUG_TREE_WALK)) WT_INTL_FOREACH_BEGIN(session, page, ref) { if (ref->state == WT_REF_MEM) { - __dmsg(ds, "\n"); + WT_RET(ds->f(ds, "\n")); WT_RET(__debug_page(ds, ref, flags)); } } WT_INTL_FOREACH_END; @@ -891,15 +910,15 @@ __debug_page_row_leaf(WT_DBG *ds, WT_PAGE *page) * key on the page. */ if ((insert = WT_ROW_INSERT_SMALLEST(page)) != NULL) - __debug_row_skip(ds, insert); + WT_ERR(__debug_row_skip(ds, insert)); /* Dump the page's K/V pairs. */ WT_ROW_FOREACH(page, rip, i) { WT_ERR(__wt_row_leaf_key(session, page, rip, key, false)); - __debug_item(ds, "K", key->data, key->size); + WT_ERR(__debug_item(ds, "K", key->data, key->size)); if ((cell = __wt_row_leaf_value_cell(page, rip, NULL)) == NULL) - __dmsg(ds, "\tV {}\n"); + WT_ERR(ds->f(ds, "\tV {}\n")); else { __wt_cell_unpack(cell, unpack); WT_ERR(__debug_cell_data( @@ -907,10 +926,10 @@ __debug_page_row_leaf(WT_DBG *ds, WT_PAGE *page) } if ((upd = WT_ROW_UPDATE(page, rip)) != NULL) - __debug_update(ds, upd, false); + WT_ERR(__debug_update(ds, upd, false)); if ((insert = WT_ROW_INSERT(page, rip)) != NULL) - __debug_row_skip(ds, insert); + WT_ERR(__debug_row_skip(ds, insert)); } err: __wt_scr_free(session, &key); @@ -921,59 +940,63 @@ err: __wt_scr_free(session, &key); * __debug_col_skip -- * Dump a column-store skiplist. */ -static void +static int __debug_col_skip( WT_DBG *ds, WT_INSERT_HEAD *head, const char *tag, bool hexbyte) { WT_INSERT *ins; WT_SKIP_FOREACH(ins, head) { - __dmsg(ds, - "\t%s %" PRIu64 "\n", tag, WT_INSERT_RECNO(ins)); - __debug_update(ds, ins->upd, hexbyte); + WT_RET(ds->f(ds, + "\t%s %" PRIu64 "\n", tag, WT_INSERT_RECNO(ins))); + WT_RET(__debug_update(ds, ins->upd, hexbyte)); } + return (0); } /* * __debug_row_skip -- * Dump an insert list. */ -static void +static int __debug_row_skip(WT_DBG *ds, WT_INSERT_HEAD *head) { WT_INSERT *ins; WT_SKIP_FOREACH(ins, head) { - __debug_item(ds, - "insert", WT_INSERT_KEY(ins), WT_INSERT_KEY_SIZE(ins)); - __debug_update(ds, ins->upd, false); + WT_RET(__debug_item(ds, + "insert", WT_INSERT_KEY(ins), WT_INSERT_KEY_SIZE(ins))); + WT_RET(__debug_update(ds, ins->upd, false)); } + return (0); } /* * __debug_update -- * Dump an update list. */ -static void +static int __debug_update(WT_DBG *ds, WT_UPDATE *upd, bool hexbyte) { for (; upd != NULL; upd = upd->next) if (WT_UPDATE_DELETED_ISSET(upd)) - __dmsg(ds, "\tvalue {deleted}\n"); + WT_RET(ds->f(ds, "\tvalue {deleted}\n")); else if (hexbyte) { - __dmsg(ds, "\t{"); - __debug_hex_byte(ds, *(uint8_t *)WT_UPDATE_DATA(upd)); - __dmsg(ds, "}\n"); + WT_RET(ds->f(ds, "\t{")); + WT_RET(__debug_hex_byte(ds, + *(uint8_t *)WT_UPDATE_DATA(upd))); + WT_RET(ds->f(ds, "}\n")); } else - __debug_item(ds, - "value", WT_UPDATE_DATA(upd), upd->size); + WT_RET(__debug_item(ds, + "value", WT_UPDATE_DATA(upd), upd->size)); + return (0); } /* * __debug_ref -- * Dump a WT_REF structure. */ -static void +static int __debug_ref(WT_DBG *ds, WT_REF *ref) { WT_SESSION_IMPL *session; @@ -982,34 +1005,34 @@ __debug_ref(WT_DBG *ds, WT_REF *ref) session = ds->session; - __dmsg(ds, "\t"); + WT_RET(ds->f(ds, "\t")); switch (ref->state) { case WT_REF_DISK: - __dmsg(ds, "disk"); + WT_RET(ds->f(ds, "disk")); break; case WT_REF_DELETED: - __dmsg(ds, "deleted"); + WT_RET(ds->f(ds, "deleted")); break; case WT_REF_LOCKED: - __dmsg(ds, "locked %p", (void *)ref->page); + WT_RET(ds->f(ds, "locked %p", (void *)ref->page)); break; case WT_REF_MEM: - __dmsg(ds, "memory %p", (void *)ref->page); + WT_RET(ds->f(ds, "memory %p", (void *)ref->page)); break; case WT_REF_READING: - __dmsg(ds, "reading"); + WT_RET(ds->f(ds, "reading")); break; case WT_REF_SPLIT: - __dmsg(ds, "split"); + WT_RET(ds->f(ds, "split")); break; default: - __dmsg(ds, "INVALID"); + WT_RET(ds->f(ds, "INVALID")); break; } __wt_ref_info(ref, &addr, &addr_size, NULL); - __dmsg(ds, " %s\n", - __wt_addr_string(session, addr, addr_size, ds->tmp)); + return (ds->f(ds, " %s\n", + __wt_addr_string(session, addr, addr_size, ds->tmp))); } /* @@ -1026,15 +1049,15 @@ __debug_cell(WT_DBG *ds, const WT_PAGE_HEADER *dsk, WT_CELL_UNPACK *unpack) session = ds->session; - __dmsg(ds, "\t%s: len %" PRIu32, - __wt_cell_type_string(unpack->raw), unpack->size); + WT_RET(ds->f(ds, "\t%s: len %" PRIu32, + __wt_cell_type_string(unpack->raw), unpack->size)); /* Dump cell's per-disk page type information. */ switch (dsk->type) { case WT_PAGE_COL_INT: switch (unpack->type) { case WT_CELL_VALUE: - __dmsg(ds, ", recno: %" PRIu64, unpack->v); + WT_RET(ds->f(ds, ", recno: %" PRIu64, unpack->v)); break; } break; @@ -1045,7 +1068,8 @@ __debug_cell(WT_DBG *ds, const WT_PAGE_HEADER *dsk, WT_CELL_UNPACK *unpack) case WT_CELL_VALUE: case WT_CELL_VALUE_OVFL: case WT_CELL_VALUE_OVFL_RM: - __dmsg(ds, ", rle: %" PRIu64, __wt_cell_rle(unpack)); + WT_RET(ds->f(ds, + ", rle: %" PRIu64, __wt_cell_rle(unpack))); break; } break; @@ -1053,7 +1077,7 @@ __debug_cell(WT_DBG *ds, const WT_PAGE_HEADER *dsk, WT_CELL_UNPACK *unpack) case WT_PAGE_ROW_LEAF: switch (unpack->type) { case WT_CELL_KEY: - __dmsg(ds, ", pfx: %" PRIu8, unpack->prefix); + WT_RET(ds->f(ds, ", pfx: %" PRIu8, unpack->prefix)); break; } break; @@ -1079,13 +1103,14 @@ __debug_cell(WT_DBG *ds, const WT_PAGE_HEADER *dsk, WT_CELL_UNPACK *unpack) case WT_CELL_VALUE_OVFL_RM: type = "ovfl"; addr: WT_RET(__wt_scr_alloc(session, 128, &buf)); - __dmsg(ds, ", %s %s", type, - __wt_addr_string(session, unpack->data, unpack->size, buf)); + WT_RET(ds->f(ds, ", %s %s", type, + __wt_addr_string( + session, unpack->data, unpack->size, buf))); __wt_scr_free(session, &buf); WT_RET(ret); break; } - __dmsg(ds, "\n"); + WT_RET(ds->f(ds, "\n")); return (__debug_cell_data(ds, NULL, dsk->type, NULL, unpack)); } @@ -1110,7 +1135,7 @@ __debug_cell_data(WT_DBG *ds, * reference. */ if (unpack == NULL) { - __debug_item(ds, tag, "deleted", strlen("deleted")); + WT_RET(__debug_item(ds, tag, "deleted", strlen("deleted"))); return (0); } @@ -1123,7 +1148,7 @@ __debug_cell_data(WT_DBG *ds, case WT_CELL_KEY_OVFL_RM: case WT_CELL_VALUE_OVFL_RM: p = __wt_cell_type_string(unpack->raw); - __debug_item(ds, tag, p, strlen(p)); + WT_RET(__debug_item(ds, tag, p, strlen(p))); break; case WT_CELL_KEY: case WT_CELL_KEY_OVFL: @@ -1139,7 +1164,7 @@ __debug_cell_data(WT_DBG *ds, __wt_dsk_cell_data_ref(session, page_type, unpack, buf) : __wt_page_cell_data_ref(session, page, unpack, buf); if (ret == 0) - __debug_item(ds, tag, buf->data, buf->size); + WT_RET(__debug_item(ds, tag, buf->data, buf->size)); __wt_scr_free(session, &buf); break; WT_ILLEGAL_VALUE(session); @@ -1152,21 +1177,23 @@ __debug_cell_data(WT_DBG *ds, * __debug_item -- * Dump a single data/size pair, with an optional tag. */ -static void +static int __debug_item(WT_DBG *ds, const char *tag, const void *data_arg, size_t size) { size_t i; u_char ch; const uint8_t *data; - __dmsg(ds, "\t%s%s{", tag == NULL ? "" : tag, tag == NULL ? "" : " "); + WT_RET(ds->f(ds, + "\t%s%s{", tag == NULL ? "" : tag, tag == NULL ? "" : " ")); for (data = data_arg, i = 0; i < size; ++i, ++data) { ch = data[0]; if (__wt_isprint(ch)) - __dmsg(ds, "%c", (int)ch); + WT_RET(ds->f(ds, "%c", (int)ch)); else - __debug_hex_byte(ds, data[0]); + WT_RET(__debug_hex_byte(ds, data[0])); } - __dmsg(ds, "}\n"); + WT_RET(ds->f(ds, "}\n")); + return (0); } #endif |