|
|
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.