|
|
1.1 ! root 1: #include "frame.pri" ! 2: #include "hostcore.h" ! 3: #include "process.pri" ! 4: #include "srcdir.h" ! 5: #include "expr.pub" ! 6: #include "master.pub" ! 7: #include "bpts.pri" ! 8: #include "memory.pub" ! 9: #include "asm.pub" ! 10: #include "symtab.pub" ! 11: #include "symbol.h" ! 12: #include "srctext.pub" ! 13: #include "format.pub" ! 14: #include "journal.pub" ! 15: SRCFILE("process.c") ! 16: ! 17: void Process::pop() ! 18: { ! 19: trace("%d.pop()", this); VOK; ! 20: journal()->insert("pop"); ! 21: char *error = 0; ! 22: if( core->behavs() == ACTIVE ){ ! 23: stop(); ! 24: sleep(1); ! 25: } ! 26: if( !error ) error = core->popcallstack(); ! 27: if( error ) insert(ERRORKEY, error); ! 28: habeascorpus(STMT_STEPPED, changes()); ! 29: } ! 30: ! 31: char *Process::kbd(char *s) ! 32: { ! 33: trace("%d.kbd(%s)", this, s); OK("Process::kbd"); ! 34: journal()->insert("kbd: %s", s); ! 35: char p[256], c[256], e[256]; ! 36: long l; ! 37: if( 3 == sscanf(s, "bpt %[^:]:%d %s", p, &l, e) ){ ! 38: BptReq r(p, l, e); ! 39: return r.set(this); ! 40: } ! 41: if( 2 == sscanf(s, " bpt %[^:]:%d", p, &l, e) ){ ! 42: BptReq r(p, l); ! 43: return r.set(this); ! 44: } ! 45: if( 3 == sscanf(s, "bpt %[^{}]%[{}] %s", p, c, e) ){ ! 46: BptReq r(p, c, e); ! 47: return r.set(this); ! 48: } ! 49: if( 2 == sscanf(s, "bpt %[^{}]%[{}]", p, c) ){ ! 50: BptReq r(p, c); ! 51: return r.set(this); ! 52: } ! 53: return help(); ! 54: } ! 55: ! 56: char *Process::help() ! 57: { ! 58: return "<ugly-keyboard-language> { cat /usr/jerq/lib/pi.help }"; ! 59: } ! 60: ! 61: Process::Process(Process *sib, char *p, char *s, char *c) ! 62: { ! 63: trace( "%d.Process(%d,%s,%s,%s)",this,sib,p,s,c); VOK; ! 64: sibling = sib; ! 65: procpath = p ? sf("%s",p) : 0; ! 66: stabpath = s ? sf("%s",s) : 0; ! 67: comment = c ? sf("%s",c) : 0; ! 68: stoprequest = 0; ! 69: cycles = 0; ! 70: _prefix = 0; ! 71: srcdir = 0; ! 72: parent = 0; ! 73: isdead = 0; ! 74: padlines = 0; ! 75: } ! 76: ! 77: void Process::currentstmt() ! 78: { ! 79: trace( "%d.currentstmt()", this ); VOK; ! 80: ! 81: if( !callstk ){ ! 82: insert(ERRORKEY, "cannot show source (there is no callstack yet)"); ! 83: return; ! 84: } ! 85: for( long l = 0; l < callstk->size; ++l ){ ! 86: Frame *f = frame(l); ! 87: if( !f->func ) continue; ! 88: Stmt *stmt = f->func->stmt(f->pc); ! 89: /* Stmt *stmt = (Stmt*) core->symtab()->loctosym(U_STMT, f->pc); */ ! 90: if( stmt ){ ! 91: stmt->select(); ! 92: return; ! 93: } ! 94: } ! 95: insert(ERRORKEY, "cannot show source for any frame on callstack"); ! 96: pad->makecurrent(); ! 97: } ! 98: ! 99: Index Process::carte() { return ZIndex; } ! 100: ! 101: void Process::closeframes() ! 102: { ! 103: trace( "%d.closeframes()", this ); VOK; ! 104: if( callstk ) { ! 105: for( long l = callstk->size-1; l>=0; --l ){ ! 106: if( callstk->fpf[l].frame ){ ! 107: callstk->fpf[l].frame->hostclose(); ! 108: delete callstk->fpf[l].frame; ! 109: callstk->fpf[l].frame = 0; ! 110: } ! 111: } ! 112: delete callstk; ! 113: callstk = 0; ! 114: } ! 115: } ! 116: ! 117: void Process::userclose() ! 118: { ! 119: trace( "%d.userclose()", this ); VOK; ! 120: if( _journal ){ ! 121: _journal->hostclose(); ! 122: delete _journal; ! 123: _journal = 0; ! 124: } ! 125: if( _bpts ){ ! 126: _bpts->hostclose(); ! 127: delete _bpts; ! 128: _bpts = 0; ! 129: } ! 130: if( srcdir ){ ! 131: srcdir->hostclose(); ! 132: delete srcdir; ! 133: srcdir = 0; ! 134: } ! 135: if( memory ){ ! 136: memory->userclose(); ! 137: delete memory; ! 138: memory = 0; ! 139: } ! 140: if( _asm ){ ! 141: _asm->userclose(); ! 142: delete _asm; ! 143: _asm = 0; ! 144: } ! 145: closeframes(); ! 146: if( core ){ ! 147: core->close(); ! 148: delete core; ! 149: core = 0; ! 150: } ! 151: if( globals ){ ! 152: globals->hostclose(); ! 153: delete globals; ! 154: globals = 0; ! 155: } ! 156: if( pad ){ ! 157: delete pad; ! 158: pad = 0; ! 159: } ! 160: isdead = 1; ! 161: master->insert(this); ! 162: master->makeproc(procpath, stabpath, comment); ! 163: } ! 164: ! 165: Bpts *Process::bpts() { return _bpts; } ! 166: ! 167: SymTab *Process::symtab() { return core->symtab(); } ! 168: ! 169: void Process::banner() ! 170: { ! 171: trace( "%d.banner()", this ); VOK; ! 172: if( pad ){ ! 173: pad->name(procpath); /* basename ? */ ! 174: pad->banner("Process: %s", procpath); ! 175: } ! 176: } ! 177: ! 178: void Process::openpad() ! 179: { ! 180: trace("%d.openpad(%d)", this); VOK; ! 181: if( !pad ){ ! 182: pad = new Pad( (PadRcv*) this ); ! 183: pad->options(TRUNCATE|NO_TILDE); ! 184: banner(); ! 185: pad->lines(padlines = ERRORKEY); ! 186: pad->clear(); /* from a previous attempt! */ ! 187: pad->makecurrent(); ! 188: } ! 189: pad->makecurrent(); ! 190: } ! 191: ! 192: void Process::openglobals(Menu *m) ! 193: { ! 194: trace("%d.openglobals()", this); VOK; ! 195: if( !globals ) globals = new Globals(core); ! 196: globals->open(); ! 197: if( m) globals->addvars(m); ! 198: } ! 199: ! 200: void Process::opentypes() ! 201: { ! 202: trace("%d.opentypes()", this); VOK; ! 203: core->symtab()->opentypes(); ! 204: } ! 205: ! 206: void Process::srcfiles() ! 207: { ! 208: trace( "%d.srcfiles()", this ); VOK; ! 209: if( !srcdir ) srcdir = new SrcDir( this ); ! 210: srcdir->open(); ! 211: } ! 212: ! 213: void Process::merge() ! 214: { ! 215: trace( "%d.merge()",this,); VOK; ! 216: CallStk *old = callstk; ! 217: callstk = core->callstack(); ! 218: if( !callstk ){ ! 219: if (old) { ! 220: callstk = old; ! 221: closeframes(); ! 222: } ! 223: insert(ERRORKEY, "cannot obtain callstack"); ! 224: return; ! 225: } ! 226: if( !old ) return; ! 227: long c = callstk->size-1, i; ! 228: for( long o = old->size-1; o>=0; --o ){ ! 229: Frame *of; ! 230: if( of = old->fpf[o].frame ){ ! 231: for( i = c; i>=0; --i ) ! 232: if( callstk->fpf[i].func == old->fpf[o].func ) ! 233: break; ! 234: if( i >= 0 ){ ! 235: Frame nf = callstk->frame(i); ! 236: of->ap = nf.ap; ! 237: of->fp = nf.fp; ! 238: of->pc = nf.pc; ! 239: of->regbase = nf.regbase; ! 240: of->regsave = nf.regsave; ! 241: if( of->pad ){ ! 242: of->banner(); ! 243: of->changes(); ! 244: } ! 245: callstk->fpf[i].frame = of; ! 246: of->level = i; ! 247: c = i-1; ! 248: } else { ! 249: of->hostclose(); ! 250: delete of; ! 251: } ! 252: } ! 253: } ! 254: delete old; ! 255: } ! 256: ! 257: void Process::mergeback(long) /* arg never used - should go away */ ! 258: { ! 259: trace( "%d.mergeback()", this ); VOK; ! 260: ! 261: if( core->behavs() == ACTIVE ){ ! 262: stop(); ! 263: if( core->behavs() == ACTIVE ){ ! 264: insert(ERRORKEY, "process not stopped"); ! 265: return; ! 266: } ! 267: } ! 268: merge(); ! 269: pad->lines(padlines = ERRORKEY); ! 270: if( callstk ) pad->lines(padlines = callstk->size+ERRORKEY); ! 271: linereq(BEHAVSKEY); // it gets linereq'd? ! 272: } ! 273: ! 274: Frame *Process::frame(long l) ! 275: { ! 276: trace("%d.frame(%d)", this, l); OK(0); ! 277: if( !callstk || l < 0 || l >= callstk->size ) return 0; ! 278: Frame *f = callstk->fpf[l].frame; ! 279: if( f ) return f; ! 280: f = callstk->fpf[l].frame = new Frame(core); // gets its own oid ! 281: PadRcv save = *(PadRcv*)f; // save PadRcv part ! 282: *f = callstk->frame(l); ! 283: *(PadRcv*)f = save; // restore PadRcv part ! 284: f->func = callstk->fpf[l].func; ! 285: f->level = l; ! 286: return f; ! 287: } ! 288: ! 289: void Process::linereq(long l, Attrib a) ! 290: { ! 291: trace("%d.linereq(%d,%x)", this, l, a); VOK; ! 292: if( l <= ERRORKEY ){ ! 293: pad->insert(l, a, "%s", bls[l].text); ! 294: journal()->insert("%s", bls[l].text); ! 295: return; ! 296: } ! 297: if( padlines && l>padlines ) return; // too late ! 298: Frame *f = frame(l-ERRORKEY-1); ! 299: Bls t; ! 300: pad->insert(l, a|DONT_CUT, (PadRcv*)f, f->carte(), "%s", f->text(t)); ! 301: if( l == ERRORKEY+1 ) ! 302: journal()->insert("%s", t.text); ! 303: } ! 304: ! 305: void Process::insert(long l, PRINTF_ARGS) ! 306: { ! 307: trace("%d.insert(%d)", this, l); VOK; ! 308: if( l == ERRORKEY ){ // ERROR doesn't change much ! 309: Bls cmp; ! 310: cmp.af(PRINTF_COPY); ! 311: if( !strcmp(cmp.text, bls[ERRORKEY].text) ) ! 312: return; ! 313: } ! 314: if( l > ERRORKEY ) return; ! 315: bls[l].clear(); ! 316: bls[l].af(PRINTF_COPY); ! 317: pad->insert(l, DONT_CUT, "%s", bls[l].text); ! 318: } ! 319: ! 320: void Process::openframe(long pc, char *k) ! 321: { ! 322: trace( "%d.openframe(%d)", this, pc ); VOK; ! 323: ! 324: Func *func = (Func*) symtab()->loctosym(U_FUNC, pc); ! 325: if( !func ){ ! 326: pad->insert(ERRORKEY, "cannot find function"); ! 327: return; ! 328: } ! 329: if( !callstk ){ ! 330: pad->insert(ERRORKEY, "there is no callstack yet"); ! 331: return; ! 332: } ! 333: long l; ! 334: Frame *f = 0; ! 335: for( l = 0; l < callstk->size; ++l ) ! 336: if( callstk->fpf[l].func == func ){ ! 337: f = frame(l); ! 338: f->open(); ! 339: break; ! 340: } ! 341: if( !f ){ ! 342: mergeback(2); ! 343: insert(ERRORKEY, "%s is not on callstack", func->text()); ! 344: pad->makecurrent(); ! 345: return; ! 346: } ! 347: for( ++l; l < callstk->size; ++l ) ! 348: if( callstk->fpf[l].func == func ){ ! 349: f->pad->insert(1, "called recursively - deepest instance"); ! 350: break; ! 351: } ! 352: if( f && k ) f->kbd(k); ! 353: } ! 354: ! 355: void Process::openmemory(long a) ! 356: { ! 357: trace( "%d.openmemory(%d)", this, a ); VOK; ! 358: if( !memory ) memory = new Memory(core); ! 359: memory->open(a); ! 360: } ! 361: ! 362: void Process::openasm(long a) ! 363: { ! 364: trace("%d.openasm()", this); VOK; ! 365: if( !_asm ) _asm = core->newAsm(); ! 366: if( a!= -1 ) _asm->open(a); ! 367: } ! 368: ! 369: void Process::openjournal() ! 370: { ! 371: trace("%d.openjournal()", this); VOK; ! 372: if( !_journal) ! 373: _journal = new Journal(basename(core->procpath())); ! 374: journal()->open(); ! 375: } ! 376: ! 377: Journal *Process::journal() ! 378: { ! 379: trace("%d.journal()", this); OK(0); ! 380: return _journal; ! 381: } ! 382: ! 383: void Process::openbpts() ! 384: { ! 385: trace( "%d.openbpts()", this ); VOK; ! 386: bpts()->pad->makecurrent(); ! 387: } ! 388: ! 389: void Process::stop() ! 390: { ! 391: trace( "%d.stop()", this ); VOK; ! 392: ! 393: IF_LIVE( !core->online() ) return; ! 394: journal()->insert("stop"); ! 395: insert(ERRORKEY, 0); ! 396: switch( core->behavs() ){ ! 397: case ACTIVE: ! 398: insert(ERRORKEY, core->stop()); ! 399: sleep(1); ! 400: cycle(); /* will ignore next cycle from term */ ! 401: return; ! 402: default: ! 403: stoprequest = 1; ! 404: habeascorpus(core->behavs(),changes()); ! 405: } ! 406: } ! 407: ! 408: void Process::stmtstep(long i) ! 409: { ! 410: char *error = 0; ! 411: class Stmt *stmt; ! 412: long changed = 0; ! 413: ! 414: trace("%d.stmtstep(%d)", this, i); VOK; ! 415: journal()->insert("step %d stmts", i); ! 416: insert(ERRORKEY, 0); ! 417: stoprequest = 0; ! 418: for( ; i>0 && !error && changed==0; --i ){ ! 419: if( i>1 ) insert(BEHAVSKEY, "step %d statements", i); ! 420: if( !(stmt = (Stmt*) symtab()->loctosym(U_STMT, core->pc())) ) ! 421: error = "cannot locate start stmt for step"; ! 422: else ! 423: error = core->step(stmt->range.lo, stmt->range.hi); ! 424: if( !error ) changed = changes(); ! 425: } ! 426: insert(ERRORKEY, error); ! 427: if( error ){ ! 428: docycle(); ! 429: return; ! 430: } ! 431: habeascorpus(STMT_STEPPED, changed); ! 432: } ! 433: ! 434: void Process::stepinto() ! 435: { ! 436: char *error = 0; ! 437: class Stmt *stmt; ! 438: long time(long*), t0 = time(0), timeout = 10, changed = 0; ! 439: ! 440: trace( "%d.stepinto()", this ); VOK; ! 441: journal()->insert("step into function"); ! 442: insert(ERRORKEY, 0); ! 443: stoprequest = 0; ! 444: if( !(stmt = (Stmt*) symtab()->loctosym(U_STMT, core->pc())) ) ! 445: error = "cannot locate start stmt for step into"; ! 446: while( !error && changed==0 ){ ! 447: if( core->pc() < stmt->range.lo ) break; ! 448: if( core->pc() >= stmt->range.hi ) break; ! 449: error = core->step(); ! 450: if( !error && time(0) > t0+timeout ) ! 451: error = sf( "step into timeout (%d secs)", timeout ); ! 452: if( !error ) ! 453: changed = changes(); ! 454: } ! 455: if( !error ) ! 456: error = core->stepprolog(); ! 457: insert(ERRORKEY, error); ! 458: if( error ){ ! 459: docycle(); ! 460: return; ! 461: } ! 462: habeascorpus(STMT_STEPPED, changed); ! 463: } ! 464: ! 465: void Process::instrstep(long i) ! 466: { ! 467: char *error = 0; ! 468: long changed = 0; ! 469: ! 470: trace("%d.instrstep(%d)", this, i); VOK; ! 471: journal()->insert("step %d instructions", i); ! 472: stoprequest = 0; ! 473: insert(ERRORKEY, 0); ! 474: while( i>0 && !error && changed==0 ){ ! 475: insert(BEHAVSKEY, "step %d instructions", i--); ! 476: error = core->step(); ! 477: if( !error ) changed = changes(); ! 478: } ! 479: insert(ERRORKEY, error); ! 480: if( error ){ ! 481: docycle(); ! 482: return; ! 483: } ! 484: habeascorpus(INST_STEPPED,changed); ! 485: openasm( core->pc() ); ! 486: } ! 487: ! 488: void Process::stepover(long lo, long hi) ! 489: { ! 490: trace( "%d.stepover()", this ); VOK; ! 491: journal()->insert("step over call"); ! 492: stoprequest = 0; ! 493: char *error = core->step(lo, hi); ! 494: insert(ERRORKEY, error); ! 495: if( error ){ ! 496: docycle(); ! 497: return; ! 498: } ! 499: habeascorpus(INST_STEPPED, changes()); ! 500: openasm(core->pc()); ! 501: } ! 502: ! 503: void Process::go() ! 504: { ! 505: Behavs b = core->behavs(); ! 506: char *error = 0; ! 507: ! 508: trace( "%d.go() %s", this, BehavsName(b) ); VOK; ! 509: journal()->insert("run"); ! 510: stoprequest = 0; ! 511: switch( b ){ ! 512: case ACTIVE: ! 513: case ERRORED: ! 514: habeascorpus(b,0); ! 515: break; ! 516: case BREAKED: ! 517: if( !error ) error = core->step(); ! 518: case INST_STEPPED: ! 519: case STMT_STEPPED: ! 520: case PENDING: ! 521: case HALTED: ! 522: if( !error ) _bpts->lay(); ! 523: if( !error ) error = core->run(); ! 524: } ! 525: insert(ERRORKEY, error); ! 526: docycle(); ! 527: } ! 528: ! 529: void Process::cycle() ! 530: { ! 531: trace( "%d.cycle() %d", this ); VOK; ! 532: if( cycles <= 0 ) return; ! 533: --cycles; ! 534: docycle(); ! 535: } ! 536: ! 537: void Process::docycle() ! 538: { ! 539: Behavs b; ! 540: ! 541: trace( "%d.docycle() %d", this ); VOK; ! 542: b = core->behavs(); ! 543: switch( b ){ ! 544: case ACTIVE: ! 545: pad->alarm(1); ! 546: ++cycles; ! 547: break; ! 548: case HALTED: ! 549: case PENDING: ! 550: case BREAKED: ! 551: if (core->online()) _bpts->lift(); ! 552: break; ! 553: default: ! 554: break; ! 555: } ! 556: habeascorpus(b, b!=ERRORED ? changes() : 0); ! 557: } ! 558: ! 559: void Process::habeascorpus(Behavs b, long c) ! 560: { ! 561: char *error; ! 562: Bls *t = &bls[BEHAVSKEY]; ! 563: Frame *f; ! 564: ! 565: trace( "%d.habeascorpus(%d, c)", this, b, c ); VOK; ! 566: t->clear(); ! 567: if( c > 0 ) t->af( "%d %s changed ", c, c==1 ? "spy" : "spies" ); ! 568: t->af( "%s ", BehavsName(b) ); ! 569: switch( b ){ ! 570: case HALTED: break; // shut up cfront ! 571: case BREAKED: { ! 572: class Stmt *stmt = bpts()->bptstmt(core->pc()); ! 573: if( !stmt || stoprequest ) break; ! 574: Expr *e = stmt->condition; ! 575: if( !e || e==Q_BPT ) break; ! 576: delete core->callstack(); // term needs refreshed ! 577: Frame cf = core->frameabove(0); ! 578: cf.addsymbols(); ! 579: stmt->condtext->clear(); ! 580: stmt->condtext->af("[%d] ", ++stmt->hits); ! 581: e->evaltext(&cf, *stmt->condtext); ! 582: Bls j; ! 583: journal()->insert("%s", stmt->journal(j)); ! 584: if( e->val.lng || c>0 ) ! 585: break; ! 586: if( !e->evalerr ){ ! 587: pad->alarm(); ! 588: ++cycles; ! 589: } ! 590: stmt->select(); ! 591: if( e->evalerr ){ ! 592: insert(ERRORKEY, "%s", stmt->condtext->text); ! 593: break; ! 594: } ! 595: error = core->step(); ! 596: if( !error ) _bpts->lay(); ! 597: if( !error ) error = core->run(); ! 598: insert(ERRORKEY, error); ! 599: return; ! 600: } ! 601: case ERRORED: ! 602: t->af( core->problem() ); ! 603: break; ! 604: case PENDING: ! 605: t->af(core->eventname()); ! 606: break; ! 607: case ACTIVE: ! 608: t->af( "%s ", core->resources() ); // fall thru ! 609: case INST_STEPPED: ! 610: case STMT_STEPPED: ! 611: long pc = core->pc(); ! 612: if( pc ){ ! 613: if( *symtab()->symaddr(pc) ) ! 614: t->af( "pc=%s", symtab()->symaddr(pc) ); ! 615: else ! 616: t->af( "pc=%d", pc ); ! 617: } ! 618: break; ! 619: } ! 620: switch( b ){ ! 621: case ACTIVE: ! 622: pad->lines(padlines = ERRORKEY); ! 623: case ERRORED: ! 624: linereq(BEHAVSKEY); ! 625: break; ! 626: case HALTED: ! 627: case BREAKED: ! 628: case INST_STEPPED: ! 629: case STMT_STEPPED: ! 630: case PENDING: ! 631: mergeback(2); ! 632: if( globals ) globals->changes(); ! 633: if( b!=INST_STEPPED && (f = frame(0)) ) ! 634: f->select(b != STMT_STEPPED ? SVP : 0); ! 635: } ! 636: } ! 637: ! 638: int Process::changes() ! 639: { ! 640: int changed = 0; ! 641: Frame *f; ! 642: ! 643: trace( "%d.changes()", this ); OK(0); ! 644: if( callstk ) ! 645: for( long l = 0; l < callstk->size; ++l ) ! 646: if( f = callstk->fpf[l].frame ) ! 647: changed += f->changes(); ! 648: if( globals ) changed += globals->changes(); ! 649: if( memory ) changed += memory->changes(); ! 650: return changed; ! 651: } ! 652: ! 653: char *Process::prefix(char *p) ! 654: { ! 655: trace( "%d.prefix(%s) %s", this, p, _prefix ); OK("Process::prefix"); ! 656: if( *p=='/' && _prefix && strncmp(_prefix, "/n/", 3) ) ! 657: return p; ! 658: if( p && _prefix ) ! 659: return sf( "%s/%s", _prefix, *p=='/' ? p+1 : p ); ! 660: return p; ! 661: } ! 662: ! 663: void Process::slavedriver(Process *sd) ! 664: { ! 665: trace("%d.slavedriver(%d)", this, sd); VOK; ! 666: if( sd == this ){ ! 667: pad->insert(ERRORKEY, "slave must be different process"); ! 668: return; ! 669: } ! 670: pad->insert(ERRORKEY, "slave of %s", sd->procpath); ! 671: sd->pad->insert(ERRORKEY, "master of %s", procpath); ! 672: sd->_slave = this; ! 673: core->slavedriver(sd->core); ! 674: } ! 675: ! 676: Process *Process::slave() ! 677: { ! 678: trace("%d.slave()", this); OK(0); ! 679: return _slave; ! 680: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.