Coverage Report

Created: 2026-10-28 18:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hdf5/src/H5Odbg.c
Line
Count
Source
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
 * Copyright by The HDF Group.                                               *
3
 * All rights reserved.                                                      *
4
 *                                                                           *
5
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
6
 * terms governing use, modification, and redistribution, is contained in    *
7
 * the LICENSE file, which can be found at the root of the source code       *
8
 * distribution tree, or in https://www.hdfgroup.org/licenses.               *
9
 * If you do not have access to either file, you may request a copy from     *
10
 * help@hdfgroup.org.                                                        *
11
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13
/*-------------------------------------------------------------------------
14
 *
15
 * Created:   H5Odbg.c
16
 *
17
 * Purpose:   Object header debugging routines.
18
 *
19
 *-------------------------------------------------------------------------
20
 */
21
22
/****************/
23
/* Module Setup */
24
/****************/
25
26
#include "H5Omodule.h" /* This source code file is part of the H5O module */
27
28
/***********/
29
/* Headers */
30
/***********/
31
#include "H5private.h"   /* Generic Functions     */
32
#include "H5Eprivate.h"  /* Error handling        */
33
#include "H5MMprivate.h" /* Memory management     */
34
#include "H5Opkg.h"      /* Object headers      */
35
36
/****************/
37
/* Local Macros */
38
/****************/
39
40
/******************/
41
/* Local Typedefs */
42
/******************/
43
44
/********************/
45
/* Package Typedefs */
46
/********************/
47
48
/********************/
49
/* Local Prototypes */
50
/********************/
51
52
/*********************/
53
/* Package Variables */
54
/*********************/
55
56
/*****************************/
57
/* Library Private Variables */
58
/*****************************/
59
60
/*******************/
61
/* Local Variables */
62
/*******************/
63
64
/*-------------------------------------------------------------------------
65
 * Function:    H5O__print_time_field
66
 *
67
 * Purpose:     Format and print a time_t value as a debug field.
68
 *              Prints "(invalid time)" if localtime_r fails.
69
 *
70
 * Return:      void
71
 *-------------------------------------------------------------------------
72
 */
73
static void
74
H5O__print_time_field(FILE *stream, int indent, int fwidth, const char *label, const time_t *time_val)
75
0
{
76
0
    struct tm tm_buf;
77
0
    char      buf[128];
78
79
0
    if (HDlocaltime_r(time_val, &tm_buf) != NULL)
80
0
        strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %Z", &tm_buf);
81
0
    else
82
0
        snprintf(buf, sizeof(buf), "(invalid time)");
83
0
    fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, label, buf);
84
0
} /* end H5O__print_time_field() */
85
86
#ifdef H5O_DEBUG
87
88
/*-------------------------------------------------------------------------
89
 * Function:    H5O__assert
90
 *
91
 * Purpose:     Sanity check the information for an object header data
92
 *              structure.
93
 *
94
 * Return:      SUCCEED (Doesn't fail, just crashes)
95
 *
96
 *-------------------------------------------------------------------------
97
 */
