blob: a2fd46c5e933e3d54a4fa4e098a2f53ab0967455 [file] [log] [blame]
rscd89ce512005-02-11 02:14:59 +00001//
2// pthread-specific access functions
3// avoid complicated libthread_db interface
4//
rsc0a61c072004-04-19 18:18:37 +00005
rsc2a931b72005-02-11 16:51:43 +00006include("pthread-"+systype+"-"+objtype);
rscd89ce512005-02-11 02:14:59 +00007
8// pick apart system mcontext_t structures
9defn mcontext(m)
rsc0a61c072004-04-19 18:18:37 +000010{
rscd89ce512005-02-11 02:14:59 +000011 complex mcontext_t m;
12
13 if systype == "linux" then {
14 m = m\X;
15 return {"PC", m[14], "SP", m[7], "BP", m[6]};
16 } else if systype == "freebsd" then {
17 return {"PC", m.mc_eip, "SP", m.mc_esp, "BP", m.mc_ebp};
18 } else
19 error("do not know how to read mcontext_t on system "+systype);
20}
21
22//
23// plan 9 thread library support
24//
25defn context(c)
26{
27 c = (Context)c;
28 return mcontext(c.uc.uc_mcontext);
29}
30
31defn contextstk(c)
32{
33 _stk(context(c), 0);
34}
35
36defn contextlstk(c)
37{
38 _stk(context(c), 1);
rsc0a61c072004-04-19 18:18:37 +000039}
40
41defn altfmt(A){
42 local i, s, yes;
43 complex Alt A;
44
45 s = "alt(";
rsc2a931b72005-02-11 16:51:43 +000046 s = s + "tag(*" + itoa(A.tag, "%#x") + "=" + itoa(*A.tag, "%#x") + ") ";
rsc0a61c072004-04-19 18:18:37 +000047 i = 0;
48 yes = 0;
49 while A.op != CHANEND && A.op != CHANNOBLK do{
50 if A.op != CHANNOP then{
51 if yes then s = s + " ";
52 s = s + itoa(i, "%d");
53 s = s + ":";
54 if A.op == CHANSND then s = s + "send";
55 if A.op == CHANRCV then s = s + "recv";
56 s = s + "(channel(";
rsc2a931b72005-02-11 16:51:43 +000057 s = s + itoa(A.c, "%#x");
rsc0a61c072004-04-19 18:18:37 +000058 s = s + "))";
59 yes = 1;
60 }
61 i = i + 1;
62 A = (Alt)(A + sizeofAlt);
63 }
64 if A.op==CHANNOBLK then{
65 if yes then s = s + " ";
66 s = s + "noblock";
67 }
68 s = s + ")";
69 return s;
70}
71
72defn alt(A){
73 print(altfmt(A), "\n");
74}
75
rscd89ce512005-02-11 02:14:59 +000076defn channel(C) {
77 complex Channel C;
78 local i, p;
79
80 print("channel ", C\X, " // ", *(C.name\s));
81 if C.freed then {
82 print(" (moribund)");
83 }
84 print("\n");
85 print("\telemsize=", C.elemsize\D, " bufsize=", C.bufsize, "\n");
86 if C.bufsize then {
87 print("\t", C.nbuf\D, " values in channel:\n");
88 print("\t");
89 p = C.buf+C.off*C.elemsize;
90 loop 1,C.nbuf do {
91 if C.elemsize==4 then {
92 print(*p\X, " ");
93 }else {
94 print("data(", p\X, ") ");
95 }
96 p = p+C.elemsize;
97 if p == C.buf+C.bufsize*C.elemsize then {
98 p = C.buf;
99 }
100 }
101 }
102 print("\n");
103 print(" senders:\n");
104 _altarray(C.asend);
105 print(" recvers:\n");
106 _altarray(C.arecv);
107}
108
109defn _altarray(aa)
110{
111 local i, a, t;
112
113 i = 0;
114 aa = (_Altarray)aa;
115 while i < aa.n do {
116 a = (Alt)aa.a[i];
117 print("\t"+threadstkline(a.thread)+"\n");
118 i++;
119 }
120}
121
rsc0a61c072004-04-19 18:18:37 +0000122defn fnname(a){
123 local sym, s;
124
125 s = symbols;
126 while s do {
127 sym = head s;
128 if sym[2] == a then
129 return sym[0];
130 s = tail s;
131 }
rsc2a931b72005-02-11 16:51:43 +0000132 return itoa(a, "%#x");
rsc0a61c072004-04-19 18:18:37 +0000133}
134
135stkignorelist = {};
rsc0a61c072004-04-19 18:18:37 +0000136defn stkignore(s){
137 append stkignorelist, s;
138}
139
140defn threadstkline(T){
rscc9896e22004-05-23 00:58:00 +0000141 local stk, frame, pc, pc0, file, s, sym, i, stop, P, mainpid;
rsc0a61c072004-04-19 18:18:37 +0000142
rscd89ce512005-02-11 02:14:59 +0000143 T = (_Thread)T;
144 P = (Proc)T.proc;
145 if P.thread == T then {
rscc9896e22004-05-23 00:58:00 +0000146 mainpid = pid;
rsc2a931b72005-02-11 16:51:43 +0000147 setproc(pthread2tid(P.osprocid));
rsc7284df12004-04-19 18:52:34 +0000148 stk = strace({});
rscd89ce512005-02-11 02:14:59 +0000149 setproc(mainpid);
rscc9896e22004-05-23 00:58:00 +0000150 } else
rscd89ce512005-02-11 02:14:59 +0000151 stk = strace(context(T.context));
rsc7284df12004-04-19 18:52:34 +0000152
rsc0a61c072004-04-19 18:18:37 +0000153 stop = 0;
154 while stk && !stop do {
rsc7284df12004-04-19 18:52:34 +0000155 frame = head stk;
156 stk = tail stk;
157 pc = frame[2];
158 pc0 = frame[0];
rsc0a61c072004-04-19 18:18:37 +0000159 file = pcfile(pc);
rsc2e965b32004-05-05 04:22:16 +0000160 if !regexp("plan9/src/lib9/", file)
rsc7284df12004-04-19 18:52:34 +0000161 && !regexp("plan9/src/libthread/", file)
rscd89ce512005-02-11 02:14:59 +0000162 && file != "?file?"
rsc0a61c072004-04-19 18:18:37 +0000163 && match(file, stkignore)==-1 then
164 stop = 1;
rsc0a61c072004-04-19 18:18:37 +0000165 }
166 file = pcfile(pc);
167 s = file+":"+itoa(pcline(pc), "%d");
168 if pc0 != 0 then
169 s = s + " "+fnname(pc0);
170 return s;
171}
172
173defn threadfmt(T){
rscd89ce512005-02-11 02:14:59 +0000174 complex _Thread T;
175 local P, s, name;
rsc0a61c072004-04-19 18:18:37 +0000176
177 P = (Proc)T.proc;
rsc2a931b72005-02-11 16:51:43 +0000178 s = "t=(_Thread)"+itoa(T, "%#-10x")+" // ";
rsc0a61c072004-04-19 18:18:37 +0000179
rscd89ce512005-02-11 02:14:59 +0000180 if P.thread == T then
rsc0a61c072004-04-19 18:18:37 +0000181 s = s + "Running ";
rsc0a61c072004-04-19 18:18:37 +0000182 else
rscd89ce512005-02-11 02:14:59 +0000183 s = s + "Sleeping ";
184 s = s + threadstkline(T);
rsc0a61c072004-04-19 18:18:37 +0000185
rscd89ce512005-02-11 02:14:59 +0000186 name = T+392; // T+offsetof(_Thread, name);
187 if *(name\b) != 0 then
188 s = s + " ["+*(name\s)+"]";
rsc0a61c072004-04-19 18:18:37 +0000189 return s;
190}
191
192defn thread(T){
193 print(threadfmt(T), "\n");
194}
195
rscd89ce512005-02-11 02:14:59 +0000196defn procthreads(P){
rsc0a61c072004-04-19 18:18:37 +0000197 complex Proc P;
rscd89ce512005-02-11 02:14:59 +0000198 local T;
rsc0a61c072004-04-19 18:18:37 +0000199
rscd89ce512005-02-11 02:14:59 +0000200 T = (_Thread)P.allthreads.$head;
rsc0a61c072004-04-19 18:18:37 +0000201 while T != 0 do{
202 print("\t");
203 thread(T);
rscd89ce512005-02-11 02:14:59 +0000204 T = (_Thread)T.allnext;
rsc0a61c072004-04-19 18:18:37 +0000205 }
rsc0a61c072004-04-19 18:18:37 +0000206}
207
rscd89ce512005-02-11 02:14:59 +0000208defn prociter(x) {
rsc0a61c072004-04-19 18:18:37 +0000209 local P;
rscc73e7cf2004-04-20 05:05:38 +0000210
rscd89ce512005-02-11 02:14:59 +0000211 P = (Proc)*_threadprocs;
rsc0a61c072004-04-19 18:18:37 +0000212 while P != 0 do{
rscd89ce512005-02-11 02:14:59 +0000213 if P != (Proc)*_threadprocs then print("\n");
rsc0a61c072004-04-19 18:18:37 +0000214 proc(P);
rscd89ce512005-02-11 02:14:59 +0000215 if x == 1 then
216 procthreads(P);
217 if x == 2 then
218 threadstks(P);
rsc7284df12004-04-19 18:52:34 +0000219 P = (Proc)P.next;
rsc0a61c072004-04-19 18:18:37 +0000220 }
rsc0a61c072004-04-19 18:18:37 +0000221}
222
rscd89ce512005-02-11 02:14:59 +0000223defn procs() {
224 prociter(0);
rsc0a61c072004-04-19 18:18:37 +0000225}
226
rscd89ce512005-02-11 02:14:59 +0000227defn threads() {
228 prociter(1);
229}
230
231defn stacks() {
232 prociter(2);
rsc0a61c072004-04-19 18:18:37 +0000233}
234
rscc73e7cf2004-04-20 05:05:38 +0000235threadstkignore = {
236 "plan9/src/libthread/",
rsc2e965b32004-05-05 04:22:16 +0000237 "plan9/src/lib9/",
238 "plan9/src/lib9/(fmt|utf)/",
rscc73e7cf2004-04-20 05:05:38 +0000239};
rsc0a61c072004-04-19 18:18:37 +0000240defn threadstks(P){
241 complex Proc P;
rscd89ce512005-02-11 02:14:59 +0000242 local T, mainpid, pref, ign;
rsc0a61c072004-04-19 18:18:37 +0000243
rsc0a61c072004-04-19 18:18:37 +0000244 pref = stkprefix;
245 stkprefix = pref+"\t\t";
246 ign = stkignore;
rscc73e7cf2004-04-20 05:05:38 +0000247 stkignore = threadstkignore;
rscd89ce512005-02-11 02:14:59 +0000248 T = (_Thread)P.allthreads.$head;
rsc0a61c072004-04-19 18:18:37 +0000249 while T != 0 do{
rsc0a61c072004-04-19 18:18:37 +0000250 print("\t");
251 thread(T);
252 threadstk(T);
rscd89ce512005-02-11 02:14:59 +0000253 T = (_Thread)T.allnext;
rsc0a61c072004-04-19 18:18:37 +0000254 print("\n");
255 }
rsc0a61c072004-04-19 18:18:37 +0000256 stkprefix = pref;
257 stkignore = ign;
258}
259
260defn proc(P){
261 complex Proc P;
262
rsc2a931b72005-02-11 16:51:43 +0000263 print("p=(Proc)", itoa(P, "%#-10x"), " // pthread ", P.osprocid\X, " pid ", pthread2tid(P.osprocid)\D, " ");
rsc0a61c072004-04-19 18:18:37 +0000264 if P.thread==0 then
265 print(" Sched");
266 else
267 print(" Running");
268 print("\n");
269}
270
rsc0a61c072004-04-19 18:18:37 +0000271defn threadlstk(T){
rscd89ce512005-02-11 02:14:59 +0000272 complex _Thread T;
rsc0a61c072004-04-19 18:18:37 +0000273 local P, mainpid;
274
275 P = (Proc)T.proc;
276 mainpid = pid;
rsc2a931b72005-02-11 16:51:43 +0000277 setproc(pthread2tid(P.osprocid));
rsc0a61c072004-04-19 18:18:37 +0000278
rscd89ce512005-02-11 02:14:59 +0000279 if P.thread == T then
280 lstk();
281 else
282 contextlstk(T.context);
283 setproc(mainpid);
284}
285
286defn threadstk(T){
287 complex _Thread T;
288 local P, mainpid;
289
290 P = (Proc)T.proc;
291 mainpid = pid;
rsc2a931b72005-02-11 16:51:43 +0000292 setproc(pthread2tid(P.osprocid));
rscd89ce512005-02-11 02:14:59 +0000293
294 if P.thread == T then
rsc0a61c072004-04-19 18:18:37 +0000295 stk();
rscd89ce512005-02-11 02:14:59 +0000296 else
297 contextstk(T.context);
rsc0a61c072004-04-19 18:18:37 +0000298
rscd89ce512005-02-11 02:14:59 +0000299 setproc(mainpid);
rscc73e7cf2004-04-20 05:05:38 +0000300}
301
rsc0a61c072004-04-19 18:18:37 +0000302print(acidfile);