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 194 .seealso: PetscSetDebugger(), PetscAttachDebugger() 195 @*/ 196 PetscErrorCode PetscWaitOnError() 197 { 198 petscwaitonerrorflg = PETSC_TRUE; 199 return 0; 200 } 201 202 /*@ 203 PetscAttachDebugger - Attaches the debugger to the running process. 204 205 Not Collective 206 207 Options Database Keys: 208 - -start_in_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] [-debugger_ranks m,n] -debug_terminal xterm or Terminal (for Apple) 209 . -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates debugger attachment 210 211 Level: advanced 212 213 Developer Notes: 214 Since this can be called by the error handler should it be calling SETERRQ() and CHKERRQ()? 215 216 .seealso: PetscSetDebugger(), PetscSetDefaultDebugger(), PetscSetDebugTerminal(), PetscAttachDebuggerErrorHandler(), PetscStopForDebugger() 217 @*/ 218 PetscErrorCode PetscAttachDebugger(void) 219 { 220 #if !defined(PETSC_CANNOT_START_DEBUGGER) && defined(PETSC_HAVE_FORK) 221 int child =0; 222 PetscReal sleeptime=0; 223 PetscErrorCode ierr; 224 char program[PETSC_MAX_PATH_LEN],display[256],hostname[64]; 225 #endif 226 227 PetscFunctionBegin; 228 #if defined(PETSC_CANNOT_START_DEBUGGER) || !defined(PETSC_HAVE_FORK) 229 (*PetscErrorPrintf)("System cannot start debugger\n"); 230 (*PetscErrorPrintf)("On Cray run program in Totalview debugger\n"); 231 (*PetscErrorPrintf)("On Windows use Developer Studio(MSDEV)\n"); 232 PETSCABORT(PETSC_COMM_WORLD,PETSC_ERR_SUP_SYS); 233 #else 234 ierr = PetscGetDisplay(display,sizeof(display));CHKERRQ(ierr); 235 ierr = PetscGetProgramName(program,sizeof(program));CHKERRQ(ierr); 236 if (ierr) { 237 (*PetscErrorPrintf)("Cannot determine program name\n"); 238 PetscFunctionReturn(PETSC_ERR_SYS); 239 } 240 if (!program[0]) { 241 (*PetscErrorPrintf)("Cannot determine program name\n"); 242 PetscFunctionReturn(PETSC_ERR_SYS); 243 } 244 child = (int)fork(); 245 if (child < 0) { 246 (*PetscErrorPrintf)("Error in fork() prior to attaching debugger\n"); 247 PetscFunctionReturn(PETSC_ERR_SYS); 248 } 249 petscindebugger = PETSC_TRUE; 250 251 /* 252 Swap role the parent and child. This is (I think) so that control c typed 253 in the debugger goes to the correct process. 254 */ 255 #if !defined(PETSC_DO_NOT_SWAP_CHILD_FOR_DEBUGGER) 256 if (child) child = 0; 257 else child = (int)getppid(); 258 #endif 259 260 if (child) { /* I am the parent, will run the debugger */ 261 const char *args[10]; 262 char pid[10]; 263 PetscInt j,jj; 264 PetscBool isdbx,isidb,isxldb,isxxgdb,isups,isxdb,isworkshop,isddd,iskdbg,islldb; 265 266 ierr = PetscGetHostName(hostname,sizeof(hostname));CHKERRQ(ierr); 267 /* 268 We need to send a continue signal to the "child" process on the 269 alpha, otherwise it just stays off forever 270 */ 271 #if defined(PETSC_NEED_KILL_FOR_DEBUGGER) 272 kill(child,SIGCONT); 273 #endif 274 sprintf(pid,"%d",child); 275 276 ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr); 277 ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr); 278 ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr); 279 ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr); 280 ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr); 281 ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr); 282 ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr); 283 ierr = PetscStrcmp(PetscDebugger,"idb",&isidb);CHKERRQ(ierr); 284 ierr = PetscStrcmp(PetscDebugger,"workshop",&isworkshop);CHKERRQ(ierr); 285 ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr); 286 287 if (isxxgdb || isups || isddd) { 288 args[1] = program; args[2] = pid; args[3] = "-display"; 289 args[0] = PetscDebugger; args[4] = display; args[5] = NULL; 290 printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname); 291 if (execvp(args[0],(char**)args) < 0) { 292 perror("Unable to start debugger"); 293 exit(0); 294 } 295 } else if (iskdbg) { 296 args[1] = "-p"; args[2] = pid; args[3] = program; args[4] = "-display"; 297 args[0] = PetscDebugger; args[5] = display; args[6] = NULL; 298 printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[3],pid,hostname); 299 if (execvp(args[0],(char**)args) < 0) { 300 perror("Unable to start debugger"); 301 exit(0); 302 } 303 } else if (isxldb) { 304 args[1] = "-a"; args[2] = pid; args[3] = program; args[4] = "-display"; 305 args[0] = PetscDebugger; args[5] = display; args[6] = NULL; 306 printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname); 307 if (execvp(args[0],(char**)args) < 0) { 308 perror("Unable to start debugger"); 309 exit(0); 310 } 311 } else if (isworkshop) { 312 args[1] = "-s"; args[2] = pid; args[3] = "-D"; args[4] = "-"; 313 args[0] = PetscDebugger; args[5] = pid; args[6] = "-display"; args[7] = display; args[8] = NULL; 314 printf("PETSC: Attaching %s to %s on %s\n",args[0],pid,hostname); 315 if (execvp(args[0],(char**)args) < 0) { 316 perror("Unable to start debugger"); 317 exit(0); 318 } 319 } else { 320 j = 0; 321 if (UseDebugTerminal) { 322 PetscBool cmp; 323 char *tmp,*tmp1; 324 ierr = PetscStrncmp(DebugTerminal,"Terminal",8,&cmp);CHKERRQ(ierr); 325 if (cmp) { 326 char command[1024]; 327 ierr = PetscSNPrintf(command,sizeof(command),"osascript -e 'tell app \"Terminal\" to do script \"lldb -p %s %s \"'\n",pid,program);CHKERRQ(ierr); 328 ierr = PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",NULL);CHKERRQ(ierr); 329 exit(0); 330 } 331 332 ierr = PetscStrncmp(DebugTerminal,"screen",6,&cmp);CHKERRQ(ierr); 333 if (!cmp) {ierr = PetscStrncmp(DebugTerminal,"gnome-terminal",6,&cmp);CHKERRQ(ierr);} 334 if (cmp) display[0] = 0; /* when using screen, we never pass -display */ 335 args[j++] = tmp = DebugTerminal; 336 if (display[0]) { 337 args[j++] = "-display"; args[j++] = display; 338 } 339 while (*tmp) { 340 ierr = PetscStrchr(tmp,' ',&tmp1);CHKERRQ(ierr); 341 if (!tmp1) break; 342 *tmp1 = 0; 343 tmp = tmp1+1; 344 args[j++] = tmp; 345 } 346 } 347 args[j++] = PetscDebugger; 348 jj = j; 349 /* this is for default gdb */ 350 args[j++] = program; 351 args[j++] = pid; 352 args[j++] = NULL; 353 354 if (isidb) { 355 j = jj; 356 args[j++] = "-pid"; 357 args[j++] = pid; 358 args[j++] = "-gdb"; 359 args[j++] = program; 360 args[j++] = NULL; 361 } 362 if (islldb) { 363 j = jj; 364 args[j++] = "-p"; 365 args[j++] = pid; 366 args[j++] = NULL; 367 } 368 if (isdbx) { 369 j = jj; 370 #if defined(PETSC_USE_P_FOR_DEBUGGER) 371 args[j++] = "-p"; 372 args[j++] = pid; 373 args[j++] = program; 374 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 375 args[j++] = "-l"; 376 args[j++] = "ALL"; 377 args[j++] = "-P"; 378 args[j++] = pid; 379 args[j++] = program; 380 #elif defined(PETSC_USE_A_FOR_DEBUGGER) 381 args[j++] = "-a"; 382 args[j++] = pid; 383 #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 384 args[j++] = "-pid"; 385 args[j++] = pid; 386 args[j++] = program; 387 #else 388 args[j++] = program; 389 args[j++] = pid; 390 #endif 391 args[j++] = NULL; 392 } 393 if (UseDebugTerminal) { 394 if (display[0]) printf("PETSC: Attaching %s to %s of pid %s on display %s on machine %s\n",PetscDebugger,program,pid,display,hostname); 395 else printf("PETSC: Attaching %s to %s on pid %s on %s\n",PetscDebugger,program,pid,hostname); 396 397 if (execvp(args[0],(char**)args) < 0) { 398 perror("Unable to start debugger in xterm"); 399 exit(0); 400 } 401 } else { 402 printf("PETSC: Attaching %s to %s of pid %s on %s\n",PetscDebugger,program,pid,hostname); 403 if (execvp(args[0],(char**)args) < 0) { 404 perror("Unable to start debugger"); 405 exit(0); 406 } 407 } 408 } 409 } else { /* I am the child, continue with user code */ 410 sleeptime = 10; /* default to sleep waiting for debugger */ 411 ierr = PetscOptionsGetReal(NULL,NULL,"-debugger_pause",&sleeptime,NULL);CHKERRQ(ierr); 412 if (sleeptime < 0) sleeptime = -sleeptime; 413 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 414 /* 415 HP cannot attach process to sleeping debugger, hence count instead 416 */ 417 { 418 PetscReal x = 1.0; 419 int i =10000000; 420 while (i--) x++; /* cannot attach to sleeper */ 421 } 422 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 423 /* 424 IBM sleep may return at anytime, hence must see if there is more time to sleep 425 */ 426 { 427 int left = sleeptime; 428 while (left > 0) left = PetscSleep(left) - 1; 429 } 430 #else 431 PetscSleep(sleeptime); 432 #endif 433 } 434 #endif 435 PetscFunctionReturn(0); 436 } 437 438 /*@C 439 PetscAttachDebuggerErrorHandler - Error handler that attaches 440 a debugger to a running process when an error is detected. 441 This routine is useful for examining variables, etc. 442 443 Not Collective 444 445 Input Parameters: 446 + comm - communicator over which error occurred 447 . line - the line number of the error (indicated by __LINE__) 448 . file - the file in which the error was detected (indicated by __FILE__) 449 . message - an error text string, usually just printed to the screen 450 . number - the generic error number 451 . p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT 452 - ctx - error handler context 453 454 Options Database Keys: 455 + -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates debugger attachment 456 - -start_in_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] [-debugger_ranks m,n] 457 458 Level: developer 459 460 Notes: 461 By default the GNU debugger, gdb, is used. Alternatives are cuda-gdb, lldb, dbx and 462 xxgdb,xldb (on IBM rs6000), xdb (on HP-UX). 463 464 Most users need not directly employ this routine and the other error 465 handlers, but can instead use the simplified interface SETERR, which has 466 the calling sequence 467 $ SETERRQ(PETSC_COMM_SELF,number,p,message) 468 469 Notes for experienced users: 470 Use PetscPushErrorHandler() to set the desired error handler. The 471 currently available PETSc error handlers are 472 $ PetscTraceBackErrorHandler() 473 $ PetscAttachDebuggerErrorHandler() 474 $ PetscAbortErrorHandler() 475 or you may write your own. 476 477 478 .seealso: PetscSetDebuggerFromString(), PetscSetDebugger(), PetscSetDefaultDebugger(), PetscError(), PetscPushErrorHandler(), PetscPopErrorHandler(), PetscTraceBackErrorHandler(), 479 PetscAbortErrorHandler(), PetscMPIAbortErrorHandler(), PetscEmacsClientErrorHandler(), PetscReturnErrorHandler(), PetscSetDebugTermainal() 480 @*/ 481 PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode num,PetscErrorType p,const char *mess,void *ctx) 482 { 483 PetscErrorCode ierr; 484 485 PetscFunctionBegin; 486 if (!fun) fun = "User provided function"; 487 if (!mess) mess = " "; 488 489 (*PetscErrorPrintf)("%s() at %s:%d %s\n",fun,file,line,mess); 490 491 ierr = PetscAttachDebugger(); 492 if (ierr) abort(); /* call abort because don't want to kill other MPI processes that may successfully attach to debugger */ 493 PetscFunctionReturn(0); 494 } 495 496 /*@C 497 PetscStopForDebugger - Prints a message to the screen indicating how to 498 attach to the process with the debugger and then waits for the 499 debugger to attach. 500 501 Not Collective 502 503 Options Database: 504 . -stop_for_debugger - will stop for you to attach the debugger when PetscInitialize() is called 505 506 Level: developer 507 508 Notes: 509 This is likely never needed since PetscAttachDebugger() is easier to use and seems to always work. 510 511 Developer Notes: 512 Since this can be called by the error handler, should it be calling SETERRQ() and CHKERRQ()? 513 514 .seealso: PetscSetDebugger(), PetscAttachDebugger() 515 @*/ 516 PetscErrorCode PetscStopForDebugger(void) 517 { 518 PetscErrorCode ierr; 519 PetscInt sleeptime=0; 520 #if !defined(PETSC_CANNOT_START_DEBUGGER) 521 int ppid; 522 PetscMPIInt rank; 523 char program[PETSC_MAX_PATH_LEN],hostname[256]; 524 PetscBool isdbx,isxldb,isxxgdb,isddd,iskdbg,isups,isxdb,islldb; 525 #endif 526 527 PetscFunctionBegin; 528 #if defined(PETSC_CANNOT_START_DEBUGGER) 529 (*PetscErrorPrintf)("System cannot start debugger; just continuing program\n"); 530 #else 531 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); 532 if (ierr) rank = 0; /* ignore error since this may be already in error handler */ 533 ierr = PetscGetHostName(hostname,sizeof(hostname)); 534 if (ierr) { 535 (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n"); 536 PetscFunctionReturn(0); 537 } 538 539 ierr = PetscGetProgramName(program,sizeof(program)); 540 if (ierr) { 541 (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 542 PetscFunctionReturn(0); 543 } 544 if (!program[0]) { 545 (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 546 PetscFunctionReturn(0); 547 } 548 549 ppid = getpid(); 550 551 ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr); 552 ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr); 553 ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr); 554 ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr); 555 ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr); 556 ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr); 557 ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr); 558 ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr); 559 560 if (isxxgdb || isups || isddd || iskdbg) printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid); 561 else if (isxldb) printf("[%d]%s>>%s -a %d %s\n",rank,hostname,PetscDebugger,ppid,program); 562 else if (islldb) printf("[%d]%s>>%s -p %d\n",rank,hostname,PetscDebugger,ppid); 563 else if (isdbx) { 564 #if defined(PETSC_USE_P_FOR_DEBUGGER) 565 printf("[%d]%s>>%s -p %d %s\n",rank,hostname,PetscDebugger,ppid,program); 566 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 567 printf("[%d]%s>>%s -l ALL -P %d %s\n",rank,hostname,PetscDebugger,ppid,program); 568 #elif defined(PETSC_USE_A_FOR_DEBUGGER) 569 printf("[%d]%s>>%s -a %d\n",rank,hostname,PetscDebugger,ppid); 570 #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 571 printf("[%d]%s>>%s -pid %d %s\n",rank,hostname,PetscDebugger,ppid,program); 572 #else 573 printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid); 574 #endif 575 } 576 #endif /* PETSC_CANNOT_START_DEBUGGER */ 577 578 fflush(stdout); /* ignore error because may already be in error handler */ 579 580 sleeptime = 25; /* default to sleep waiting for debugger */ 581 PetscOptionsGetInt(NULL,NULL,"-debugger_pause",&sleeptime,NULL); /* ignore error because may already be in error handler */ 582 if (sleeptime < 0) sleeptime = -sleeptime; 583 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 584 /* 585 HP cannot attach process to sleeping debugger, hence count instead 586 */ 587 { 588 PetscReal x = 1.0; 589 int i =10000000; 590 while (i--) x++; /* cannot attach to sleeper */ 591 } 592 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 593 /* 594 IBM sleep may return at anytime, hence must see if there is more time to sleep 595 */ 596 { 597 int left = sleeptime; 598 while (left > 0) left = sleep(left) - 1; 599 } 600 #else 601 PetscSleep(sleeptime); 602 #endif 603 PetscFunctionReturn(0); 604 } 605