98
herr_t
99
H5O__assert(const H5O_t *oh)
100
{
101
    H5O_mesg_t *curr_msg;            /* Pointer to current message to examine */
102
    H5O_mesg_t *tmp_msg;             /* Pointer to temporary message to examine */
103
    unsigned    cont_msgs_found = 0; /* # of continuation messages for object */
104
    size_t      meta_space;          /* Size of header metadata */
105
    size_t      mesg_space;          /* Size of message raw data */
106
    size_t      free_space;          /* Size of free space in header */
107
    size_t      hdr_size;            /* Size of header's chunks */
108
    unsigned    u, v;                /* Local index variables */
109
110
    FUNC_ENTER_PACKAGE_NOERR
111
112
    assert(oh);
113
    assert(oh->chunk || oh->nchunks == 0);
114
    assert(oh->mesg || oh->nmesgs == 0);
115
116
    /* Initialize the tracking variables */
117
    hdr_size   = 0;
118
    meta_space = (size_t)H5O_SIZEOF_HDR(oh) + (size_t)(H5O_SIZEOF_CHKHDR_OH(oh) * (oh->nchunks - 1));
119
    mesg_space = 0;
120
    free_space = 0;
121
122
    /* Loop over all chunks in object header */
123
    for (u = 0; u < oh->nchunks; u++) {
124
        /* Accumulate the size of the header on header */
125
        hdr_size += oh->chunk[u].size;
126
127
        /* If the chunk has a gap, add it to the free space */
128
        free_space += oh->chunk[u].gap;
129
130
        /* Check for valid raw data image */
131
        assert(oh->chunk[u].image);
132
        assert(oh->chunk[u].size > (size_t)H5O_SIZEOF_CHKHDR_OH(oh));
133
134
        /* All chunks must be allocated on disk */
135
        assert(H5_addr_defined(oh->chunk[u].addr));
136
137
        /* Version specific checks */
138
        if (oh->version > H5O_VERSION_1) {
139
            /* Make certain that the magic number is correct for each chunk */
140
            assert(!memcmp(oh->chunk[u].image, (u == 0 ? H5O_HDR_MAGIC : H5O_CHK_MAGIC), H5_SIZEOF_MAGIC));
141
142
            /* Check for valid gap size */
143
            assert(oh->chunk[u].gap < (size_t)H5O_SIZEOF_MSGHDR_OH(oh));
144
        } /* end if */
145
        else
146
            /* Gaps should never occur in version 1 of the format */
147
            assert(oh->chunk[u].gap == 0);
148
    } /* end for */
149
150
    /* Check for correct chunk #0 size flags */
151
    if (oh->version > H5O_VERSION_1) {
152
        uint64_t chunk0_size = oh->chunk[0].size - (size_t)H5O_SIZEOF_HDR(oh);
153
154
        if (chunk0_size <= 255)
155
            assert((oh->flags & H5O_HDR_CHUNK0_SIZE) == H5O_HDR_CHUNK0_1);
156
        else if (chunk0_size <= 65535)
157
            assert((oh->flags & H5O_HDR_CHUNK0_SIZE) == H5O_HDR_CHUNK0_2);
158
        else if (chunk0_size <= 4294967295)
159
            assert((oh->flags & H5O_HDR_CHUNK0_SIZE) == H5O_HDR_CHUNK0_4);
160
        else
161
            assert((oh->flags & H5O_HDR_CHUNK0_SIZE) == H5O_HDR_CHUNK0_8);
162
    } /* end if */
163
164
    /* Loop over all messages in object header */
165
    for (u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
166
        uint8_t H5_ATTR_NDEBUG_UNUSED *curr_hdr;      /* Start of current message header */
167
        size_t                         curr_tot_size; /* Total size of current message (including header) */
168
169
        assert(curr_msg->type);
170
171
        curr_hdr      = curr_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh);
172
        curr_tot_size = curr_msg->raw_size + (size_t)H5O_SIZEOF_MSGHDR_OH(oh);
173
174
        /* Accumulate information, based on the type of message */
175
        if (H5O_NULL_ID == curr_msg->type->id)
176
            free_space += curr_tot_size;
177
        else if (H5O_CONT_ID == curr_msg->type->id) {
178
            H5O_cont_t                *cont        = (H5O_cont_t *)curr_msg->native;
179
            bool H5_ATTR_NDEBUG_UNUSED found_chunk = false; /* Found a chunk that matches */
180
181
            assert(cont);
182
183
            /* Increment # of continuation messages found */
184
            cont_msgs_found++;
185
186
            /* Sanity check that every continuation message has a matching chunk */
187
            /* (and only one) */
188
            for (v = 0; v < oh->nchunks; v++) {
189
                if (H5_addr_eq(cont->addr, oh->chunk[v].addr) && cont->size == oh->chunk[v].size) {
190
                    assert(cont->chunkno == v);
191
                    assert(!found_chunk);
192
                    found_chunk = true;
193
                } /* end if */
194
            }     /* end for */
195
            assert(found_chunk);
196
197
            meta_space += curr_tot_size;
198
        } /* end if */
199
        else {
200
            meta_space += (size_t)H5O_SIZEOF_MSGHDR_OH(oh);
201
            mesg_space += curr_msg->raw_size;
202
203
            /* Make sure the message has a native form if it is marked dirty */
204
            assert(curr_msg->native || !curr_msg->dirty);
205
        } /* end else */
206
207
        /* Make certain that the message is in a valid chunk */
208
        assert(curr_msg->chunkno < oh->nchunks);
209
210
        /* Make certain null messages aren't in chunks with gaps */
211
        if (H5O_NULL_ID == curr_msg->type->id)
212
            assert(oh->chunk[curr_msg->chunkno].gap == 0);
213
214
        /* Make certain that the message is completely in a chunk message area */
215
        assert(curr_tot_size <= (oh->chunk[curr_msg->chunkno].size) -
216
                                    (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[curr_msg->chunkno].gap));
217
        if (curr_msg->chunkno == 0)
218
            assert(curr_hdr >=
219
                   oh->chunk[curr_msg->chunkno].image + (H5O_SIZEOF_HDR(oh) - H5O_SIZEOF_CHKSUM_OH(oh)));
220
        else
221
            assert(curr_hdr >= oh->chunk[curr_msg->chunkno].image +
222
                                   (H5O_SIZEOF_CHKHDR_OH(oh) - H5O_SIZEOF_CHKSUM_OH(oh)));
223
        assert(curr_msg->raw + curr_msg->raw_size <=
224
               (oh->chunk[curr_msg->chunkno].image + oh->chunk[curr_msg->chunkno].size) -
225
                   (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[curr_msg->chunkno].gap));
226
227
        /* Make certain that no other messages overlap this message */
228
        for (v = 0, tmp_msg = &oh->mesg[0]; v < oh->nmesgs; v++, tmp_msg++) {
229
            if (u != v)
230
                assert(!((tmp_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh)) >= curr_hdr &&
231
                         (tmp_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh)) < (curr_hdr + curr_tot_size)));
