Go to the documentation of this file.
28 #ifndef MPQC4_SRC_MPQC_UTIL_MISC_BUG_H_
29 #define MPQC4_SRC_MPQC_UTIL_MISC_BUG_H_
34 #include <unordered_map>
38 #if defined(__APPLE__) && defined(__x86_64__)
39 #include <mach/mach.h>
92 const std::vector<const pthread_t *> &threads) {
93 get_instance() = std::shared_ptr<Pool>(
new Pool(threads));
99 auto result = get_instance();
101 "Pool::instance() called but Pool::initialize_instance() had not "
111 const auto it = pool_.find(thread);
112 assert(it != pool_.end());
114 for (
auto &watchpt_ptr : it->second) {
115 if (watchpt_ptr && watchpt_ptr->address() == addr)
return *
this;
119 auto &watchpt_ptr = it->second[dr];
121 watchpt_ptr = std::make_shared<MemoryWatchpoint_x86_64>(
134 const auto it = pool_.find(thread);
135 assert(it != pool_.end());
136 for (
auto &watchpt_ptr : it->second) {
137 if (watchpt_ptr && watchpt_ptr->address() == addr)
138 return watchpt_ptr.get();
145 const auto it = pool_.find(thread);
146 assert(it != pool_.end());
147 for (
auto &watchpt_ptr : it->second) {
148 if (watchpt_ptr && watchpt_ptr->address() == addr) {
157 std::unordered_map<
const pthread_t *,
158 std::vector<std::shared_ptr<MemoryWatchpoint_x86_64>>>
167 explicit Pool(
const std::vector<const pthread_t *> &threads) {
168 for (
const auto &thread : threads) {
169 assert(thread !=
nullptr);
174 static std::shared_ptr<Pool> &get_instance() {
175 static std::shared_ptr<Pool> instance_;
191 : addr_(addr), size_(
size), cond_(cond), dr_(dr), thread_(thread) {
207 const pthread_t *thread_;
212 return (state | cond << 16 |
size << 24) << (2 * reg);
221 void init(
bool create) {
222 #if defined(__APPLE__) && defined(__x86_64__)
224 mach_msg_type_number_t dr_count = x86_DEBUG_STATE_COUNT;
226 mach_port_t target_mach_thread = pthread_mach_thread_np(*thread_);
229 thread_get_state(target_mach_thread, x86_DEBUG_STATE,
230 reinterpret_cast<thread_state_t
>(&dr), &dr_count);
232 if (create && rc != KERN_SUCCESS)
233 throw std::runtime_error(
234 "MemoryWatchpoint_x86_64::MemoryWatchpoint_x86_64(): "
235 "thread_get_state failed");
239 dr.uds.ds64.__dr0 =
reinterpret_cast<uint64_t
>(addr_);
242 dr.uds.ds64.__dr1 =
reinterpret_cast<uint64_t
>(addr_);
245 dr.uds.ds64.__dr2 =
reinterpret_cast<uint64_t
>(addr_);
248 dr.uds.ds64.__dr3 =
reinterpret_cast<uint64_t
>(addr_);
252 dr.uds.ds64.__dr7 &= ~MakeMask(dr_);
257 rc = thread_set_state(target_mach_thread, x86_DEBUG_STATE,
258 reinterpret_cast<thread_state_t
>(&dr), dr_count);
260 if (create && rc != KERN_SUCCESS)
261 throw std::runtime_error(
262 "MemoryWatchpoint_x86_64::MemoryWatchpoint_x86_64(): "
263 "thread_set_state failed");
264 #endif // defined(__APPLE__) && defined(__x86_64__)
307 const char *reason =
nullptr);
313 explicit Debugger(
const char *exec =
nullptr);
318 virtual void debug(
const char *reason);
326 virtual void traceback(
const char *reason);
339 virtual void handle(
int sig);
356 virtual void set_cmd(
const char *);
362 virtual void set_exec(
const char *);
374 void resolve_cmd_alias();
384 #endif // MPQC4_SRC_MPQC_UTIL_MISC_BUG_H_
void launch_gdb_xterm()
Use this to launch GNU debugger in xterm.
a singleton pool of MemoryWatchpoint objects
virtual void set_cmd(const char *)
static std::shared_ptr< Debugger > default_debugger()
Return the global default debugger.
virtual void set_traceback_on_signal(int)
Turn on or off traceback on a signel. The default is on.
MemoryWatchpoint_x86_64 * find(void *addr, const pthread_t *thread)
DebugRegister debug_register() const
Condition condition() const
MemoryWatchpoint represents a hardware watchpoint for a memory location Implements a memory watchpoin...
virtual void set_prefix(const char *p)
This sets a prefix which preceeds all messages printing by Debugger.
volatile int debugger_ready_
virtual void set_debug_on_signal(int)
Turn on or off debugging on a signel. The default is on.
static std::shared_ptr< Debugger > default_debugger_
static constexpr const size_t nwatchpoints_per_thread
MemoryWatchpoint_x86_64(void *addr, Size size, Condition cond, DebugRegister dr, const pthread_t *thread)
creates a MemoryWatchpoint watching memory window [addr,addr+size) for condition cond from threads th...
virtual void set_exit_on_signal(int)
Turn on or off exit after a signel. The default is on.
static void initialize_instance(const std::vector< const pthread_t * > &threads)
Pool & clear(void *addr, const pthread_t *thread)
virtual void debug(const char *reason)
virtual void set_exec(const char *)
Pool & set(void *addr, Size size, Condition cond, const pthread_t *thread)
virtual void traceback(const char *reason)
virtual void default_cmd()
Calls set_cmd with a hopefully suitable default.
virtual void handle(int sig)
The Debugger will be activated when sig is caught.
static void __traceback(const std::string &prefix, const char *reason=nullptr)
virtual void release(int sig)
Debugger(const char *exec=nullptr)
Programmatic construction of Debugger.
virtual void got_signal(int sig)
Called when signal sig is received. This is mainly for internal use.
friend class MemoryWatchPool
virtual void set_wait_for_debugger(int)
void launch_lldb_xterm()
Use this to launch LLVM debugger in xterm.
static std::shared_ptr< Pool > instance()
~MemoryWatchpoint_x86_64()
static void set_default_debugger(const std::shared_ptr< Debugger > &)
Set the global default debugger. The initial value is null.
virtual void handle_defaults()
This calls handle(int) with all of the major signals.