Skip to content

Commit 23dc954

Browse files
powellsrevaleev
authored andcommitted
Allow attaching debugger via cl, enable prelaunch actions, cleanup
1 parent d0d7b73 commit 23dc954

File tree

2 files changed

+66
-83
lines changed

2 files changed

+66
-83
lines changed

src/TiledArray/util/bug.cpp

Lines changed: 51 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ Debugger::~Debugger() {
7777
for (int i = 0; i < NSIG; i++) {
7878
if (mysigs_[i]) signals[i] = nullptr;
7979
}
80-
delete[] mysigs_;
8180
}
8281

8382
void Debugger::init() {
@@ -91,7 +90,7 @@ void Debugger::init() {
9190
debug_ = 1;
9291
wait_for_debugger_ = 1;
9392

94-
mysigs_ = new int[NSIG];
93+
mysigs_ = std::make_unique<int[]>(NSIG);
9594
for (int i = 0; i < NSIG; i++) {
9695
mysigs_[i] = 0;
9796
}
@@ -187,13 +186,9 @@ const std::string Debugger::lldb_cmd_ =
187186

188187
void Debugger::resolve_cmd_alias() {
189188
if (cmd_ == "gdb_xterm") {
190-
cmd_ =
191-
"xterm -title \"$(PREFIX)$(EXEC)\" -e gdb -ex \"set variable "
192-
"debugger_ready_=1\" --pid=$(PID) $(EXEC) &";
189+
cmd_ = "xterm -title \"$(PREFIX)$(EXEC)\" -e " + gdb_cmd_ + " &";
193190
} else if (cmd_ == "lldb_xterm") {
194-
cmd_ =
195-
"xterm -title \"$(PREFIX)$(EXEC)\" -e lldb -p $(PID) -o \"expr "
196-
"debugger_ready_=1\" &";
191+
cmd_ = "xterm -title \"$(PREFIX)$(EXEC)\" -e " + lldb_cmd_ + " &";
197192
}
198193
}
199194

@@ -222,10 +217,10 @@ std::string Debugger::replace_macros(std::string str) {
222217
void Debugger::set_cmd(const char *cmd) {
223218
if (cmd) {
224219
cmd_ = cmd;
225-
resolve_cmd_alias();
226220
} else {
227221
cmd_.resize(0);
228222
}
223+
this->resolve_cmd_alias();
229224
}
230225

231226
void Debugger::debug(const char *reason) {
@@ -236,80 +231,50 @@ void Debugger::debug(const char *reason) {
236231
std::cout << "no reason given";
237232
std::cout << std::endl;
238233

239-
if (!cmd_.empty()) {
240-
int pid = getpid();
241-
// contruct the command name
242-
std::string cmd = cmd_;
243-
std::string::size_type pos;
244-
std::string pidvar("$(PID)");
245-
while ((pos = cmd.find(pidvar)) != std::string::npos) {
246-
std::string pidstr;
247-
pidstr += std::to_string(pid);
248-
cmd.replace(pos, pidvar.size(), pidstr);
249-
}
250-
std::string execvar("$(EXEC)");
251-
while ((pos = cmd.find(execvar)) != std::string::npos) {
252-
cmd.replace(pos, execvar.size(), exec_);
253-
}
254-
std::string prefixvar("$(PREFIX)");
255-
while ((pos = cmd.find(prefixvar)) != std::string::npos) {
256-
cmd.replace(pos, prefixvar.size(), prefix_);
257-
}
258234

259-
// start the debugger
260-
// before starting the debugger de-register signal handler for SIGTRAP to
261-
// let the debugger take over
262-
release(SIGTRAP);
235+
const std::string cmd = replace_macros(cmd_);
236+
// start the debugger
237+
// before starting the debugger de-register signal handler for SIGTRAP to
238+
// let the debugger take over
239+
release(SIGTRAP);
240+
int system_retvalue = 0;
241+
if (!cmd.empty()) {
263242
std::cout << prefix_ << "Debugger: starting \"" << cmd << "\"" << std::endl;
264-
debugger_ready_ = 0;
265-
const auto system_retvalue = system(cmd.c_str());
266-
if (system_retvalue != 0) { // call to system() failed
267-
std::cout << prefix_
268-
<< "Failed debugger launch: system() did not succeed ..."
269-
<< std::endl;
270-
} else { // call to system() succeeded
271-
// wait until the debugger is ready
272-
if (sleep_) {
273-
std::cout << prefix_ << "Sleeping " << sleep_
274-
<< " seconds to wait for debugger ..." << std::endl;
275-
sleep(sleep_);
276-
}
277-
if (wait_for_debugger_) {
278-
std::string make_ready_message;
279-
if (cmd_.find(" gdb ") != std::string::npos ||
280-
cmd_.find(" lldb ") != std::string::npos) {
281-
make_ready_message =
282-
" configure debugging session (set breakpoints/watchpoints, "
283-
"etc.) then type 'c' to continue running";
284-
}
285-
286-
std::cout << prefix_ << ": waiting for the user ..."
287-
<< make_ready_message << std::endl;
288-
while (!debugger_ready_)
289-
;
290-
}
291-
}
292-
} // Here, need handling of cmd_ empty
293-
if (sleep_) {
294-
std::cout << prefix_ << "Debugger: sleeping " << sleep_
295-
<< " seconds to wait for debugger ..." << std::endl;
296-
sleep(sleep_);
243+
system_retvalue = system(cmd.c_str());
297244
}
298-
if (wait_for_debugger_) {
299-
std::cout << prefix_ << "Debugger: waiting for the user ...";
300-
if (cmd_.empty()) {
301-
std::cout << " attach debugger to process "
302-
<< std::to_string(getpid())
303-
<< " as follows:" << std::endl
304-
<< prefix_ << "Debugger: - if using gdb: "
305-
<< replace_macros(gdb_cmd_) << std::endl
306-
<< prefix_ << "Debugger: - if using lldb: "
307-
<< replace_macros(lldb_cmd_);
245+
if (system_retvalue != 0) {
246+
ExEnv::outn() << prefix_
247+
<< "Failed debugger launch: system() did not succeed ..."
248+
<< std::endl;
249+
} else { // call to system() succeeded
250+
// wait until the debugger is ready
251+
if (sleep_) {
252+
std::cout << prefix_ << "Debugger: sleeping " << sleep_
253+
<< " seconds to wait for debugger ..." << std::endl;
254+
sleep(sleep_);
308255
}
256+
if (wait_for_debugger_) {
257+
std::cout << prefix_ << "Debugger: waiting for the user ...";
258+
if (cmd_.find(" gdb ") != std::string::npos ||
259+
cmd_.find(" lldb ") != std::string::npos) {
260+
std::cout <<
261+
" configure debugging session (set breakpoints/watchpoints, "
262+
"etc.) then type 'c' to continue running";
263+
} else if (cmd.empty()) {
264+
std::cout << " attach debugger to process "
265+
<< std::to_string(getpid())
266+
<< " as follows:" << std::endl
267+
<< prefix_ << "Debugger: - if using gdb: "
268+
<< replace_macros(gdb_cmd_) << std::endl
269+
<< prefix_ << "Debugger: - if using lldb: "
270+
<< replace_macros(lldb_cmd_);
271+
}
272+
std::cout << std::endl;
309273

310-
std::cout << prefix_ << ": waiting for the user ..." << std::endl;
311-
while (!debugger_ready_)
312-
;
274+
debugger_ready_ = 0;
275+
while (!debugger_ready_)
276+
;
277+
}
313278
}
314279
}
315280

@@ -334,6 +299,10 @@ void Debugger::got_signal(int sig) {
334299
else
335300
signame = "UNKNOWN SIGNAL";
336301

302+
for (auto const &action: actions_) {
303+
action();
304+
}
305+
actions_.clear();
337306
if (traceback_) {
338307
traceback(signame);
339308
}
@@ -403,6 +372,10 @@ void Debugger::__traceback(const std::string &prefix, const char *reason) {
403372
std::cout << result.str(nframes_to_skip) << std::endl;
404373
}
405374

375+
void Debugger::register_prelaunch_action(std::function<void()> action) {
376+
actions_.push_back(action);
377+
}
378+
406379
void create_debugger(const char *cmd, const char *exec, std::int64_t rank) {
407380
auto debugger = std::make_shared<TiledArray::Debugger>();
408381
if (cmd) debugger->set_cmd(cmd);

src/TiledArray/util/bug.h

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ class Debugger {
291291
bool sleep_;
292292
bool wait_for_debugger_;
293293
bool handle_sigint_;
294-
int *mysigs_;
294+
std::unique_ptr<int[]> mysigs_;
295295

296296
void init();
297297

@@ -325,11 +325,11 @@ class Debugger {
325325
@param reason optional string specifying the reason for traceback
326326
*/
327327
virtual void traceback(const char *reason);
328-
/// Turn on or off debugging on a signel. The default is on.
328+
/// Turn on or off debugging on a signal. The default is on.
329329
virtual void set_debug_on_signal(int);
330-
/// Turn on or off traceback on a signel. The default is on.
330+
/// Turn on or off traceback on a signal. The default is on.
331331
virtual void set_traceback_on_signal(int);
332-
/// Turn on or off exit after a signel. The default is on.
332+
/// Turn on or off exit after a signal. The default is on.
333333
virtual void set_exit_on_signal(int);
334334
/** Turn on or off running an infinite loop after the debugger is started.
335335
This loop gives the debugger a chance to attack to the process.
@@ -370,7 +370,7 @@ class Debugger {
370370
virtual void default_cmd();
371371
/** Set the name of the executable for the current process.
372372
It is up to the programmer to set this, even if the Debugger
373-
is initialized with the KeyVal constructor. */
373+
is initialized with the constructor. */
374374
virtual void set_exec(const char *);
375375

376376
/// Called when signal sig is received. This is mainly for internal use.
@@ -381,12 +381,22 @@ class Debugger {
381381
/// Return the global default debugger.
382382
static std::shared_ptr<Debugger> default_debugger();
383383

384+
/// Register a (one-time) action to be executed when debugger is launched
385+
/// @param action an action to be executed
386+
/// @note multiple actions registered via this will be executed in order of
387+
/// their registration
388+
void register_prelaunch_action(std::function<void()> action);
389+
384390
private:
385391
/// Replaces alias in cmd_ with its full form
386392
void resolve_cmd_alias();
393+
/// Replace macros (\c PID , \c EXEC , \c PREFIX ) in \p cmd by their values
394+
/// \param cmd a string
395+
/// \return processed str
387396
std::string replace_macros(std::string cmd);
388397
static const std::string gdb_cmd_;
389398
static const std::string lldb_cmd_;
399+
std::vector<std::function<void()>> actions_; // prelaunch actions
390400
};
391401

392402
/// Use this to create a Debugger object and make it the default

0 commit comments

Comments
 (0)