232
        } /* end for */
233
    }     /* end for */
234
235
    /* Sanity check that the # of cont. messages is correct for the # of chunks */
236
    assert(oh->nchunks == (cont_msgs_found + 1));
237
238
    /* Sanity check that all the bytes are accounted for */
239
    assert(hdr_size == (free_space + meta_space + mesg_space));
240
241
    FUNC_LEAVE_NOAPI(SUCCEED)
242
} /* end H5O__assert() */
243
#endif /* H5O_DEBUG */
244
245
/*-------------------------------------------------------------------------
246
 * Function:  H5O_debug_id
247
 *
248
 * Purpose: Act as a proxy for calling the 'debug' method for a
249
 *              particular class of object header.
250
 *
251
 * Return:  Non-negative on success/Negative on failure
252
 *
253
 *-------------------------------------------------------------------------
254
 */
255
herr_t
256
H5O_debug_id(unsigned type_id, H5F_t *f, const void *mesg, FILE *stream, int indent, int fwidth)
257
0
{
258
0
    const H5O_msg_class_t *type;             /* Actual H5O class type for the ID */
259
0
    herr_t                 ret_value = FAIL; /* Return value */
260
261
0
    FUNC_ENTER_NOAPI(FAIL)
262
263
    /* Check args */
264
0
    assert(type_id < NELMTS(H5O_msg_class_g));
265
0
    type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */
266
0
    assert(type);
267
0
    assert(type->debug);
268
0
    assert(f);
269
0
    assert(mesg);
270
0
    assert(stream);
271
0
    assert(indent >= 0);
272
0
    assert(fwidth >= 0);
273
274
    /* Call the debug method in the class */
275
0
    if ((ret_value = (type->debug)(f, mesg, stream, indent, fwidth)) < 0)
276
0
        HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, FAIL, "unable to debug message");
