1 /* 2 Code to handle PETSc starting up in debuggers,etc. 3 */ 4 5 #include <petscsys.h> /*I "petscsys.h" I*/ 6 #include <signal.h> 7 #if defined(PETSC_HAVE_UNISTD_H) 8 #include <unistd.h> 9 #endif 10 11 /* 12 These are the debugger and display used if the debugger is started up 13 */ 14 static char PetscDebugger[PETSC_MAX_PATH_LEN]; 15 static char DebugTerminal[PETSC_MAX_PATH_LEN]; 16 static PetscBool UseDebugTerminal = PETSC_TRUE; 17 PetscBool petscwaitonerrorflg = PETSC_FALSE; 18 PetscBool petscindebugger = PETSC_FALSE; 19 20 /*@C 21 PetscSetDebugTerminal - Sets the terminal to use for debugging. 22 23 Not Collective 24 25 Input Parameters: 26 . terminal - name of terminal and any flags required to execute a program. 27 For example xterm, "urxvt -e", "gnome-terminal -x". 28 On Apple MacOS you can use Terminal (note the capital T) 29 30 Options Database Keys: 31 -debug_terminal terminal - use this terminal instead of the default 32 33 Level: developer 34 35 Notes: 36 You can start the debugger for all processes in the same GNU screen session. 37 38 mpiexec -n 4 ./myapp -start_in_debugger -debug_terminal "screen -X -S debug screen" 39 40 will open 4 windows in the session named "debug". 41 42 The default on Apple is Terminal, on other systems the default is xterm 43 44 Fortran Note: 45 This routine is not supported in Fortran. 46 47 .seealso: PetscSetDebugger() 48 @*/ 49 PetscErrorCode PetscSetDebugTerminal(const char terminal[]) 50 { 51 PetscErrorCode ierr; 52 PetscBool xterm; 53 54 PetscFunctionBegin; 55 ierr = PetscStrncpy(DebugTerminal,terminal,sizeof(DebugTerminal));CHKERRQ(ierr); 56 ierr = PetscStrcmp(terminal,"xterm",&xterm);CHKERRQ(ierr); 57 if (xterm) { 58 ierr = PetscStrlcat(DebugTerminal," -e",sizeof(DebugTerminal));CHKERRQ(ierr); 59 } 60 PetscFunctionReturn(0); 61 } 62 63 /*@C 64 PetscSetDebugger - Sets options associated with the debugger. 65 66 Not Collective 67 68 Input Parameters: 69 + debugger - name of debugger, which should be in your path, 70 usually "lldb", "dbx", "gdb", "cuda-gdb", "idb", "xxgdb", "kdgb" or "ddd". Also, HP-UX 71 supports "xdb", and IBM rs6000 supports "xldb". 72 73 - usedebugterminal - flag to indicate debugger window, set to either PETSC_TRUE (to indicate 74 debugger should be started in a new terminal window) or PETSC_FALSE (to start debugger 75 in initial window (the option PETSC_FALSE makes no sense when using more 76 than one MPI process.) 77 78 Level: developer 79 80 Fortran Note: 81 This routine is not supported in Fortran. 82 83 .seealso: PetscAttachDebugger(), PetscAttachDebuggerErrorHandler(), PetscSetDebugTerminal() 84 @*/ 85 PetscErrorCode PetscSetDebugger(const char debugger[],PetscBool usedebugterminal) 86 { 87 PetscErrorCode ierr; 88 89 PetscFunctionBegin; 90 if (debugger) { 91 ierr = PetscStrncpy(PetscDebugger,debugger,sizeof(PetscDebugger));CHKERRQ(ierr); 92 } 93 if (UseDebugTerminal) UseDebugTerminal = usedebugterminal; 94 PetscFunctionReturn(0); 95 } 96 97 /*@C 98 PetscSetDefaultDebugger - Causes PETSc to use its default debugger and output terminal 99 100 Not collective 101 102 Level: developer 103 104 .seealso: PetscSetDebugger(), PetscSetDebuggerFromString() 105 @*/ 106 PetscErrorCode PetscSetDefaultDebugger(void) 107 { 108 PetscErrorCode ierr; 109 110 PetscFunctionBegin; 111 #if defined(PETSC_USE_DEBUGGER) 112 ierr = PetscSetDebugger(PETSC_USE_DEBUGGER,PETSC_TRUE);CHKERRQ(ierr); 113 #endif 114 #if defined(__APPLE__) 115 ierr = PetscSetDebugTerminal("Terminal");CHKERRQ(ierr); 116 #else 117 ierr = PetscSetDebugTerminal("xterm");CHKERRQ(ierr); 118 #endif 119 PetscFunctionReturn(0); 120 } 121 122 static PetscErrorCode PetscCheckDebugger_Private(const char defaultDbg[], const char string[], const char *debugger[]) 123 { 124 PetscBool exists; 125 char *f; 126 PetscErrorCode ierr; 127 128 PetscFunctionBegin; 129 ierr = PetscStrstr(string, defaultDbg, &f);CHKERRQ(ierr); 130 if (f) { 131 ierr = PetscTestFile(string, 'x', &exists);CHKERRQ(ierr); 132 if (exists) *debugger = string; 133 else *debugger = defaultDbg; 134 } 135 PetscFunctionReturn(0); 136 } 137 138 /*@C 139 PetscSetDebuggerFromString - Set the complete path for the 140 debugger for PETSc to use. 141 142 Not collective 143 144 Level: developer 145 146 .seealso: PetscSetDebugger(), PetscSetDefaultDebugger() 147 @*/ 148 PetscErrorCode PetscSetDebuggerFromString(const char *string) 149 { 150 const char *debugger = NULL; 151 PetscBool useterminal = PETSC_TRUE; 152 char *f; 153 PetscErrorCode ierr; 154 155 PetscFunctionBegin; 156 ierr = PetscStrstr(string, "noxterm", &f);CHKERRQ(ierr); 157 if (f) useterminal = PETSC_FALSE; 158 ierr = PetscStrstr(string, "ddd", &f);CHKERRQ(ierr); 159 if (f) useterminal = PETSC_FALSE; 160 ierr = PetscStrstr(string, "noterminal", &f);CHKERRQ(ierr); 161 if (f) useterminal = PETSC_FALSE; 162 ierr = PetscCheckDebugger_Private("xdb", string, &debugger);CHKERRQ(ierr); 163 ierr = PetscCheckDebugger_Private("dbx", string, &debugger);CHKERRQ(ierr); 164 ierr = PetscCheckDebugger_Private("xldb", string, &debugger);CHKERRQ(ierr); 165 ierr = PetscCheckDebugger_Private("gdb", string, &debugger);CHKERRQ(ierr); 166 ierr = PetscCheckDebugger_Private("cuda-gdb", string, &debugger);CHKERRQ(ierr); 167 ierr = PetscCheckDebugger_Private("idb", string, &debugger);CHKERRQ(ierr); 168 ierr = PetscCheckDebugger_Private("xxgdb", string, &debugger);CHKERRQ(ierr); 169 ierr = PetscCheckDebugger_Private("ddd", string, &debugger);CHKERRQ(ierr); 170 ierr = PetscCheckDebugger_Private("kdbg", string, &debugger);CHKERRQ(ierr); 171 ierr = PetscCheckDebugger_Private("ups", string, &debugger);CHKERRQ(ierr); 172 ierr = PetscCheckDebugger_Private("workshop", string, &debugger);CHKERRQ(ierr); 173 ierr = PetscCheckDebugger_Private("pgdbg", string, &debugger);CHKERRQ(ierr); 174 ierr = PetscCheckDebugger_Private("pathdb", string, &debugger);CHKERRQ(ierr); 175 ierr = PetscCheckDebugger_Private("lldb", string, &debugger);CHKERRQ(ierr); 176 177 ierr = PetscSetDebugger(debugger, useterminal);CHKERRQ(ierr); 178 PetscFunctionReturn(0); 179 } 180 181 /*@ 182 PetscWaitOnError - If an error is detected and the process would normally exit the main program with MPI_Abort() sleep instead 183 of exiting. 184 185 Not Collective 186 187 Level: advanced 188 189 Notes: 190 When -start_in_debugger -debugger_ranks x,y,z is used this prevents the processes NOT listed in x,y,z from calling MPI_Abort and 191 killing the user's debugging sessions. 192 193 .seealso: PetscSetDebugger(), PetscAttachDebugger() 194 @*/ 195 PetscErrorCode PetscWaitOnError() 196 { 197 petscwaitonerrorflg = PETSC_TRUE; 198 return 0; 199 } 200 201 /*@ 202 PetscAttachDebugger - Attaches the debugger to the running process. 203 204 Not Collective 205 206 Options Database Keys: 207 - -start_in_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] [-debugger_ranks m,n] -debug_terminal xterm or Terminal (for Apple) 208 . -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates debugger attachment 209 210 Level: advanced 211 212 Developer Notes: 213 Since this can be called by the error handler should it be calling SETERRQ() and CHKERRQ()? 214 215 .seealso: PetscSetDebugger(), PetscSetDefaultDebugger(), PetscSetDebugTerminal(), PetscAttachDebuggerErrorHandler(), PetscStopForDebugger() 216 @*/ 217 PetscErrorCode PetscAttachDebugger(void) 218 { 219 #if !defined(PETSC_CANNOT_START_DEBUGGER) && defined(PETSC_HAVE_FORK) 220 int child =0; 221 PetscReal sleeptime=0; 222 PetscErrorCode ierr; 223 char program[PETSC_MAX_PATH_LEN],display[256],hostname[64]; 224 #endif 225 226 PetscFunctionBegin; 227 #if defined(PETSC_CANNOT_START_DEBUGGER) || !defined(PETSC_HAVE_FORK) 228 (*PetscErrorPrintf)("System cannot start debugger\n"); 229 (*PetscErrorPrintf)("On Cray run program in Totalview debugger\n"); 230 (*PetscErrorPrintf)("On Windows use Developer Studio(MSDEV)\n"); 231 PETSCABORT(PETSC_COMM_WORLD,PETSC_ERR_SUP_SYS); 232 #else 233 ierr = PetscGetDisplay(display,sizeof(display));CHKERRQ(ierr); 234 ierr = PetscGetProgramName(program,sizeof(program));CHKERRQ(ierr); 235 if (ierr) { 236 (*PetscErrorPrintf)("Cannot determine program name\n"); 237 PetscFunctionReturn(PETSC_ERR_SYS); 238 } 239 if (!program[0]) { 240 (*PetscErrorPrintf)("Cannot determine program name\n"); 241 PetscFunctionReturn(PETSC_ERR_SYS); 242 } 243 child = (int)fork(); 244 if (child < 0) { 245 (*PetscErrorPrintf)("Error in fork() prior to attaching debugger\n"); 246 PetscFunctionReturn(PETSC_ERR_SYS); 247 } 248 petscindebugger = PETSC_TRUE; 249 250 /* 251 Swap role the parent and child. This is (I think) so that control c typed 252 in the debugger goes to the correct process. 253 */ 254 #if !defined(PETSC_DO_NOT_SWAP_CHILD_FOR_DEBUGGER) 255 if (child) child = 0; 256 else child = (int)getppid(); 257 #endif 258 259 if (child) { /* I am the parent, will run the debugger */ 260 const char *args[10]; 261 char pid[10]; 262 PetscInt j,jj; 263 PetscBool isdbx,isidb,isxldb,isxxgdb,isups,isxdb,isworkshop,isddd,iskdbg,islldb; 264 265 ierr = PetscGetHostName(hostname,sizeof(hostname));CHKERRQ(ierr); 266 /* 267 We need to send a continue signal to the "child" process on the 268 alpha, otherwise it just stays off forever 269 */ 270 #if defined(PETSC_NEED_KILL_FOR_DEBUGGER) 271 kill(child,SIGCONT); 272 #endif 273 sprintf(pid,"%d",child); 274 275 ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr); 276 ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr); 277 ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr); 278 ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr); 279 ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr); 280 ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr); 281 ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr); 282 ierr = PetscStrcmp(PetscDebugger,"idb",&isidb);CHKERRQ(ierr); 283 ierr = PetscStrcmp(PetscDebugger,"workshop",&isworkshop);CHKERRQ(ierr); 284 ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr); 285 286 if (isxxgdb || isups || isddd) { 287 args[1] = program; args[2] = pid; args[3] = "-display"; 288 args[0] = PetscDebugger; args[4] = display; args[5] = NULL; 289 printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname); 290 if (execvp(args[0],(char**)args) < 0) { 291 perror("Unable to start debugger"); 292 exit(0); 293 } 294 } else if (iskdbg) { 295 args[1] = "-p"; args[2] = pid; args[3] = program; args[4] = "-display"; 296 args[0] = PetscDebugger; args[5] = display; args[6] = NULL; 297 printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[3],pid,hostname); 298 if (execvp(args[0],(char**)args) < 0) { 299 perror("Unable to start debugger"); 300 exit(0); 301 } 302 } else if (isxldb) { 303 args[1] = "-a"; args[2] = pid; args[3] = program; args[4] = "-display"; 304 args[0] = PetscDebugger; args[5] = display; args[6] = NULL; 305 printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname); 306 if (execvp(args[0],(char**)args) < 0) { 307 perror("Unable to start debugger"); 308 exit(0); 309 } 310 } else if (isworkshop) { 311 args[1] = "-s"; args[2] = pid; args[3] = "-D"; args[4] = "-"; 312 args[0] = PetscDebugger; args[5] = pid; args[6] = "-display"; args[7] = display; args[8] = NULL; 313 printf("PETSC: Attaching %s to %s on %s\n",args[0],pid,hostname); 314 if (execvp(args[0],(char**)args) < 0) { 315 perror("Unable to start debugger"); 316 exit(0); 317 } 318 } else { 319 j = 0; 320 if (UseDebugTerminal) { 321 PetscBool cmp; 322 char *tmp,*tmp1; 323 ierr = PetscStrncmp(DebugTerminal,"Terminal",8,&cmp);CHKERRQ(ierr); 324 if (cmp) { 325 char command[1024]; 326 ierr = PetscSNPrintf(command,sizeof(command),"osascript -e 'tell app \"Terminal\" to do script \"lldb -p %s %s \"'\n",pid,program);CHKERRQ(ierr); 327 ierr = PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",NULL);CHKERRQ(ierr); 328 exit(0); 329 } 330 331 ierr = PetscStrncmp(DebugTerminal,"screen",6,&cmp);CHKERRQ(ierr); 332 if (!cmp) {ierr = PetscStrncmp(DebugTerminal,"gnome-terminal",6,&cmp);CHKERRQ(ierr);} 333 if (cmp) display[0] = 0; /* when using screen, we never pass -display */ 334 args[j++] = tmp = DebugTerminal; 335 if (display[0]) { 336 args[j++] = "-display"; args[j++] = display; 337 } 338 while (*tmp) { 339 ierr = PetscStrchr(tmp,' ',&tmp1);CHKERRQ(ierr); 340 if (!tmp1) break; 341 *tmp1 = 0; 342 tmp = tmp1+1; 343 args[j++] = tmp; 344 } 345 } 346 args[j++] = PetscDebugger; 347 jj = j; 348 /* this is for default gdb */ 349 args[j++] = program; 350 args[j++] = pid; 351 args[j++] = NULL; 352 353 if (isidb) { 354 j = jj; 355 args[j++] = "-pid"; 356 args[j++] = pid; 357 args[j++] = "-gdb"; 358 args[j++] = program; 359 args[j++] = NULL; 360 } 361 if (islldb) { 362 j = jj; 363 args[j++] = "-p"; 364 args[j++] = pid; 365 args[j++] = NULL; 366 } 367 if (isdbx) { 368 j = jj; 369 #if defined(PETSC_USE_P_FOR_DEBUGGER) 370 args[j++] = "-p"; 371 args[j++] = pid; 372 args[j++] = program; 373 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 374 args[j++] = "-l"; 375 args[j++] = "ALL"; 376 args[j++] = "-P"; 377 args[j++] = pid; 378 args[j++] = program; 379 #elif defined(PETSC_USE_A_FOR_DEBUGGER) 380 args[j++] = "-a"; 381 args[j++] = pid; 382 #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 383 args[j++] = "-pid"; 384 args[j++] = pid; 385 args[j++] = program; 386 #else 387 args[j++] = program; 388 args[j++] = pid; 389 #endif 390 args[j++] = NULL; 391 } 392 if (UseDebugTerminal) { 393 if (display[0]) printf("PETSC: Attaching %s to %s of pid %s on display %s on machine %s\n",PetscDebugger,program,pid,display,hostname); 394 else printf("PETSC: Attaching %s to %s on pid %s on %s\n",PetscDebugger,program,pid,hostname); 395 396 if (execvp(args[0],(char**)args) < 0) { 397 perror("Unable to start debugger in xterm"); 398 exit(0); 399 } 400 } else { 401 printf("PETSC: Attaching %s to %s of pid %s on %s\n",PetscDebugger,program,pid,hostname); 402 if (execvp(args[0],(char**)args) < 0) { 403 perror("Unable to start debugger"); 404 exit(0); 405 } 406 } 407 } 408 } else { /* I am the child, continue with user code */ 409 sleeptime = 10; /* default to sleep waiting for debugger */ 410 ierr = PetscOptionsGetReal(NULL,NULL,"-debugger_pause",&sleeptime,NULL);CHKERRQ(ierr); 411 if (sleeptime < 0) sleeptime = -sleeptime; 412 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 413 /* 414 HP cannot attach process to sleeping debugger, hence count instead 415 */ 416 { 417 PetscReal x = 1.0; 418 int i =10000000; 419 while (i--) x++; /* cannot attach to sleeper */ 420 } 421 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 422 /* 423 IBM sleep may return at anytime, hence must see if there is more time to sleep 424 */ 425 { 426 int left = sleeptime; 427 while (left > 0) left = PetscSleep(left) - 1; 428 } 429 #else 430 PetscSleep(sleeptime); 431 #endif 432 } 433 #endif 434 PetscFunctionReturn(0); 435 } 436 437 /*@C 438 PetscAttachDebuggerErrorHandler - Error handler that attaches 439 a debugger to a running process when an error is detected. 440 This routine is useful for examining variables, etc. 441 442 Not Collective 443 444 Input Parameters: 445 + comm - communicator over which error occurred 446 . line - the line number of the error (indicated by __LINE__) 447 . file - the file in which the error was detected (indicated by __FILE__) 448 . message - an error text string, usually just printed to the screen 449 . number - the generic error number 450 . p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT 451 - ctx - error handler context 452 453 Options Database Keys: 454 + -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates debugger attachment 455 - -start_in_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] [-debugger_ranks m,n] 456 457 Level: developer 458 459 Notes: 460 By default the GNU debugger, gdb, is used. Alternatives are cuda-gdb, lldb, dbx and 461 xxgdb,xldb (on IBM rs6000), xdb (on HP-UX). 462 463 Most users need not directly employ this routine and the other error 464 handlers, but can instead use the simplified interface SETERR, which has 465 the calling sequence 466 $ SETERRQ(PETSC_COMM_SELF,number,p,message) 467 468 Notes for experienced users: 469 Use PetscPushErrorHandler() to set the desired error handler. The 470 currently available PETSc error handlers are 471 $ PetscTraceBackErrorHandler() 472 $ PetscAttachDebuggerErrorHandler() 473 $ PetscAbortErrorHandler() 474 or you may write your own. 475 476 .seealso: PetscSetDebuggerFromString(), PetscSetDebugger(), PetscSetDefaultDebugger(), PetscError(), PetscPushErrorHandler(), PetscPopErrorHandler(), PetscTraceBackErrorHandler(), 477 PetscAbortErrorHandler(), PetscMPIAbortErrorHandler(), PetscEmacsClientErrorHandler(), PetscReturnErrorHandler(), PetscSetDebugTermainal() 478 @*/ 479 PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode num,PetscErrorType p,const char *mess,void *ctx) 480 { 481 PetscErrorCode ierr; 482 483 PetscFunctionBegin; 484 if (!fun) fun = "User provided function"; 485 if (!mess) mess = " "; 486 487 (*PetscErrorPrintf)("%s() at %s:%d %s\n",fun,file,line,mess); 488 489 ierr = PetscAttachDebugger(); 490 if (ierr) abort(); /* call abort because don't want to kill other MPI processes that may successfully attach to debugger */ 491 PetscFunctionReturn(0); 492 } 493 494 /*@C 495 PetscStopForDebugger - Prints a message to the screen indicating how to 496 attach to the process with the debugger and then waits for the 497 debugger to attach. 498 499 Not Collective 500 501 Options Database: 502 . -stop_for_debugger - will stop for you to attach the debugger when PetscInitialize() is called 503 504 Level: developer 505 506 Notes: 507 This is likely never needed since PetscAttachDebugger() is easier to use and seems to always work. 508 509 Developer Notes: 510 Since this can be called by the error handler, should it be calling SETERRQ() and CHKERRQ()? 511 512 .seealso: PetscSetDebugger(), PetscAttachDebugger() 513 @*/ 514 PetscErrorCode PetscStopForDebugger(void) 515 { 516 PetscErrorCode ierr; 517 PetscInt sleeptime=0; 518 #if !defined(PETSC_CANNOT_START_DEBUGGER) 519 int ppid; 520 PetscMPIInt rank; 521 char program[PETSC_MAX_PATH_LEN],hostname[256]; 522 PetscBool isdbx,isxldb,isxxgdb,isddd,iskdbg,isups,isxdb,islldb; 523 #endif 524 525 PetscFunctionBegin; 526 #if defined(PETSC_CANNOT_START_DEBUGGER) 527 (*PetscErrorPrintf)("System cannot start debugger; just continuing program\n"); 528 #else 529 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); 530 if (ierr) rank = 0; /* ignore error since this may be already in error handler */ 531 ierr = PetscGetHostName(hostname,sizeof(hostname)); 532 if (ierr) { 533 (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n"); 534 PetscFunctionReturn(0); 535 } 536 537 ierr = PetscGetProgramName(program,sizeof(program)); 538 if (ierr) { 539 (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 540 PetscFunctionReturn(0); 541 } 542 if (!program[0]) { 543 (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 544 PetscFunctionReturn(0); 545 } 546 547 ppid = getpid(); 548 549 ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr); 550 ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr); 551 ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr); 552 ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr); 553 ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr); 554 ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr); 555 ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr); 556 ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr); 557 558 if (isxxgdb || isups || isddd || iskdbg) printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid); 559 else if (isxldb) printf("[%d]%s>>%s -a %d %s\n",rank,hostname,PetscDebugger,ppid,program); 560 else if (islldb) printf("[%d]%s>>%s -p %d\n",rank,hostname,PetscDebugger,ppid); 561 else if (isdbx) { 562 #if defined(PETSC_USE_P_FOR_DEBUGGER) 563 printf("[%d]%s>>%s -p %d %s\n",rank,hostname,PetscDebugger,ppid,program); 564 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 565 printf("[%d]%s>>%s -l ALL -P %d %s\n",rank,hostname,PetscDebugger,ppid,program); 566 #elif defined(PETSC_USE_A_FOR_DEBUGGER) 567 printf("[%d]%s>>%s -a %d\n",rank,hostname,PetscDebugger,ppid); 568 #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 569 printf("[%d]%s>>%s -pid %d %s\n",rank,hostname,PetscDebugger,ppid,program); 570 #else 571 printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid); 572 #endif 573 } 574 #endif /* PETSC_CANNOT_START_DEBUGGER */ 575 576 fflush(stdout); /* ignore error because may already be in error handler */ 577 578 sleeptime = 25; /* default to sleep waiting for debugger */ 579 PetscOptionsGetInt(NULL,NULL,"-debugger_pause",&sleeptime,NULL); /* ignore error because may already be in error handler */ 580 if (sleeptime < 0) sleeptime = -sleeptime; 581 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 582 /* 583 HP cannot attach process to sleeping debugger, hence count instead 584 */ 585 { 586 PetscReal x = 1.0; 587 int i =10000000; 588 while (i--) x++; /* cannot attach to sleeper */ 589 } 590 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 591 /* 592 IBM sleep may return at anytime, hence must see if there is more time to sleep 593 */ 594 { 595 int left = sleeptime; 596 while (left > 0) left = sleep(left) - 1; 597 } 598 #else 599 PetscSleep(sleeptime); 600 #endif 601 PetscFunctionReturn(0); 602 } 603