-
Notifications
You must be signed in to change notification settings - Fork 35
/
self.cc
108 lines (91 loc) · 2.2 KB
/
self.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include "libpstack/proc.h"
#include <sys/ptrace.h>
#include <sys/types.h>
#include <dirent.h>
#include <err.h>
#include <fcntl.h>
#include <unistd.h>
#include <wait.h>
#include <cassert>
#include <ucontext.h>
#include <dlfcn.h>
#include <syscall.h> // gettid is still relatively new - use syscall instead.
namespace pstack::Procman {
SelfProcess::SelfProcess(const Elf::Object::sptr &ex, const PstackOptions &options, Dwarf::ImageCache &imageCache)
: Process(
ex ? ex : imageCache.getImageForName("/proc/self/exe"),
std::make_shared<MemReader>("me", std::numeric_limits<size_t>::max(), nullptr),
options, imageCache)
, pid( getpid() )
{
}
Reader::csptr
SelfProcess::getAUXV() const
{
return loadFile("/proc/self/auxv");
}
void
SelfProcess::listLWPs(std::function<void(lwpid_t)> cb) {
cb(int(syscall(SYS_gettid)));
}
size_t
SelfProcess::getRegs(lwpid_t, int code, size_t size, void *regs) // for now, we just support the current thread.
{
ucontext_t context;
assert(pid == getpid());
getcontext(&context);
switch (code) {
case NT_PRSTATUS:
#ifdef __aarch64__
assert(size == sizeof context.uc_mcontext.regs);
memcpy(regs, &context.uc_mcontext.regs, size);
#else
assert(size == sizeof (user_regs_struct));
gregset2core(*reinterpret_cast<user_regs_struct *>(regs), context.uc_mcontext.gregs);
#endif
return size;
#ifndef __aarch64__ // TODO
case NT_FPREGSET:
memcpy(regs, context.uc_mcontext.fpregs, size);
return size;
#endif
}
return 0;
}
void
SelfProcess::resume(lwpid_t)
{
}
pid_t
SelfProcess::getPID() const
{
return pid;
}
void
SelfProcess::stopProcess()
{
}
void
SelfProcess::resumeProcess()
{
}
void
SelfProcess::stop(lwpid_t)
{
}
std::vector<AddressRange>
SelfProcess::addressSpace() const {
return procAddressSpace("/proc/self/maps");
}
bool
SelfProcess::loadSharedObjectsFromFileNote()
{
// In theory we can implement this by grovelling in /proc/<pid>/maps, but
// it mostly exists for truncated core files, so don't bother now.
return false;
}
Elf::Addr
SelfProcess::findRDebugAddr() {
return Elf::Addr(dlsym(RTLD_DEFAULT, "_r_debug"));
}
}