277
278
0
done:
279
0
    FUNC_LEAVE_NOAPI(ret_value)
280
0
} /* end H5O_debug_id() */
281
282
/*-------------------------------------------------------------------------
283
 * Function:    H5O__debug_real
284
 *
285
 * Purpose:     Prints debugging info about an object header.
286
 *
287
 * Return:      SUCCEED/FAIL
288
 *
289
 *-------------------------------------------------------------------------
290
 */
291
herr_t
292
H5O__debug_real(H5F_t *f, H5O_t *oh, haddr_t addr, FILE *stream, int indent, int fwidth)
293
0
{
294
0
    size_t    mesg_total = 0, chunk_total = 0, gap_total = 0;
295
0
    unsigned *sequence = NULL;
296
0
    unsigned  i; /* Local index variable */
297
0
    herr_t    ret_value = SUCCEED;
298
299
0
    FUNC_ENTER_PACKAGE
300
301
    /* check args */
302
0
    assert(f);
303
0
    assert(oh);
304
0
    assert(H5_addr_defined(addr));
305
0
    assert(stream);
306
0
    assert(indent >= 0);
307
0
    assert(fwidth >= 0);
308
309
    /* debug */
310
0
    fprintf(stream, "%*sObject Header...\n", indent, "");
311
312
0
    fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, "Dirty:", oh->cache_info.is_dirty ? "TRUE" : "FALSE");
313
0
    fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Version:", oh->version);
314
0
    fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
315
0
            "Header size (in bytes):", (unsigned)H5O_SIZEOF_HDR(oh));
316
0
    fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Number of links:", oh->nlink);
317
318
    /* Extra information for later versions */
319
0
    if (oh->version > H5O_VERSION_1) {
320
        /* Display object's status flags */
321
0
        fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, "Attribute creation order tracked:",
322
0
                (oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED) ? "Yes" : "No");
323
0
        fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, "Attribute creation order indexed:",
324
0
                (oh->flags & H5O_HDR_ATTR_CRT_ORDER_INDEXED) ? "Yes" : "No");
325
0
        fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, "Attribute storage phase change values:",
326
0
                (oh->flags & H5O_HDR_ATTR_STORE_PHASE_CHANGE) ? "Non-default" : "Default");
327
0
        fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
328
0
                "Timestamps:", (oh->flags & H5O_HDR_STORE_TIMES) ? "Enabled" : "Disabled");
329
0
        if (oh->flags & ~H5O_HDR_ALL_FLAGS)
330
0
            fprintf(stream, "*** UNKNOWN OBJECT HEADER STATUS FLAG: %02x!\n", (unsigned)oh->flags);
331
332
        /* Only dump times, if they are tracked */
333
0
        if (oh->flags & H5O_HDR_STORE_TIMES) {
334
0
            H5O__print_time_field(stream, indent, fwidth, "Access Time:", &oh->atime);
335
0
            H5O__print_time_field(stream, indent, fwidth, "Modification Time:", &oh->mtime);
336
0
            H5O__print_time_field(stream, indent, fwidth, "Change Time:", &oh->ctime);
337
0
            H5O__print_time_field(stream, indent, fwidth, "Birth Time:", &oh->btime);
338
0
        } /* end if */
339
340
        /* Attribute tracking fields */
341
0
        if (oh->flags & H5O_HDR_ATTR_STORE_PHASE_CHANGE) {
342
0
            fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
343
0
                    "Max. compact attributes:", (unsigned)oh->max_compact);
344
0
            fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
345
0
                    "Min. dense attributes:", (unsigned)oh->min_dense);
346
0
        } /* end if */
347
0
    }     /* end if */
348
349
0
    fprintf(stream, "%*s%-*s %zu (%zu)\n", indent, "", fwidth, "Number of messages (allocated):", oh->nmesgs,
350
0
            oh->alloc_nmesgs);
