@@ -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
8382void 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 }
@@ -106,14 +105,14 @@ static void handler(int sig) {
106105void Debugger::handle (int sig) {
107106 if (sig >= NSIG) return ;
108107 typedef void (*handler_type)(int );
109- signal (sig, (handler_type)handler);
108+ std:: signal (sig, (handler_type)handler);
110109 signals[sig] = this ;
111110 mysigs_[sig] = 1 ;
112111}
113112
114113void Debugger::release (int sig) {
115114 if (sig >= NSIG) return ;
116- signal (sig, SIG_DFL);
115+ std:: signal (sig, SIG_DFL);
117116 signals[sig] = nullptr ;
118117 mysigs_[sig] = 0 ;
119118}
@@ -180,25 +179,48 @@ void Debugger::default_cmd() {
180179 }
181180}
182181
182+ const std::string Debugger::gdb_cmd_ =
183+ " gdb -ex \" set variable debugger_ready_=1\" --pid=$(PID) $(EXEC)" ;
184+ const std::string Debugger::lldb_cmd_ =
185+ " lldb -p $(PID) -o \" expr debugger_ready_=1\" " ;
186+
183187void Debugger::resolve_cmd_alias () {
184188 if (cmd_ == " gdb_xterm" ) {
185- cmd_ =
186- " xterm -title \" $(PREFIX)$(EXEC)\" -e gdb -ex \" set variable "
187- " debugger_ready_=1\" --pid=$(PID) $(EXEC) &" ;
189+ cmd_ = " xterm -title \" $(PREFIX)$(EXEC)\" -e " + gdb_cmd_ + " &" ;
188190 } else if (cmd_ == " lldb_xterm" ) {
189- cmd_ =
190- " xterm -title \" $(PREFIX)$(EXEC)\" -e lldb -p $(PID) -o \" expr "
191- " debugger_ready_=1\" &" ;
191+ cmd_ = " xterm -title \" $(PREFIX)$(EXEC)\" -e " + lldb_cmd_ + " &" ;
192192 }
193193}
194194
195+ std::string Debugger::replace_macros (std::string str) {
196+ if (!str.empty ()) {
197+ int pid = getpid ();
198+ std::string::size_type pos;
199+ std::string pidvar (" $(PID)" );
200+ while ((pos = str.find (pidvar)) != std::string::npos) {
201+ std::string pidstr;
202+ pidstr += std::to_string (pid);
203+ str.replace (pos, pidvar.size (), pidstr);
204+ }
205+ std::string execvar (" $(EXEC)" );
206+ while ((pos = str.find (execvar)) != std::string::npos) {
207+ str.replace (pos, execvar.size (), exec_);
208+ }
209+ std::string prefixvar (" $(PREFIX)" );
210+ while ((pos = str.find (prefixvar)) != std::string::npos) {
211+ str.replace (pos, prefixvar.size (), prefix_);
212+ }
213+ }
214+ return str;
215+ }
216+
195217void Debugger::set_cmd (const char *cmd) {
196218 if (cmd) {
197219 cmd_ = cmd;
198- resolve_cmd_alias ();
199220 } else {
200221 cmd_.resize (0 );
201222 }
223+ this ->resolve_cmd_alias ();
202224}
203225
204226void Debugger::debug (const char *reason) {
@@ -209,58 +231,48 @@ void Debugger::debug(const char *reason) {
209231 std::cout << " no reason given" ;
210232 std::cout << std::endl;
211233
212- if (!cmd_.empty ()) {
213- int pid = getpid ();
214- // contruct the command name
215- std::string cmd = cmd_;
216- std::string::size_type pos;
217- std::string pidvar (" $(PID)" );
218- while ((pos = cmd.find (pidvar)) != std::string::npos) {
219- std::string pidstr;
220- pidstr += std::to_string (pid);
221- cmd.replace (pos, pidvar.size (), pidstr);
222- }
223- std::string execvar (" $(EXEC)" );
224- while ((pos = cmd.find (execvar)) != std::string::npos) {
225- cmd.replace (pos, execvar.size (), exec_);
226- }
227- std::string prefixvar (" $(PREFIX)" );
228- while ((pos = cmd.find (prefixvar)) != std::string::npos) {
229- cmd.replace (pos, prefixvar.size (), prefix_);
230- }
231-
232- // start the debugger
233- // before starting the debugger de-register signal handler for SIGTRAP to
234- // let the debugger take over
235- release (SIGTRAP);
234+ const std::string cmd = replace_macros (cmd_);
235+ // start the debugger
236+ // before starting the debugger de-register signal handler for SIGTRAP to
237+ // let the debugger take over
238+ release (SIGTRAP);
239+ int system_retvalue = 0 ;
240+ if (!cmd.empty ()) {
236241 std::cout << prefix_ << " Debugger: starting \" " << cmd << " \" " << std::endl;
237- debugger_ready_ = 0 ;
238- const auto system_retvalue = system (cmd.c_str ());
239- if (system_retvalue != 0 ) { // call to system() failed
240- std::cout << prefix_
241- << " Failed debugger launch: system() did not succeed ..."
242- << std::endl;
243- } else { // call to system() succeeded
244- // wait until the debugger is ready
245- if (sleep_) {
246- std::cout << prefix_ << " Sleeping " << sleep_
247- << " seconds to wait for debugger ..." << std::endl;
248- sleep (sleep_);
249- }
250- if (wait_for_debugger_) {
251- std::string make_ready_message;
252- if (cmd_.find (" gdb " ) != std::string::npos ||
253- cmd_.find (" lldb " ) != std::string::npos) {
254- make_ready_message =
255- " configure debugging session (set breakpoints/watchpoints, "
256- " etc.) then type 'c' to continue running" ;
257- }
258-
259- std::cout << prefix_ << " : waiting for the user ..."
260- << make_ready_message << std::endl;
261- while (!debugger_ready_)
262- ;
242+ system_retvalue = std::system (cmd.c_str ());
243+ }
244+ if (system_retvalue != 0 ) {
245+ std::cout << prefix_
246+ << " Failed debugger launch: system() did not succeed ..."
247+ << std::endl;
248+ } else { // call to system() succeeded
249+ // wait until the debugger is ready
250+ if (sleep_) {
251+ std::cout << prefix_ << " Debugger: sleeping " << sleep_
252+ << " seconds to wait for debugger ..." << std::endl;
253+ sleep (sleep_);
254+ }
255+ if (wait_for_debugger_) {
256+ std::cout << prefix_ << " Debugger: waiting for the user ..." ;
257+ if (cmd_.find (" gdb " ) != std::string::npos ||
258+ cmd_.find (" lldb " ) != std::string::npos) {
259+ std::cout
260+ << " configure debugging session (set breakpoints/watchpoints, "
261+ " etc.) then type 'c' to continue running" ;
262+ } else if (cmd.empty ()) {
263+ std::cout << " attach debugger to process " << std::to_string (getpid ())
264+ << " as follows:" << std::endl
265+ << prefix_
266+ << " Debugger: - if using gdb: " << replace_macros (gdb_cmd_)
267+ << std::endl
268+ << prefix_
269+ << " Debugger: - if using lldb: " << replace_macros (lldb_cmd_);
263270 }
271+ std::cout << std::endl;
272+
273+ debugger_ready_ = 0 ;
274+ while (!debugger_ready_)
275+ ;
264276 }
265277 }
266278}
@@ -286,6 +298,10 @@ void Debugger::got_signal(int sig) {
286298 else
287299 signame = " UNKNOWN SIGNAL" ;
288300
301+ for (auto const &action : actions_) {
302+ action ();
303+ }
304+ actions_.clear ();
289305 if (traceback_) {
290306 traceback (signame);
291307 }
@@ -355,6 +371,10 @@ void Debugger::__traceback(const std::string &prefix, const char *reason) {
355371 std::cout << result.str (nframes_to_skip) << std::endl;
356372}
357373
374+ void Debugger::register_prelaunch_action (std::function<void ()> action) {
375+ actions_.push_back (action);
376+ }
377+
358378void create_debugger (const char *cmd, const char *exec, std::int64_t rank) {
359379 auto debugger = std::make_shared<TiledArray::Debugger>();
360380 if (cmd) debugger->set_cmd (cmd);
0 commit comments