Skip to content

Commit c4783d4

Browse files
committed
Fix some issues with "AddressSpace"s in core processes.
Populate the "offset" from the start of a file, based on the File note, and set the inode to be something other than 0 in the case that the file exists. Also, because the FileEntry type is only used by the "dead" process, move it into the .cc file to stop exposing the public headers to it. Also, previously, vmflags and permissions were aggregated into one field. After splitting, the local variable used to build up the permissions remained called "flags". Fix that, and rename it.
1 parent 28140c4 commit c4783d4

File tree

2 files changed

+64
-61
lines changed

2 files changed

+64
-61
lines changed

dead.cc

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,61 @@
44

55
#include <iostream>
66

7+
78
namespace pstack::Procman {
89

10+
namespace {
11+
12+
struct FileEntry {
13+
Elf::Off start;
14+
Elf::Off end;
15+
Elf::Off fileOff;
16+
};
17+
18+
class FileEntries {
19+
FileNoteHeader header;
20+
Reader::csptr entries;
21+
std::unique_ptr<ReaderArray<FileEntry>> entriesArray;
22+
Reader::csptr names;
23+
24+
public:
25+
class sentinel { };
26+
class iterator {
27+
friend class FileEntries;
28+
const FileEntries &entries;
29+
void fetch();
30+
bool fetched = false;
31+
size_t nameoff = 0;
32+
std::pair<std::string, FileEntry> cur;
33+
ReaderArray<FileEntry>::iterator entriesIterator;
34+
public:
35+
iterator(const FileEntries &entries, ReaderArray<FileEntry>::iterator start);
36+
iterator &operator++();
37+
std::pair<std::string, FileEntry> operator *() { fetch(); return cur; }
38+
bool operator != (const iterator &rhs) const { return entriesIterator != rhs.entriesIterator; }
39+
bool operator != (const sentinel &) const { return entriesIterator != entries.entriesArray->end(); }
40+
};
41+
FileEntries(const Elf::Object &obj) {
42+
// find the Notes section.
43+
for (auto note : obj.notes()) {
44+
if (note.name() == "CORE" && note.type() == NT_FILE) {
45+
auto data = note.data();
46+
header = data->readObj<FileNoteHeader>(0);
47+
entries = data->view("FILE note entries", sizeof header, header.count * sizeof (FileEntry));
48+
names = data->view("FILE note names", sizeof header + header.count * sizeof (FileEntry));
49+
break;
50+
}
51+
}
52+
if (!entries)
53+
entries = std::make_shared<NullReader>();
54+
entriesArray = std::make_unique<ReaderArray<FileEntry>>(*entries);
55+
}
56+
iterator begin() const { return iterator(*this, entriesArray->begin()); }
57+
sentinel end() const { return sentinel{}; }
58+
};
59+
}
60+
61+
962
CoreProcess::CoreProcess(Context &ctx, Elf::Object::sptr exec, Elf::Object::sptr core)
1063
: Process(ctx, std::move(exec), std::make_shared<CoreReader>(this, core))
1164
, prpsinfo{}
@@ -228,20 +281,25 @@ CoreProcess::addressSpace() const {
228281
for (const auto &hdr : coreImage->getSegments(PT_LOAD)) {
229282
auto ub = entries.upper_bound(hdr.p_vaddr);
230283
std::string name;
284+
uintmax_t offset = 0;
285+
uintmax_t inode = 0;
231286
if (ub != entries.begin()) {
232287
--ub;
233-
if (ub->first >= hdr.p_vaddr && ub->second.second.end <= hdr.p_vaddr + hdr.p_memsz)
288+
if (ub->first >= hdr.p_vaddr && ub->second.second.end <= hdr.p_vaddr + hdr.p_memsz) {
234289
name = ub->second.first;
290+
offset = ub->second.second.fileOff * getpagesize(); // that's the offset in pages.
291+
inode = 1;
292+
}
235293
}
236-
std::set<AddressRange::Permission> flags;
294+
std::set<AddressRange::Permission> permissions;
237295
if ((hdr.p_flags & PF_W) != 0)
238-
flags.insert(AddressRange::Permission::write);
296+
permissions.insert(AddressRange::Permission::write);
239297
if ((hdr.p_flags & PF_R) != 0)
240-
flags.insert(AddressRange::Permission::read);
298+
permissions.insert(AddressRange::Permission::read);
241299
if ((hdr.p_flags & PF_X) != 0)
242-
flags.insert(AddressRange::Permission::exec);
300+
permissions.insert(AddressRange::Permission::exec);
243301
rv.push_back( { hdr.p_vaddr, hdr.p_vaddr + hdr.p_memsz,
244-
hdr.p_vaddr + hdr.p_filesz, 0, {0, 0, 0, name}, flags, {}});
302+
hdr.p_vaddr + hdr.p_filesz, offset, {0, 0, inode, name}, permissions, {}});
245303
}
246304
return rv;
247305
}
@@ -284,11 +342,5 @@ CoreProcess::getSignalInfo() const {
284342
return std::nullopt;
285343
}
286344