351
0
    fprintf(stream, "%*s%-*s %zu (%zu)\n", indent, "", fwidth, "Number of chunks (allocated):", oh->nchunks,
352
0
            oh->alloc_nchunks);
353
354
    /* debug each chunk */
355
0
    for (i = 0, chunk_total = 0; i < oh->nchunks; i++) {
356
0
        size_t chunk_size;
357
358
0
        fprintf(stream, "%*sChunk %d...\n", indent, "", i);
359
360
0
        fprintf(stream, "%*s%-*s %" PRIuHADDR "\n", indent + 3, "", MAX(0, fwidth - 3),
361
0
                "Address:", oh->chunk[i].addr);
362
363
        /* Decrement chunk 0's size by the object header prefix size */
364
0
        if (0 == i) {
365
0
            if (H5_addr_ne(oh->chunk[i].addr, addr))
366
0
                fprintf(stream, "*** WRONG ADDRESS FOR CHUNK #0!\n");
367
0
            chunk_size = oh->chunk[i].size - (size_t)H5O_SIZEOF_HDR(oh);
368
0
        } /* end if */
369
0
        else
370
0
            chunk_size = oh->chunk[i].size;
371
372
        /* Accumulate chunk's size to total */
373
0
        chunk_total += chunk_size;
374
0
        gap_total += oh->chunk[i].gap;
375
376
0
        fprintf(stream, "%*s%-*s %zu\n", indent + 3, "", MAX(0, fwidth - 3), "Size in bytes:", chunk_size);
377
378
0
        fprintf(stream, "%*s%-*s %zu\n", indent + 3, "", MAX(0, fwidth - 3), "Gap:", oh->chunk[i].gap);
379
0
    } /* end for */
380
381
    /* debug each message */
382
0
    if (NULL == (sequence = (unsigned *)H5MM_calloc(NELMTS(H5O_msg_class_g) * sizeof(unsigned))))
