ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Control
CxxUtils
Root
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 <format>
15
#include <cstdint>
16
#include <array>
17
#include <bit>
18
#include <unistd.h>
19
20
21
namespace
{
22
// Number of bytes to dump on one line.
23
constexpr
unsigned
int
width
= 16;
24
}
25
26
27
namespace
CxxUtils
{
28
29
38
void
hexdump
(std::ostream& s,
const
void
* addr,
size_t
n,
size_t
offset
/*= 0*/
)
39
{
40
const
char
* ptr =
reinterpret_cast<
const
char
*
>
(addr);
41
size_t
ipos = 0;
42
43
char
cbuf[
width
+ 1]{};
44
std::array<unsigned char, 4> bbuf{};
45
46
while
(n-- > 0) {
47
if
((ipos %
width
) == 0) {
48
s << std::format(
"{:016x} "
,
reinterpret_cast<
uintptr_t
>
(ptr + ipos) - offset);
49
}
50
if
((ipos % 4) == 0) {
51
s <<
" "
;
52
}
53
bbuf[ipos % 4] =
static_cast<
unsigned
char
>
(ptr[ipos]);
54
cbuf[ipos %
width
] = std::isgraph(
static_cast<
unsigned
char
>
(ptr[ipos])) ? ptr[ipos] :
'.'
;
55
56
++ipos;
57
if
((ipos % 4) == 0) {
58
s << std::format(
"{:08x}"
,
static_cast<
unsigned
int
>
(std::bit_cast<uint32_t>(bbuf)));
59
}
60
if
((ipos %
width
) == 0) {
61
s <<
" "
<< cbuf <<
"\n"
;
62
}
63
}
64
65
if
((ipos %
width
) > 0) {
66
unsigned
ntrail = (ipos % 4);
67
if
(ntrail > 0) {
68
for
(
unsigned
i = ntrail; i < 4; i++) {
69
bbuf[i] = 0;
70
}
71
s << std::format(
"{:0{}x}"
,
static_cast<
unsigned
int
>
(std::bit_cast<uint32_t>(bbuf)), 2*ntrail);
72
}
73
while
((ipos %
width
) != 0) {
74
if
((ipos % 4) == 0) {
75
s <<
" "
;
76
}
77
s <<
" "
;
78
cbuf[ipos %
width
] =
' '
;
79
++ipos;
80
}
81
s <<
" "
<< cbuf <<
"\n"
;
82
}
83
}
84
85
98
void
safeHexdump
(std::ostream& s,
const
void
* addr,
size_t
n,
size_t
offset
/*= 0*/
)
99
{
100
const
char
* ptr =
reinterpret_cast<
const
char
*
>
(addr);
101
102
// Adjust to start at width-byte boundary.
103
size_t
nadj =
reinterpret_cast<
uintptr_t
>
(ptr) %
width
;
104
if
(nadj > 0) {
105
ptr -= nadj;
106
n += nadj;
107
}
108
109
long
pagesize_ret = sysconf (_SC_PAGESIZE);
110
if
(pagesize_ret < 0 || pagesize_ret >= 1024*1024*1024) {
111
std::abort();
112
}
113
size_t
pagesize = pagesize_ret;
114
115
116
procmaps
m;
117
118
// Print page by page.
119
while
(n > 0) {
120
uintptr_t iptr =
reinterpret_cast<
uintptr_t
>
(ptr);
121
size_t
thispage = ((iptr + pagesize) & ~(pagesize-1)) - iptr;
122
if
(thispage > n) {
123
thispage = n;
124
}
125
const
procmaps::Entry
* ent = m.getEntry (ptr);
126
if
(ent && ent->
readable
) {
127
hexdump
(s, ptr, thispage, offset);
128
}
129
else
{
130
s << std::format(
"{:016x} --- is not readable\n"
,
131
reinterpret_cast<
uintptr_t
>
(ptr) - offset);
132
if
(ent) {
133
thispage = std::max (ent->
endAddress
- iptr, thispage);
134
}
135
}
136
ptr += thispage;
137
n -= thispage;
138
}
139
}
140
141
142
}
// namespace CxxUtils
width
const double width
Definition
TTileTripReader.cxx:24
procmaps
On stopMonitoring/finalize the handler is uninstalled.
Definition
procmaps.h:18
hexdump.h
Helpers to make a nice dump of a region of memory.
CxxUtils
Definition
aligned_vector.h:29
CxxUtils::hexdump
void hexdump(std::ostream &s, const void *addr, size_t n, size_t offset=0)
Make a hex dump of memory.
Definition
hexdump.cxx:38
CxxUtils::safeHexdump
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:98
procmaps.h
procmaps::Entry
Definition
procmaps.h:20
procmaps::Entry::readable
bool readable
Definition
procmaps.h:24
procmaps::Entry::endAddress
unsigned long endAddress
Definition
procmaps.h:23
Generated on
for ATLAS Offline Software by
1.17.0