1implement Command; 2 3include "sys.m"; 4 sys: Sys; 5 print, fprint, FD: import sys; 6 stderr: ref FD; 7 8include "draw.m"; 9 10include "debug.m"; 11 debug: Debug; 12 Prog, Module, Exp: import debug; 13 14include "arg.m"; 15include "bufio.m"; 16 bufio: Bufio; 17 Iobuf: import bufio; 18 19include "env.m"; 20 env: Env; 21 22include "string.m"; 23 str: String; 24 25include "dis.m"; 26 dism: Dis; 27 28Command: module 29{ 30 init: fn(ctxt: ref Draw->Context, argv: list of string); 31}; 32 33usage() 34{ 35 sys->fprint(stderr, "usage: stack [-v] pid\n"); 36 raise "fail:usage"; 37} 38 39badmodule(p: string) 40{ 41 sys->fprint(stderr, "stack: cannot load %s: %r\n", p); 42 raise "fail:bad module"; 43} 44 45sbldirs: list of (string, string); 46 47init(nil: ref Draw->Context, argv: list of string) 48{ 49 50 sys = load Sys Sys->PATH; 51 stderr = sys->fildes(2); 52 arg := load Arg Arg->PATH; 53 if (arg == nil) 54 badmodule(Arg->PATH); 55 bufio = load Bufio Bufio->PATH; 56 if (bufio == nil) 57 badmodule(Bufio->PATH); 58 debug = load Debug Debug->PATH; 59 if(debug == nil) 60 badmodule(Debug->PATH); 61 env = load Env Env->PATH; 62 if (env != nil) { 63 str = load String String->PATH; 64 if (str == nil) 65 badmodule(String->PATH); 66 } 67 bout := bufio->fopen(sys->fildes(1), Sys->OWRITE); 68 69 arg->init(argv); 70 verbose := 0; 71 while ((opt := arg->opt()) != 0) { 72 case opt { 73 'v' => 74 verbose = 1; 75 'p' => 76 dispath := arg->arg(); 77 sblpath := arg->arg(); 78 if (dispath == nil || sblpath == nil) 79 usage(); 80 sbldirs = (addslash(dispath), addslash(sblpath)) :: sbldirs; 81 * => 82 usage(); 83 } 84 } 85 if (env != nil && (pathl := env->getenv("sblpath")) != nil) { 86 toks := str->unquoted(pathl); 87 for (; toks != nil && tl toks != nil; toks = tl tl toks) 88 sbldirs = (addslash(hd toks), addslash(hd tl toks)) :: sbldirs; 89 } 90 t: list of (string, string); 91 for (; sbldirs != nil; sbldirs = tl sbldirs) 92 t = hd sbldirs :: t; 93 sbldirs = t; 94 95 argv = arg->argv(); 96 if(argv == nil) 97 usage(); 98 99 debug->init(); 100 101 (p, err) := debug->prog(int hd argv); 102 if(err != nil){ 103 fprint(stderr, "stack: %s\n", err); 104 return; 105 } 106 stk: array of ref Exp; 107 (stk, err) = p.stack(); 108 109 if(err != nil){ 110 fprint(stderr, "stack: %s\n", err); 111 return; 112 } 113 114 for(i := 0; i < len stk; i++){ 115 stdsym(stk[i].m); 116 stk[i].m.stdsym(); 117 stk[i].findsym(); 118 bout.puts(stk[i].name + "("); 119 vs := stk[i].expand(); 120 if(verbose && vs != nil){ 121 for(j := 0; j < len vs; j++){ 122 if(vs[j].name == "args"){ 123 d := vs[j].expand(); 124 s := ""; 125 for(j = 0; j < len d; j++) { 126 bout.puts(sys->sprint("%s%s=%s", s, d[j].name, d[j].val().t0)); 127 s = ", "; 128 } 129 break; 130 } 131 } 132 } 133 bout.puts(sys->sprint(") %s\n", stk[i].srcstr())); 134 if(verbose && vs != nil){ 135 for(j := 0; j < len vs; j++){ 136 if(vs[j].name == "locals"){ 137 d := vs[j].expand(); 138 for(j = 0; j < len d; j++) 139 bout.puts("\t" + d[j].name + "=" + d[j].val().t0 + "\n"); 140 break; 141 } 142 } 143 } 144 } 145 bout.flush(); 146} 147 148stdsym(m: ref Module) 149{ 150 dis := m.dis(); 151 if(dism == nil){ 152 dism = load Dis Dis->PATH; 153 if(dism != nil) 154 dism->init(); 155 } 156 if(dism != nil && (sp := dism->src(dis)) != nil){ 157 sp = sp[0: len sp - 1] + "sbl"; 158 (sym, nil) := debug->sym(sp); 159 if (sym != nil) { 160 m.addsym(sym); 161 return; 162 } 163 } 164 for (sbl := sbldirs; sbl != nil; sbl = tl sbl) { 165 (dispath, sblpath) := hd sbl; 166 if (len dis > len dispath && dis[0:len dispath] == dispath) { 167 sblpath = sblpath + dis[len dispath:]; 168 if (len sblpath > 4 && sblpath[len sblpath - 4:] == ".dis") 169 sblpath = sblpath[0:len sblpath - 4] + ".sbl"; 170 (sym, nil) := debug->sym(sblpath); 171 if (sym != nil) { 172 m.addsym(sym); 173 return; 174 } 175 } 176 } 177} 178 179addslash(p: string): string 180{ 181 if (p != nil && p[len p - 1] != '/') 182 p[len p] = '/'; 183 return p; 184} 185