383
0
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
384
0
    for (i = 0, mesg_total = 0; i < oh->nmesgs; i++) {
385
0
        const H5O_msg_class_t *debug_type; /* Type of message to use for callbacks */
386
0
        unsigned               chunkno;    /* Chunk for message */
387
388
        /* Accumulate message's size to total */
389
0
        mesg_total += (size_t)H5O_SIZEOF_MSGHDR_OH(oh) + oh->mesg[i].raw_size;
390
391
        /* For version 2 object header, add size of "OCHK" for continuation chunk */
392
0
        if (oh->mesg[i].type->id == H5O_CONT_ID)
393
0
            mesg_total += H5O_SIZEOF_CHKHDR_OH(oh);
394
395
0
        fprintf(stream, "%*sMessage %d...\n", indent, "", i);
396
397
        /* check for bad message id */
398
0
        if (oh->mesg[i].type->id >= (int)NELMTS(H5O_msg_class_g)) {
399
0
            fprintf(stream, "*** BAD MESSAGE ID 0x%04x\n", oh->mesg[i].type->id);
400
0
            continue;
401
0
        } /* end if */
402
403
        /* message name and size */
404
0
        fprintf(stream, "%*s%-*s 0x%04x `%s' (%d)\n", indent + 3, "", MAX(0, fwidth - 3),
405
0
                "Message ID (sequence number):", (unsigned)(oh->mesg[i].type->id), oh->mesg[i].type->name,
406
0
                sequence[oh->mesg[i].type->id]++);
407
0
        fprintf(stream, "%*s%-*s %s\n", indent + 3, "", MAX(0, fwidth - 3),
408
0
                "Dirty:", oh->mesg[i].dirty ? "TRUE" : "FALSE");
409
0
        fprintf(stream, "%*s%-*s ", indent + 3, "", MAX(0, fwidth - 3), "Message flags:");
410
0
        if (oh->mesg[i].flags) {
411
0
            bool flag_printed = false;
412
413
            /* Sanity check that all flags in format are covered below */
414
0
            HDcompile_assert(H5O_MSG_FLAG_BITS ==
415
0
                             (H5O_MSG_FLAG_CONSTANT | H5O_MSG_FLAG_SHARED | H5O_MSG_FLAG_DONTSHARE |
416
0
                              H5O_MSG_FLAG_FAIL_IF_UNKNOWN_AND_OPEN_FOR_WRITE | H5O_MSG_FLAG_MARK_IF_UNKNOWN |
417
0
                              H5O_MSG_FLAG_WAS_UNKNOWN | H5O_MSG_FLAG_SHAREABLE |
418
0
                              H5O_MSG_FLAG_FAIL_IF_UNKNOWN_ALWAYS));
419
420
0
            if (oh->mesg[i].flags & H5O_MSG_FLAG_CONSTANT) {
421
0
                fprintf(stream, "%sC", (flag_printed ? ", " : "<"));
422
0
                flag_printed = true;
423
0
            } /* end if */
424
0
            if (oh->mesg[i].flags & H5O_MSG_FLAG_SHARED) {
425
0
                fprintf(stream, "%sS", (flag_printed ? ", " : "<"));
426
0
                flag_printed = true;
427
0
            } /* end if */
428
0
            if (oh->mesg[i].flags & H5O_MSG_FLAG_DONTSHARE) {
429
0
                fprintf(stream, "%sDS", (flag_printed ? ", " : "<"));
430
0
                flag_printed = true;
431
0
            } /* end if */
432
0
            if (oh->mesg[i].flags & H5O_MSG_FLAG_FAIL_IF_UNKNOWN_AND_OPEN_FOR_WRITE) {
433
0
                fprintf(stream, "%sFIUW", (flag_printed ? ", " : "<"));
434
0
                flag_printed = true;
435
0
            } /* end if */
436
0
            if (oh->mesg[i].flags & H5O_MSG_FLAG_MARK_IF_UNKNOWN) {
437
0
                fprintf(stream, "%sMIU", (flag_printed ? ", " : "<"));
438
0
                flag_printed = true;
439
0
            } /* end if */
440
0
            if (oh->mesg[i].flags & H5O_MSG_FLAG_WAS_UNKNOWN) {
441
0
                assert(oh->mesg[i].flags & H5O_MSG_FLAG_MARK_IF_UNKNOWN);
442
0
                fprintf(stream, "%sWU", (flag_printed ? ", " : "<"));
443
0
                flag_printed = true;
444
0
            } /* end if */
445
0
            if (oh->mesg[i].flags & H5O_MSG_FLAG_SHAREABLE) {
446
0
                fprintf(stream, "%sSA", (flag_printed ? ", " : "<"));
447
0
                flag_printed = true;
448
0
            } /* end if */
449
0
            if (oh->mesg[i].flags & H5O_MSG_FLAG_FAIL_IF_UNKNOWN_ALWAYS) {
450
0
                fprintf(stream, "%sFIUA", (flag_printed ? ", " : "<"));
451
0
                flag_printed = true;
452
0
            } /* end if */
453
0
            if (!flag_printed)
454
0
                fprintf(stream, "-");
455
0
            fprintf(stream, ">\n");
456
0
            if (oh->mesg[i].flags & ~H5O_MSG_FLAG_BITS)
457
0
                fprintf(stream, "%*s%-*s 0x%02x\n", indent + 3, "", MAX(0, fwidth - 3),
458
0
                        "*** ADDITIONAL UNKNOWN FLAGS --->", oh->mesg[i].flags & ~H5O_MSG_FLAG_BITS);
459
0
        } /* end if */
460
0
        else
461
0
            fprintf(stream, "<none>\n");
462
463
0
        fprintf(stream, "%*s%-*s %u\n", indent + 3, "", MAX(0, fwidth - 3),
464
0
                "Chunk number:", oh->mesg[i].chunkno);
465
0
        chunkno = oh->mesg[i].chunkno;
466
0
        if (chunkno >= oh->nchunks)
467
0
            fprintf(stream, "*** BAD CHUNK NUMBER\n");
468
0
        fprintf(stream, "%*s%-*s (%zu, %zu) bytes\n", indent + 3, "", MAX(0, fwidth - 3),
469
0
                "Raw message data (offset, size) in chunk:",
470
0
                (size_t)(oh->mesg[i].raw - oh->chunk[chunkno].image), oh->mesg[i].raw_size);
471
472
        /* check the size */
473
0
        if ((oh->mesg[i].raw + oh->mesg[i].raw_size > oh->chunk[chunkno].image + oh->chunk[chunkno].size) ||
474
0
            (oh->mesg[i].raw < oh->chunk[chunkno].image))
475
0
            fprintf(stream, "*** BAD MESSAGE RAW ADDRESS\n");
476
477
        /* decode the message */
478
0
        debug_type = oh->mesg[i].type;
479
0
        if (NULL == oh->mesg[i].native && debug_type->decode)
480
0
            H5O_LOAD_NATIVE(f, H5O_DECODEIO_NOCHANGE, oh, &oh->mesg[i], FAIL)
481
482
        /* print the message */
483
0
        fprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3), "Message Information:");
