ATLAS Offline Software
hexdump.cxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration.
3  */
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 
20 namespace {
21 // Number of bytes to dump on one line.
22 constexpr unsigned int width = 16;
23 }
24 
25 
26 namespace CxxUtils {
27 
28 
37 void 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 
104 void 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  size_t pagesize = sysconf (_SC_PAGESIZE);
116 
117  procmaps m;
118 
119  // Print page by page.
120  while (n > 0) {
121  uintptr_t iptr = reinterpret_cast<uintptr_t>(ptr);
122  size_t thispage = ((iptr + pagesize) & ~(pagesize-1)) - iptr;
123  if (thispage > n) {
124  thispage = n;
125  }
126  const procmaps::Entry* ent = m.getEntry (ptr);
127  if (ent && ent->readable) {
128  hexdump (s, ptr, thispage, offset);
129  }
130  else {
131  boost::io::ios_all_saver saver (s);
132  std::hex (s);
133  s.fill ('0');
134  s << std::setw(16) << reinterpret_cast<uintptr_t>(ptr) - offset
135  << " --- is not readable\n";
136  if (ent) {
137  thispage = std::max (ent->endAddress - iptr, thispage);
138  }
139  }
140  ptr += thispage;
141  n -= thispage;
142  }
143 }
144 
145 
146 } // namespace CxxUtils
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:104
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
python.SystemOfUnits.m
int m
Definition: SystemOfUnits.py:91
max
#define max(a, b)
Definition: cfImp.cxx:41
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
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:37
procmaps.h
lumiFormat.i
int i
Definition: lumiFormat.py:92
beamspotman.n
n
Definition: beamspotman.py:731
procmaps::Entry::readable
bool readable
Definition: procmaps.h:24
CxxUtils
Definition: aligned_vector.h:29
hexdump.h
Helpers to make a nice dump of a region of memory.
procmaps::Entry::endAddress
unsigned long endAddress
Definition: procmaps.h:23
Base_Fragment.width
width
Definition: Sherpa_i/share/common/Base_Fragment.py:59
procmaps
A simple API to access /proc/self/maps info.
Definition: procmaps.h:18
procmaps::Entry
Definition: procmaps.h:20
convertTimingResiduals.offset
offset
Definition: convertTimingResiduals.py:71