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);
40 print(sym[0], "=", itoa(sym[1], "%ux"));
57 print(stkprefix, "\t", sym[0], "=", itoa(sym[1], "%ux"), "\n");
66 if regexp(head s, file) then
73 // print a stack trace
75 // in a run of leading frames in files matched by regexps in stkignore,
76 // only print the last one.
77 defn _stk(pc, sp, link, dolocals)
79 local stk, ign, last, lastpc;
81 stk = strace(pc, sp, link);
90 if !_stkign(pcfile(pc)) then {
98 print(stkprefix, fmt(frame[0], 'a'), "(");
100 print(")+", itoa(pc-frame[0], "%ux"), " ");
110 print(stkprefix, fmt(pc, 'a'), " ");
118 if file[0] == '/' then {
121 srcfiles = append srcfiles, file;
122 srctext = append srctext, src;
130 src = file(head lst+file);
132 srcfiles = append srcfiles, file;
133 srctext = append srctext, src;
145 src = match(file, srcfiles);
153 print("no source for ", file, "\n");
156 line = pcline(addr)-1;
157 print(file, ":", src[line], "\n");
164 if match(dir, srcpath) >= 0 then {
165 print("already in srcpath\n");
169 srcpath = {dir}+srcpath;
184 print("\t", head l, "\n");
195 if file[0] == '/' && access(file) then {
196 rc("B "+file+":"+itoa(pcline(addr)));
200 name = head lst+file;
201 if access(name) then {
202 rc("B "+name+":"+itoa(pcline(addr)));
207 print("no source for ", file, "\n");
212 local text, cline, line, file, src;
214 src = match(file,srcfiles);
221 return "(no source)";
223 return src[pcline(addr)-1];
228 local src, file, line, cline, text;
231 src = match(file, srcfiles);
239 print("no source for ", file, "\n");
243 cline = pcline(addr)-1;
244 print(file, ":", cline+1, "\n");
251 if line == cline then
255 print(line+1, "\t", text, "\n");
261 defn step() // single step the process
263 local lst, lpl, addr, bput;
266 if match(*PC, bplist) >= 0 then { // Sitting on a breakpoint
267 bput = fmt(*PC, bpfmt);
274 while lpl do { // place break points
275 *(head lpl) = bpinst;
279 startstop(pid); // do the step
281 while lst do { // remove the breakpoints
282 addr = fmt(head lst, bpfmt);
290 defn bpset(addr) // set a breakpoint
292 if status(pid) != "Stopped" then {
293 print("Waiting...\n");
296 if match(addr, bplist) >= 0 then
297 print("breakpoint already set at ", fmt(addr, 'a'), "\n");
299 *fmt(addr, bpfmt) = bpinst;
300 bplist = append bplist, addr;
304 defn bptab() // print a table of breakpoints
311 print("\t", fmt(addr, 'A'), " ", fmt(addr, 'a'), " ", fmt(addr, 'i'), "\n");
316 defn bpdel(addr) // delete a breakpoint
318 local n, pc, nbplist;
320 n = match(addr, bplist);
322 print("no breakpoint at ", fmt(addr, 'a'), "\n");
326 addr = fmt(addr, bpfmt);
329 nbplist = {}; // delete from list
333 nbplist = append nbplist, pc;
334 bplist = tail bplist;
336 bplist = nbplist; // delete from memory
339 defn cont() // continue execution
343 addr = fmt(*PC, bpfmt);
344 if match(addr, bplist) >= 0 then { // Sitting on a breakpoint
349 startstop(pid); // Run
352 defn stopped(pid) // called from acid when a process changes state
354 pstop(pid); // stub so this is easy to replace
357 defn procs() // print status of processes
370 print(fmt(c, 'c'), np, ": ", status(np), " at ", fmt(*PC, 'a'), " setproc(", np, ")\n");
384 bound = fnbound(addr);
386 addr = fmt(addr, 'i');
387 loop 1,_asmlines do {
388 print(fmt(addr, 'a'), " ", fmt(addr, 'A'));
389 print("\t", @addr++, "\n");
390 if bound != {} && addr > bound[1] then {
410 estr = "/sys/lib/acid/window '0 0 600 400' "+textfile;
411 if progargs != "" then
412 estr = estr+" "+progargs;
417 error("win failed to create process");
430 estr = "/sys/lib/acid/transcript '0 0 600 400' '100 100 700 500' "+textfile;
431 if progargs != "" then
432 estr = estr+" "+progargs;
437 error("win failed to create process");
447 // Dont miss the delay slot calls
448 bpset(follow(main)[0]);
453 defn stmnt() // step one statement
460 if line != pcline(*PC) then {
467 defn func() // step until we leave the current function
469 local bound, end, start, pc;
471 bound = fnbound(*PC);
472 if bound == {} then {
473 print("cannot locate text symbol\n");
480 while pc >= start && pc < end do {
491 bound = fnbound(*PC);
494 if pc >= bound[0] && pc < bound[1] then
497 while (pc < bound[0] || pc > bound[1]) && sp >= *SP do {
504 defn dump(addr, n, fmt)
506 // see definition of dump in acid manual: it does n+1 iterations
508 print(fmt(addr, 'A'), ": ");
509 addr = mem(addr, fmt);
519 while fmt[i] != 0 do {
522 while '0' <= fmt[i] && fmt[i] <= '9' do {
523 n = 10*n + fmt[i]-'0';
526 if n <= 0 then n = 1;
527 addr = fmt(addr, fmt[i]);
538 defn symbols(pattern)
545 if regexp(pattern, s[0]) then
546 print(s[0], "\t", s[1], "\t", s[2], "\n");
556 s = origin & 0x7fffffff;
557 e = etext & 0x7fffffff;
561 if c > s && c < e then {
562 print("src(", a, ")\n");
569 print("/sys/lib/acid/port");