484
0
        if (debug_type->debug && oh->mesg[i].native != NULL)
485
0
            (debug_type->debug)(f, oh->mesg[i].native, stream, indent + 6, MAX(0, fwidth - 6));
486
0
        else
487
0
            fprintf(stream, "%*s<No info for this message>\n", indent + 6, "");
488
0
    } /* end for */
489
490
0
    if ((mesg_total + gap_total) != chunk_total)
491
0
        fprintf(stream, "*** TOTAL SIZE DOES NOT MATCH ALLOCATED SIZE!\n");
492
493
0
done:
494
    /* Release resources */
495
0
    if (sequence)
496
0
        sequence = (unsigned *)H5MM_xfree(sequence);
497
498
0
    FUNC_LEAVE_NOAPI(ret_value)
499
0
} /* end H5O__debug_real() */
500
501
/*-------------------------------------------------------------------------
502
 * Function:  H5O_debug
503
 *
504
 * Purpose: Prints debugging info about an object header.
505
 *
506
 * Return:  Non-negative on success/Negative on failure
507
 *
508
 *-------------------------------------------------------------------------
509
 */
510
herr_t
511
H5O_debug(H5F_t *f, haddr_t addr, FILE *stream, int indent, int fwidth)
512
0
{
513
0
    H5O_t    *oh = NULL;           /* Object header to display */
514
0
    H5O_loc_t loc;                 /* Object location for object to delete */
515
0
    herr_t    ret_value = SUCCEED; /* Return value */
516
517
0
    FUNC_ENTER_NOAPI(FAIL)
518
519
    /* check args */
520
0
    assert(f);
521
0
    assert(H5_addr_defined(addr));
522
0
    assert(stream);
523
0
    assert(indent >= 0);
524
0
    assert(fwidth >= 0);
525
526
    /* Set up the object location */
527
0
    loc.file         = f;
528
0
    loc.addr         = addr;
529
0
    loc.holding_file = false;
530
531
0
    if (NULL == (oh = H5O_protect(&loc, H5AC__READ_ONLY_FLAG, false)))
532
0
        HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header");
533
534
    /* debug */
535
0
    if (H5O__debug_real(f, oh, addr, stream, indent, fwidth) < 0)
536
0
        HGOTO_ERROR(H5E_OHDR, H5E_SYSTEM, FAIL, "debug dump call failed");
537
538
0
done:
539
0
    if (oh && H5O_unprotect(&loc, oh, H5AC__NO_FLAGS_SET) < 0)
540
0
        HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header");
541
542
0
    FUNC_LEAVE_NOAPI(ret_value)
543
0
} /* end H5O_debug() */