@@ -77,7 +77,6 @@ Debugger::~Debugger() {
77
77
for (int i = 0 ; i < NSIG; i++) {
78
78
if (mysigs_[i]) signals[i] = nullptr ;
79
79
}
80
- delete[] mysigs_;
81
80
}
82
81
83
82
void Debugger::init () {
@@ -91,7 +90,7 @@ void Debugger::init() {
91
90
debug_ = 1 ;
92
91
wait_for_debugger_ = 1 ;
93
92
94
- mysigs_ = new int [NSIG] ;
93
+ mysigs_ = std::make_unique< int []>(NSIG) ;
95
94
for (int i = 0 ; i < NSIG; i++) {
96
95
mysigs_[i] = 0 ;
97
96
}
@@ -106,14 +105,14 @@ static void handler(int sig) {
106
105
void Debugger::handle (int sig) {
107
106
if (sig >= NSIG) return ;
108
107
typedef void (*handler_type)(int );
109
- signal (sig, (handler_type)handler);
108
+ std:: signal (sig, (handler_type)handler);
110
109
signals[sig] = this ;
111
110
mysigs_[sig] = 1 ;
112
111
}
113
112
114
113
void Debugger::release (int sig) {
115
114
if (sig >= NSIG) return ;
116
- signal (sig, SIG_DFL);
115
+ std:: signal (sig, SIG_DFL);
117
116
signals[sig] = nullptr ;
118
117
mysigs_[sig] = 0 ;
119
118
}
@@ -180,25 +179,48 @@ void Debugger::default_cmd() {
180
179
}
181
180
}
182
181
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
+
183
187
void Debugger::resolve_cmd_alias () {
184
188
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_ + " &" ;
188
190
} 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_ + " &" ;
192
192
}
193
193
}
194
194
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
+
195
217
void Debugger::set_cmd (const char *cmd) {
196
218
if (cmd) {
197
219
cmd_ = cmd;
198
- resolve_cmd_alias ();
199
220
} else {
200
221
cmd_.resize (0 );
201
222
}
223
+ this ->resolve_cmd_alias ();
202
224
}
203
225
204
226
void Debugger::debug (const char *reason) {
@@ -209,58 +231,48 @@ void Debugger::debug(const char *reason) {
209
231
std::cout << " no reason given" ;
210
232
std::cout << std::endl;
211
233
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 ()) {
236
241
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_);
263
270
}
271
+ std::cout << std::endl;
272
+
273
+ debugger_ready_ = 0 ;
274
+ while (!debugger_ready_)
275
+ ;
264
276
}
265
277
}
266
278
}
@@ -286,6 +298,10 @@ void Debugger::got_signal(int sig) {
286
298
else
287
299
signame = " UNKNOWN SIGNAL" ;
288
300
301
+ for (auto const &action : actions_) {
302
+ action ();
303
+ }
304
+ actions_.clear ();
289
305
if (traceback_) {
290
306
traceback (signame);
291
307
}
@@ -355,6 +371,10 @@ void Debugger::__traceback(const std::string &prefix, const char *reason) {
355
371
std::cout << result.str (nframes_to_skip) << std::endl;
356
372
}
357
373
374
+ void Debugger::register_prelaunch_action (std::function<void ()> action) {
375
+ actions_.push_back (action);
376
+ }
377
+
358
378
void create_debugger (const char *cmd, const char *exec, std::int64_t rank) {
359
379
auto debugger = std::make_shared<TiledArray::Debugger>();
360
380
if (cmd) debugger->set_cmd (cmd);
0 commit comments