1 // portable acid for all architectures
5 print(pcfile(addr), ":", pcline(addr), "\n");
17 print("Note pc:", pc, " sp:", sp, " ", fmt(pc, 'a'), " ");
19 _stk(pc, sp, linkreg(addr), 1);
31 print("Note pc:", pc, " sp:", sp, " ", fmt(pc, 'a'), " ");
33 _stk(pc, sp, linkreg(addr), 1);
36 defn labstk(l) // trace from a label
38 _stk(*(l+4), *l, linkreg(0), 0);
45 print(sym[0], "=", itoa(sym[1], "%ux"));
62 print(stkprefix, "\t", sym[0], "=", itoa(sym[1], "%ux"), "\n");
71 if regexp(head s, file) then
78 // print a stack trace
80 // in a run of leading frames in files matched by regexps in stkignore,
81 // only print the last one.
82 defn _stk(pc, sp, link, dolocals)
84 local stk, ign, last, lastpc;
86 stk = strace(pc, sp, link);
95 if !_stkign(pcfile(pc)) then {
103 print(stkprefix, fmt(frame[0], 'a'), "(");
105 print(")+", itoa(pc-frame[0], "%ux"), " ");
115 print(stkprefix, fmt(pc, 'a'), " ");
123 if file[0] == '/' then {
126 srcfiles = append srcfiles, file;
127 srctext = append srctext, src;
135 src = file(head lst+file);
137 srcfiles = append srcfiles, file;
138 srctext = append srctext, src;
150 src = match(file, srcfiles);
158 print("no source for ", file, "\n");
161 line = pcline(addr)-1;
162 print(file, ":", src[line], "\n");
169 if match(dir, srcpath) >= 0 then {
170 print("already in srcpath\n");
174 srcpath = {dir}+srcpath;
189 print("\t", head l, "\n");
200 if file[0] == '/' && access(file) then {
201 rc("B "+file+":"+itoa(pcline(addr)));
205 name = head lst+file;
206 if access(name) then {
207 rc("B "+name+":"+itoa(pcline(addr)));
212 print("no source for ", file, "\n");
217 local text, cline, line, file, src;
219 src = match(file,srcfiles);
226 return "(no source)";
228 return src[pcline(addr)-1];
233 local src, file, line, cline, text;
236 src = match(file, srcfiles);
244 print("no source for ", file, "\n");
248 cline = pcline(addr)-1;
249 print(file, ":", cline+1, "\n");
256 if line == cline then
260 print(line+1, "\t", text, "\n");
266 defn step() // single step the process
268 local lst, lpl, addr, bput;
271 if match(*PC, bplist) >= 0 then { // Sitting on a breakpoint
272 bput = fmt(*PC, bpfmt);
279 while lpl do { // place break points
280 *(head lpl) = bpinst;
284 startstop(pid); // do the step
286 while lst do { // remove the breakpoints
287 addr = fmt(head lst, bpfmt);
295 defn bpset(addr) // set a breakpoint
297 if status(pid) != "Stopped" then {
298 print("Waiting...\n");
301 if match(addr, bplist) >= 0 then
302 print("breakpoint already set at ", fmt(addr, 'a'), "\n");
304 *fmt(addr, bpfmt) = bpinst;
305 bplist = append bplist, addr;
309 defn bptab() // print a table of breakpoints
316 print("\t", fmt(addr, 'X'), " ", fmt(addr, 'a'), " ", fmt(addr, 'i'), "\n");
321 defn bpdel(addr) // delete a breakpoint
323 local n, pc, nbplist;
325 n = match(addr, bplist);
327 print("no breakpoint at ", fmt(addr, 'a'), "\n");
331 addr = fmt(addr, bpfmt);
334 nbplist = {}; // delete from list
338 nbplist = append nbplist, pc;
339 bplist = tail bplist;
341 bplist = nbplist; // delete from memory
344 defn cont() // continue execution
348 addr = fmt(*PC, bpfmt);
349 if match(addr, bplist) >= 0 then { // Sitting on a breakpoint
354 startstop(pid); // Run
357 defn stopped(pid) // called from acid when a process changes state
359 pstop(pid); // stub so this is easy to replace
362 defn procs() // print status of processes
375 print(fmt(c, 'c'), np, ": ", status(np), " at ", fmt(*PC, 'a'), " setproc(", np, ")\n");
389 bound = fnbound(addr);
391 addr = fmt(addr, 'i');
392 loop 1,_asmlines do {
393 print(fmt(addr, 'a'), " ", fmt(addr, 'X'));
394 print("\t", @addr++, "\n");
395 if bound != {} && addr > bound[1] then {
415 estr = "/sys/lib/acid/window '0 0 600 400' "+textfile;
416 if progargs != "" then
417 estr = estr+" "+progargs;
422 error("win failed to create process");
435 estr = "/sys/lib/acid/transcript '0 0 600 400' '100 100 700 500' "+textfile;
436 if progargs != "" then
437 estr = estr+" "+progargs;
442 error("win failed to create process");
452 // Dont miss the delay slot calls
453 bpset(follow(main)[0]);
458 defn stmnt() // step one statement
465 if line != pcline(*PC) then {
472 defn func() // step until we leave the current function
474 local bound, end, start, pc;
476 bound = fnbound(*PC);
477 if bound == {} then {
478 print("cannot locate text symbol\n");
485 while pc >= start && pc < end do {
496 bound = fnbound(*PC);
499 if pc >= bound[0] && pc < bound[1] then
502 while (pc < bound[0] || pc > bound[1]) && sp >= *SP do {
509 defn dump(addr, n, fmt)
511 // see definition of dump in acid manual: it does n+1 iterations
513 print(fmt(addr, 'X'), ": ");
514 addr = mem(addr, fmt);
524 while fmt[i] != 0 do {
527 while '0' <= fmt[i] && fmt[i] <= '9' do {
528 n = 10*n + fmt[i]-'0';
531 if n <= 0 then n = 1;
532 addr = fmt(addr, fmt[i]);
543 defn symbols(pattern)
550 if regexp(pattern, s[0]) then
551 print(s[0], "\t", s[1], "\t", s[2], "\n");
561 s = origin & 0x7fffffff;
562 e = etext & 0x7fffffff;
566 if c > s && c < e then {
567 print("src(", a, ")\n");
574 print("/sys/lib/acid/port");