287-
std::ostream &operator << (std::ostream &os, const JSON<pstack::Procman::FileEntry> &j) {
288-
return JObject(os)
289-
.field("start", j.object.start)
290-
.field("end", j.object.end)
291-
.field("fileOff", j.object.fileOff);
292-
}
293345
}
294346

libpstack/proc.h

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -427,54 +427,6 @@ struct FileNoteHeader {
427427
Elf::Off pageSize;
428428
};
429429

430-
struct FileEntry {
431-
Elf::Off start;
432-
Elf::Off end;
433-
Elf::Off fileOff;
434-
};
435-
436-
class FileEntries {
437-
FileNoteHeader header;
438-
Reader::csptr entries;
439-
std::unique_ptr<ReaderArray<FileEntry>> entriesArray;
440-
Reader::csptr names;
441-
442-
public:
443-
class sentinel { };
444-
class iterator {
445-
friend class FileEntries;
446-
const FileEntries &entries;
447-
void fetch();
448-
bool fetched = false;
449-
size_t nameoff = 0;
450-
std::pair<std::string, FileEntry> cur;
451-
ReaderArray<FileEntry>::iterator entriesIterator;
452-
public:
453-
iterator(const FileEntries &entries, ReaderArray<FileEntry>::iterator start);
454-
iterator &operator++();
455-
std::pair<std::string, FileEntry> operator *() { fetch(); return cur; }
456-
bool operator != (const iterator &rhs) const { return entriesIterator != rhs.entriesIterator; }
457-
bool operator != (const sentinel &) const { return entriesIterator != entries.entriesArray->end(); }
458-
};
459-
FileEntries(const Elf::Object &obj) {
460-
// find the Notes section.
461-
for (auto note : obj.notes()) {
462-
if (note.name() == "CORE" && note.type() == NT_FILE) {
463-
auto data = note.data();
464-
header = data->readObj<FileNoteHeader>(0);
465-
entries = data->view("FILE note entries", sizeof header, header.count * sizeof (FileEntry));
466-
names = data->view("FILE note names", sizeof header + header.count * sizeof (FileEntry));
467-
break;
468-
}
469-
}
470-
if (!entries)
471-
entries = std::make_shared<NullReader>();
472-
entriesArray = std::make_unique<ReaderArray<FileEntry>>(*entries);
473-
}
474-
iterator begin() const { return iterator(*this, entriesArray->begin()); }
475-
sentinel end() const { return sentinel{}; }
476-
};
477-
478430

479431
struct WaitStatus {
480432
int status;
@@ -493,7 +445,6 @@ std::ostream &operator << (std::ostream &os, WaitStatus ws);
493445

494446
std::ostream &operator << (std::ostream &os, const JSON<pstack::Procman::StackFrame, pstack::Procman::Process *> &jt);
495447
std::ostream &operator << (std::ostream &os, const JSON<pstack::Procman::ThreadStack, pstack::Procman::Process *> &jt);
496-
std::ostream &operator << (std::ostream &os, const JSON<pstack::Procman::FileEntry> &);
497448

498449
}
499450

0 commit comments

Comments
 (0)