ATLAS Offline Software
Loading...
Searching...
No Matches
hexdump.cxx
Go to the documentation of this file.
1/*
2 * Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration.
3 */
10
11
12#include "CxxUtils/hexdump.h"
13#include "CxxUtils/procmaps.h"
14#include "boost/io/ios_state.hpp"
15#include <iomanip>
16#include <cstdint>
17#include <unistd.h>
18
19
20namespace {
21// Number of bytes to dump on one line.
22constexpr unsigned int width = 16;
23}
24
25
26namespace CxxUtils {
27
28
37void hexdump (std::ostream& s, const void* addr, size_t n, size_t offset /*= 0*/)
38{
39 const char* ptr = reinterpret_cast<const char*> (addr);
40 size_t ipos = 0;
41
42 boost::io::ios_all_saver saver (s);
43 std::hex (s);
44 s.fill ('0');
45
46 char cbuf[width + 1] = {0};
47 union {
48 uint32_t u32;
49 unsigned char uc[4];
50 } bbuf;
51
52 while (n-- > 0) {
53 if ((ipos % width) == 0) {
54 s << std::setw(16) << reinterpret_cast<uintptr_t>(ptr + ipos) - offset << " ";
55 }
56 if ((ipos % 4) == 0) {
57 s << " ";
58 }
59 bbuf.uc[ipos % 4] = ptr[ipos];
60 cbuf[ipos % width] = std::isgraph (ptr[ipos]) ? ptr[ipos] : '.';
61
62 ++ipos;
63 if ((ipos % 4) == 0) {
64 s << std::setw(8) << static_cast<unsigned int>(bbuf.u32);
65 }
66 if ((ipos % width) == 0) {
67 s << " " << cbuf << "\n";
68 }
69 }
70
71 if ((ipos % width) > 0) {
72 unsigned ntrail = (ipos % 4);
73 if (ntrail > 0) {
74 for (unsigned i = ntrail; i < 4; i++) {
75 bbuf.uc[i] = 0;
76 }
77 s << std::setw(2*ntrail) << static_cast<unsigned int>(bbuf.u32);
78 }
79 while ((ipos % width) != 0) {
80 if ((ipos % 4) == 0) {
81 s << " ";
82 }
83 s << " ";
84 cbuf[ipos % width] = ' ';
85 ++ipos;
86 }
87 s << " " << cbuf << "\n";
88 }
89}
90
91
104void safeHexdump (std::ostream& s, const void* addr, size_t n, size_t offset /*= 0*/)
105{
106 const char* ptr = reinterpret_cast<const char*> (addr);
107
108 // Adjust to start at width-byte boundary.
109 size_t nadj = reinterpret_cast<uintptr_t>(ptr) % width;
110 if (nadj > 0) {
111 ptr -= nadj;
112 n += nadj;
113 }
114
115 long pagesize_ret = sysconf (_SC_PAGESIZE);
116 if (pagesize_ret < 0 || pagesize_ret >= 1024*1024*1024) {
117 std::abort();
118 }
119 size_t pagesize = pagesize_ret;
120
121
122 procmaps m;
123
124 // Print page by page.
125 while (n > 0) {
126 uintptr_t iptr = reinterpret_cast<uintptr_t>(ptr);
127 size_t thispage = ((iptr + pagesize) & ~(pagesize-1)) - iptr;
128 if (thispage > n) {
129 thispage = n;
130 }
131 const procmaps::Entry* ent = m.getEntry (ptr);
132 if (ent && ent->readable) {
133 hexdump (s, ptr, thispage, offset);
134 }
135 else {
136 boost::io::ios_all_saver saver (s);
137 std::hex (s);
138 s.fill ('0');
139 s << std::setw(16) << reinterpret_cast<uintptr_t>(ptr) - offset
140 << " --- is not readable\n";
141 if (ent) {
142 thispage = std::max (ent->endAddress - iptr, thispage);
143 }
144 }
145 ptr += thispage;
146 n -= thispage;
147 }
148}
149
150
151} // namespace CxxUtils
const double width
On stopMonitoring/finalize the handler is uninstalled.
Definition procmaps.h:18
Helpers to make a nice dump of a region of memory.
void hexdump(std::ostream &s, const void *addr, size_t n, size_t offset=0)
Make a hex dump of memory.
Definition hexdump.cxx:37
void safeHexdump(std::ostream &s, const void *addr, size_t n, size_t offset=0)
Make a hex dump of memory, protected against bad reads.
Definition hexdump.cxx:104
unsigned long endAddress
Definition procmaps.h:23