123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574 |
- // portable acid for all architectures
- defn pfl(addr)
- {
- print(pcfile(addr), ":", pcline(addr), "\n");
- }
- defn
- notestk(addr)
- {
- local pc, sp;
- complex Ureg addr;
- pc = addr.pc\X;
- sp = addr.sp\X;
- print("Note pc:", pc, " sp:", sp, " ", fmt(pc, 'a'), " ");
- pfl(pc);
- _stk(pc, sp, linkreg(addr), 1);
- }
- defn
- notelstk(addr)
- {
- local pc, sp;
- complex Ureg addr;
- pc = addr.pc\X;
- sp = addr.sp\X;
- print("Note pc:", pc, " sp:", sp, " ", fmt(pc, 'a'), " ");
- pfl(pc);
- _stk(pc, sp, linkreg(addr), 1);
- }
- defn labstk(l) // trace from a label
- {
- _stk(*(l+4), *l, linkreg(0), 0);
- }
- defn params(param)
- {
- while param do {
- sym = head param;
- print(sym[0], "=", itoa(sym[1], "%ux"));
- param = tail param;
- if param then
- print (",");
- }
- }
- stkprefix = "";
- stkignore = {};
- stkend = 0;
- defn locals(l)
- {
- local sym;
- while l do {
- sym = head l;
- print(stkprefix, "\t", sym[0], "=", itoa(sym[1], "%ux"), "\n");
- l = tail l;
- }
- }
- defn _stkign(file)
- {
- s = stkignore;
- while s do {
- if regexp(head s, file) then
- return 1;
- s = tail s;
- }
- return 0;
- }
- // print a stack trace
- //
- // in a run of leading frames in files matched by regexps in stkignore,
- // only print the last one.
- defn _stk(pc, sp, link, dolocals)
- {
- local stk, ign, last, lastpc;
- stk = strace(pc, sp, link);
- if stkignore then
- ign = 1;
- else
- ign = 0;
- last = stk;
- lastpc = pc;
- while stk do {
- if ign then {
- if !_stkign(pcfile(pc)) then {
- ign = 0;
- stk = last;
- pc = lastpc;
- }
- }
- frame = head stk;
- if !ign then {
- print(stkprefix, fmt(frame[0], 'a'), "(");
- params(frame[2]);
- print(")+", itoa(pc-frame[0], "%ux"), " ");
- pfl(pc);
- if dolocals then
- locals(frame[3]);
- }
- last = stk;
- lastpc = pc;
- stk = tail stk;
- pc = frame[1];
- }
- print(stkprefix, fmt(pc, 'a'), " ");
- pfl(pc);
- }
- defn findsrc(file)
- {
- local lst, src;
- if file[0] == '/' then {
- src = file(file);
- if src != {} then {
- srcfiles = append srcfiles, file;
- srctext = append srctext, src;
- return src;
- }
- return {};
- }
- lst = srcpath;
- while head lst do {
- src = file(head lst+file);
- if src != {} then {
- srcfiles = append srcfiles, file;
- srctext = append srctext, src;
- return src;
- }
- lst = tail lst;
- }
- }
- defn line(addr)
- {
- local src, file;
- file = pcfile(addr);
- src = match(file, srcfiles);
- if src >= 0 then
- src = srctext[src];
- else
- src = findsrc(file);
- if src == {} then {
- print("no source for ", file, "\n");
- return {};
- }
- line = pcline(addr)-1;
- print(file, ":", src[line], "\n");
- }
- defn addsrcdir(dir)
- {
- dir = dir+"/";
- if match(dir, srcpath) >= 0 then {
- print("already in srcpath\n");
- return {};
- }
- srcpath = {dir}+srcpath;
- }
- defn source()
- {
- local l;
- l = srcpath;
- while l do {
- print(head l, "\n");
- l = tail l;
- }
- l = srcfiles;
- while l do {
- print("\t", head l, "\n");
- l = tail l;
- }
- }
- defn Bsrc(addr)
- {
- local lst;
- lst = srcpath;
- file = pcfile(addr);
- if file[0] == '/' && access(file) then {
- rc("B "+file+":"+itoa(pcline(addr)));
- return {};
- }
- while head lst do {
- name = head lst+file;
- if access(name) then {
- rc("B "+name+":"+itoa(pcline(addr)));
- return {};
- }
- lst = tail lst;
- }
- print("no source for ", file, "\n");
- }
- defn srcline(addr)
- {
- local text, cline, line, file, src;
- file = pcfile(addr);
- src = match(file,srcfiles);
- if (src>=0) then
- src = srctext[src];
- else
- src = findsrc(file);
- if (src=={}) then
- {
- return "(no source)";
- }
- return src[pcline(addr)-1];
- }
- defn src(addr)
- {
- local src, file, line, cline, text;
- file = pcfile(addr);
- src = match(file, srcfiles);
- if src >= 0 then
- src = srctext[src];
- else
- src = findsrc(file);
- if src == {} then {
- print("no source for ", file, "\n");
- return {};
- }
- cline = pcline(addr)-1;
- print(file, ":", cline+1, "\n");
- line = cline-5;
- loop 0,10 do {
- if line >= 0 then {
- text = src[line];
- if text == {} then
- return {};
- if line == cline then
- print(">");
- else
- print(" ");
- print(line+1, "\t", text, "\n");
- }
- line = line+1;
- }
- }
- defn step() // single step the process
- {
- local lst, lpl, addr, bput;
- bput = 0;
- if match(*PC, bplist) >= 0 then { // Sitting on a breakpoint
- bput = fmt(*PC, bpfmt);
- *bput = @bput;
- }
- lst = follow(*PC);
- lpl = lst;
- while lpl do { // place break points
- *(head lpl) = bpinst;
- lpl = tail lpl;
- }
- startstop(pid); // do the step
- while lst do { // remove the breakpoints
- addr = fmt(head lst, bpfmt);
- *addr = @addr;
- lst = tail lst;
- }
- if bput != 0 then
- *bput = bpinst;
- }
- defn bpset(addr) // set a breakpoint
- {
- if status(pid) != "Stopped" then {
- print("Waiting...\n");
- stop(pid);
- }
- if match(addr, bplist) >= 0 then
- print("breakpoint already set at ", fmt(addr, 'a'), "\n");
- else {
- *fmt(addr, bpfmt) = bpinst;
- bplist = append bplist, addr;
- }
- }
- defn bptab() // print a table of breakpoints
- {
- local lst, addr;
- lst = bplist;
- while lst do {
- addr = head lst;
- print("\t", fmt(addr, 'X'), " ", fmt(addr, 'a'), " ", fmt(addr, 'i'), "\n");
- lst = tail lst;
- }
- }
- defn bpdel(addr) // delete a breakpoint
- {
- local n, pc, nbplist;
- n = match(addr, bplist);
- if n < 0 then {
- print("no breakpoint at ", fmt(addr, 'a'), "\n");
- return {};
- }
- addr = fmt(addr, bpfmt);
- *addr = @addr;
- nbplist = {}; // delete from list
- while bplist do {
- pc = head bplist;
- if pc != addr then
- nbplist = append nbplist, pc;
- bplist = tail bplist;
- }
- bplist = nbplist; // delete from memory
- }
- defn cont() // continue execution
- {
- local addr;
- addr = fmt(*PC, bpfmt);
- if match(addr, bplist) >= 0 then { // Sitting on a breakpoint
- *addr = @addr;
- step(); // Step over
- *addr = bpinst;
- }
- startstop(pid); // Run
- }
- defn stopped(pid) // called from acid when a process changes state
- {
- pstop(pid); // stub so this is easy to replace
- }
- defn procs() // print status of processes
- {
- local c, lst, cpid;
- cpid = pid;
- lst = proclist;
- while lst do {
- np = head lst;
- setproc(np);
- if np == cpid then
- c = '>';
- else
- c = ' ';
- print(fmt(c, 'c'), np, ": ", status(np), " at ", fmt(*PC, 'a'), " setproc(", np, ")\n");
- lst = tail lst;
- }
- pid = cpid;
- if pid != 0 then
- setproc(pid);
- }
- _asmlines = 30;
- defn asm(addr)
- {
- local bound;
- bound = fnbound(addr);
- addr = fmt(addr, 'i');
- loop 1,_asmlines do {
- print(fmt(addr, 'a'), " ", fmt(addr, 'X'));
- print("\t", @addr++, "\n");
- if bound != {} && addr > bound[1] then {
- lasmaddr = addr;
- return {};
- }
- }
- lasmaddr = addr;
- }
- defn casm()
- {
- asm(lasmaddr);
- }
- defn win()
- {
- local npid, estr;
- bplist = {};
- notes = {};
- estr = "/sys/lib/acid/window '0 0 600 400' "+textfile;
- if progargs != "" then
- estr = estr+" "+progargs;
- npid = rc(estr);
- npid = atoi(npid);
- if npid == 0 then
- error("win failed to create process");
- setproc(npid);
- stopped(npid);
- }
- defn win2()
- {
- local npid, estr;
- bplist = {};
- notes = {};
- estr = "/sys/lib/acid/transcript '0 0 600 400' '100 100 700 500' "+textfile;
- if progargs != "" then
- estr = estr+" "+progargs;
- npid = rc(estr);
- npid = atoi(npid);
- if npid == 0 then
- error("win failed to create process");
- setproc(npid);
- stopped(npid);
- }
- defn new()
- {
- bplist = {};
- newproc(progargs);
- // Dont miss the delay slot calls
- bpset(follow(main)[0]);
- cont();
- bpdel(*PC);
- }
- defn stmnt() // step one statement
- {
- local line;
- line = pcline(*PC);
- while 1 do {
- step();
- if line != pcline(*PC) then {
- src(*PC);
- return {};
- }
- }
- }
- defn func() // step until we leave the current function
- {
- local bound, end, start, pc;
- bound = fnbound(*PC);
- if bound == {} then {
- print("cannot locate text symbol\n");
- return {};
- }
- pc = *PC;
- start = bound[0];
- end = bound[1];
- while pc >= start && pc < end do {
- step();
- pc = *PC;
- }
- }
- defn next()
- {
- local sp, bound;
- sp = *SP;
- bound = fnbound(*PC);
- stmnt();
- pc = *PC;
- if pc >= bound[0] && pc < bound[1] then
- return {};
- while (pc < bound[0] || pc > bound[1]) && sp >= *SP do {
- step();
- pc = *PC;
- }
- src(*PC);
- }
- defn dump(addr, n, fmt)
- {
- // see definition of dump in acid manual: it does n+1 iterations
- loop 0, n do {
- print(fmt(addr, 'X'), ": ");
- addr = mem(addr, fmt);
- }
- }
- defn mem(addr, fmt)
- {
- local i, c, n;
- i = 0;
- while fmt[i] != 0 do {
- c = fmt[i];
- n = 0;
- while '0' <= fmt[i] && fmt[i] <= '9' do {
- n = 10*n + fmt[i]-'0';
- i = i+1;
- }
- if n <= 0 then n = 1;
- addr = fmt(addr, fmt[i]);
- while n > 0 do {
- print(*addr++, " ");
- n = n-1;
- }
- i = i+1;
- }
- print("\n");
- return addr;
- }
- defn symbols(pattern)
- {
- local l, s;
- l = symbols;
- while l do {
- s = head l;
- if regexp(pattern, s[0]) then
- print(s[0], "\t", s[1], "\t", s[2], "\n");
- l = tail l;
- }
- }
- defn spsrch(len)
- {
- local addr, a, s, e;
- addr = *SP;
- s = origin & 0x7fffffff;
- e = etext & 0x7fffffff;
- loop 1, len do {
- a = *addr++;
- c = a & 0x7fffffff;
- if c > s && c < e then {
- print("src(", a, ")\n");
- pfl(a);
- }
- }
- }
- progargs="";
- print("/sys/lib/acid/port");
|