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