1 /*************************************************************************
2 * *
3 * YAP Prolog @(#)amidefs.h 1.3 3/15/90
4 * *
5 * Yap Prolog was developed at NCCUP - Universidade do Porto *
6 * *
7 * Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
8 * *
9 **************************************************************************
10 * *
11 * File: tracer.h *
12 * Last rev: *
13 * mods: *
14 * comments: definitions for low level tracer *
15 * *
16 *************************************************************************/
17
18 #include "Yap.h"
19
20 #ifdef LOW_LEVEL_TRACER
21
22 #include "Yatom.h"
23 #include "YapHeap.h"
24 #include "attvar.h"
25 #include "yapio.h"
26 #include "tracer.h"
27
28 STATIC_PROTO(int TracePutchar, (int, int));
29 STATIC_PROTO(void send_tracer_message, (char *, char *, Int, char *, CELL *));
30
31 static int do_trace_primitives = TRUE;
32
33 static int
TracePutchar(int sno,int ch)34 TracePutchar(int sno, int ch)
35 {
36 return(putc(ch, Yap_stderr)); /* use standard error stream, which is supposed to be 2*/
37 }
38
39 static void
send_tracer_message(char * start,char * name,Int arity,char * mname,CELL * args)40 send_tracer_message(char *start, char *name, Int arity, char *mname, CELL *args)
41 {
42 UInt omax_depth, omax_list, omax_write_args;
43
44 if (name == NULL) {
45 #ifdef YAPOR
46 fprintf(Yap_stderr, "(%d)%s", worker_id, start);
47 #else
48 fprintf(Yap_stderr, "%s", start);
49 #endif
50 } else {
51 int i;
52
53 if (arity) {
54 if (args)
55 fprintf(Yap_stderr, "%s %s:%s(", start, mname, name);
56 else
57 fprintf(Yap_stderr, "%s %s:%s/%lu", start, mname, name, (unsigned long int)arity);
58 } else {
59 fprintf(Yap_stderr, "%s %s:%s", start, mname, name);
60 }
61 if (args) {
62 for (i= 0; i < arity; i++) {
63 if (i > 0) fprintf(Yap_stderr, ",");
64 #if DEBUG
65 #if COROUTINING
66 Yap_Portray_delays = TRUE;
67 #endif
68 #endif
69 omax_depth = max_depth;
70 omax_list = max_list;
71 omax_write_args = max_write_args;
72 max_depth = 5;
73 max_list = 5;
74 max_write_args = 10;
75 Yap_plwrite(args[i], TracePutchar, Handle_vars_f, 1200);
76 max_depth = omax_depth;
77 max_list = omax_list;
78 max_write_args = omax_write_args;
79 #if DEBUG
80 #if COROUTINING
81 Yap_Portray_delays = FALSE;
82 #endif
83 #endif
84 }
85 if (arity) {
86 fprintf(Yap_stderr, ")");
87 }
88 }
89 }
90 fprintf(Yap_stderr, "\n");
91 }
92
93 #if defined(__GNUC__)
94 unsigned long long vsc_count;
95 #else
96 unsigned long vsc_count;
97 #endif
98
99 #if THREADS
100 static int thread_trace;
101 #endif
102
103 /*
104 static int
105 check_trail_consistency(void) {
106 tr_fr_ptr ptr = TR;
107 while (ptr > (CELL *)Yap_TrailBase) {
108 ptr = --ptr;
109 if (!IsVarTerm(TrailTerm(ptr))) {
110 if (IsApplTerm(TrailTerm(ptr))) {
111 CELL *cptr = (CELL *)ptr;
112 ptr = (tr_fr_ptr)(cptr-1);
113 } else {
114 if (IsPairTerm(TrailTerm(ptr))) {
115 CELL *p = RepPair(TrailTerm(ptr));
116 if IsAttVar(p) continue;
117 }
118 printf("Oops at call %ld, B->cp(%p) TR(%p) pt(%p)\n", vsc_count,B->cp_tr, TR, ptr);
119 return(FALSE);
120 }
121 }
122 }
123 return(TRUE);
124 }
125 */
126
127
128 CELL old_value = 0L, old_value2 = 0L;
129
130 void jmp_deb(int);
131
132 void
jmp_deb(int i)133 jmp_deb(int i) {if (i) printf("Here we go\n"); else jmp_deb(0);}
134
135 struct various_codes *sc;
136
137 /*
138 CELL array[332];
139
140 int found = FALSE;
141
142 static void
143 check_area(void)
144 {
145 int i, first = -1;
146 for (i= 0; i < 332; i++) {
147 if (array[i] !=((CELL *)0x187a800)[i]) {
148 if (first != -1) {
149 first = i;
150 found = TRUE;
151 }
152 fprintf(stderr,"%lld changed %d\n",vsc_count,i);
153 }
154 array[i] = ((CELL *)0x187a800)[i];
155 }
156 if (first != -1)
157 jmp_deb(i);
158 }
159 */
160
161 PredEntry *old_p[10000];
162 Term old_x1[10000], old_x2[10000], old_x3[10000];
163
164 void
low_level_trace(yap_low_level_port port,PredEntry * pred,CELL * args)165 low_level_trace(yap_low_level_port port, PredEntry *pred, CELL *args)
166 {
167 char *s;
168 char *mname;
169 Int arity;
170 /* extern int gc_calls; */
171
172 LOCK(Yap_heap_regs->low_level_trace_lock);
173 sc = Yap_heap_regs;
174 vsc_count++;
175 if (vsc_count==29)
176 jmp_deb(1);
177 #ifdef THREADS
178 MY_ThreadHandle.thread_inst_count++;
179 #endif
180 #ifdef COMMENTED
181 //*(H0+(0xb65f2850-0xb64b2008)/sizeof(CELL))==0xc ||
182 //0x4fd4d
183 if (vsc_count == 40650191LL)
184 jmp_deb(1);
185 return;
186 if (vsc_count > 1388060LL && vsc_count < 1388070LL) {
187 if (vsc_count==1388061LL)
188 jmp_deb(1);
189 if (vsc_count % 1LL == 0) {
190 UInt sz = Yap_regp->H0_[17];
191 UInt end = sizeof(MP_INT)/sizeof(CELL)+sz+1;
192 fprintf(stderr,"VAL %lld %d %x/%x\n",vsc_count,sz,H0[16],H0[16+end]);
193 }
194 } else
195 return;
196 if (worker_id != 04 || worker_id != 03) return;
197 // if (vsc_count == 218280)
198 // vsc_xstop = 1;
199 if (vsc_count < 1468068888) {
200 UNLOCK(Yap_heap_regs->low_level_trace_lock);
201 return;
202 }
203 if (port != enter_pred ||
204 !pred ||
205 pred->ArityOfPE != 4 ||
206 strcmp(RepAtom(NameOfFunctor(pred->FunctorOfPred))->StrOfAE,"in_between_target_phrases")) {
207 UNLOCK(Yap_heap_regs->low_level_trace_lock);
208 return;
209 }
210 if (vsc_count < 1246949400LL) {
211 UNLOCK(Yap_heap_regs->low_level_trace_lock);
212 return;
213 }
214 if (vsc_count == 1246949493LL)
215 vsc_xstop = TRUE;
216 if (vsc_count < 5646100000LL) {
217 UNLOCK(Yap_heap_regs->low_level_trace_lock);
218 return;
219 }
220 if (vsc_count == 5646100441LL)
221 vsc_xstop = TRUE;
222 if (vsc_count < 2923351500LL) {
223 UNLOCK(Yap_heap_regs->low_level_trace_lock);
224 return;
225 }
226 if (vsc_count == 123536441LL) vsc_xstop = 1;
227 if (vsc_count < 5530257LL) {
228 UNLOCK(Yap_heap_regs->low_level_trace_lock);
229 return;
230 }
231 if (vsc_count == 9414280LL) {
232 vsc_xstop = TRUE;
233 }
234 if (vsc_count < 3399741LL) {
235 UNLOCK(Yap_heap_regs->low_level_trace_lock);
236 return;
237 }
238 if (vsc_count == 51021) {
239 printf("Here I go\n");
240 }
241 if (vsc_count < 52000) {
242 UNLOCK(Yap_heap_regs->low_level_trace_lock);
243 return;
244 }
245 if (vsc_count > 52000) exit(0);
246 UNLOCK(Yap_heap_regs->low_level_trace_lock);
247 return;
248 if (vsc_count == 837074) {
249 printf("Here I go\n");
250 }
251 if (gc_calls < 1) {
252 UNLOCK(Yap_heap_regs->low_level_trace_lock);
253 return;
254 }
255 {
256 CELL *env_ptr = ENV;
257 PredEntry *p;
258
259 while (env_ptr) {
260 PredEntry *pe = EnvPreg(env_ptr[E_CP]);
261
262 printf("%p->",env_ptr,pe);
263 if (vsc_count == 52LL) printf("\n");
264 if (p == pe) {
265 UNLOCK(Yap_heap_regs->low_level_trace_lock);
266 return;
267 }
268 if (env_ptr != NULL)
269 env_ptr = (CELL *)(env_ptr[E_E]);
270 }
271 printf("\n");
272 }
273 #endif
274 fprintf(Yap_stderr,"%lld ",vsc_count);
275 #if defined(THREADS) || defined(YAPOR)
276 fprintf(Yap_stderr,"(%d)", worker_id);
277 #endif
278 /* check_trail_consistency(); */
279 if (pred == NULL) {
280 UNLOCK(Yap_heap_regs->low_level_trace_lock);
281 return;
282 }
283 if (pred->ModuleOfPred == 0 && !do_trace_primitives) {
284 UNLOCK(Yap_heap_regs->low_level_trace_lock);
285 return;
286 }
287 switch (port) {
288 case enter_pred:
289 mname = RepAtom(AtomOfTerm(Yap_Module_Name(pred)))->StrOfAE;
290 arity = pred->ArityOfPE;
291 if (arity == 0)
292 s = RepAtom((Atom)pred->FunctorOfPred)->StrOfAE;
293 else
294 s = RepAtom(NameOfFunctor((pred->FunctorOfPred)))->StrOfAE;
295 /* if ((pred->ModuleOfPred == 0) && (s[0] == '$'))
296 return; */
297 send_tracer_message("CALL: ", s, arity, mname, args);
298 break;
299 case try_or:
300 send_tracer_message("TRY_OR ", NULL, 0, NULL, args);
301 break;
302 case retry_or:
303 send_tracer_message("FAIL ", NULL, 0, NULL, args);
304 send_tracer_message("RETRY_OR ", NULL, 0, NULL, args);
305 break;
306 case retry_table_generator:
307 send_tracer_message("FAIL ", NULL, 0, NULL, args);
308 mname = RepAtom(AtomOfTerm(Yap_Module_Name(pred)))->StrOfAE;
309 arity = pred->ArityOfPE;
310 if (arity == 0)
311 s = RepAtom((Atom)pred->FunctorOfPred)->StrOfAE;
312 else
313 s = RepAtom(NameOfFunctor((pred->FunctorOfPred)))->StrOfAE;
314 send_tracer_message("RETRY GENERATOR: ", s, arity, mname, args);
315 break;
316 case retry_table_consumer:
317 send_tracer_message("FAIL ", NULL, 0, NULL, args);
318 mname = RepAtom(AtomOfTerm(Yap_Module_Name(pred)))->StrOfAE;
319 arity = pred->ArityOfPE;
320 if (arity == 0) {
321 s = RepAtom((Atom)pred->FunctorOfPred)->StrOfAE;
322 send_tracer_message("RETRY CONSUMER: ", s, 0, mname, NULL);
323 } else {
324 s = RepAtom(NameOfFunctor((pred->FunctorOfPred)))->StrOfAE;
325 send_tracer_message("RETRY CONSUMER: ", s, pred->ArityOfPE, mname, NULL);
326 }
327 break;
328 case retry_table_loader:
329 send_tracer_message("FAIL ", NULL, 0, NULL, args);
330 if (pred == UndefCode) {
331 send_tracer_message("RETRY LOADER ", NULL, 0, NULL, NULL);
332 } else {
333 mname = RepAtom(AtomOfTerm(Yap_Module_Name(pred)))->StrOfAE;
334 arity = pred->ArityOfPE;
335 if (arity == 0)
336 s = RepAtom((Atom)pred->FunctorOfPred)->StrOfAE;
337 else
338 s = RepAtom(NameOfFunctor((pred->FunctorOfPred)))->StrOfAE;
339 send_tracer_message("RETRY LOADER: ", s, 0, mname, NULL);
340 }
341 break;
342 case retry_pred:
343 send_tracer_message("FAIL ", NULL, 0, NULL, args);
344 if (pred != NULL) {
345 mname = RepAtom(AtomOfTerm(Yap_Module_Name(pred)))->StrOfAE;
346 arity = pred->ArityOfPE;
347 if (pred->ModuleOfPred == IDB_MODULE) {
348 s = "recorded";
349 arity = 3;
350 } else if (arity == 0) {
351 s = RepAtom((Atom)pred->FunctorOfPred)->StrOfAE;
352 } else {
353 s = RepAtom(NameOfFunctor((pred->FunctorOfPred)))->StrOfAE;
354 }
355 send_tracer_message("RETRY: ", s, arity, mname, args);
356 }
357 break;
358 }
359 fflush(NULL);
360 UNLOCK(Yap_heap_regs->low_level_trace_lock);
361 }
362
363 void
toggle_low_level_trace(void)364 toggle_low_level_trace(void)
365 {
366 Yap_do_low_level_trace = !Yap_do_low_level_trace;
367 }
368
p_start_low_level_trace(void)369 static Int p_start_low_level_trace(void)
370 {
371 Yap_do_low_level_trace = TRUE;
372 return(TRUE);
373 }
374
p_total_choicepoints(void)375 static Int p_total_choicepoints(void)
376 {
377 return Yap_unify(MkIntegerTerm(Yap_total_choicepoints),ARG1);
378 }
379
p_reset_total_choicepoints(void)380 static Int p_reset_total_choicepoints(void)
381 {
382 Yap_total_choicepoints = 0;
383 }
384
p_show_low_level_trace(void)385 static Int p_show_low_level_trace(void)
386 {
387 fprintf(stderr,"Call counter=%lld\n",vsc_count);
388 return(TRUE);
389 }
390
391 #ifdef THREADS
p_start_low_level_trace2(void)392 static Int p_start_low_level_trace2(void)
393 {
394 thread_trace = IntegerOfTerm(Deref(ARG1))+1;
395 Yap_do_low_level_trace = TRUE;
396 return(TRUE);
397 }
398 #endif
399
400 #include <stdio.h>
401
p_stop_low_level_trace(void)402 static Int p_stop_low_level_trace(void)
403 {
404 Yap_do_low_level_trace = FALSE;
405 do_trace_primitives = TRUE;
406 return(TRUE);
407 }
408
409 volatile int vsc_wait;
410
p_vsc_wait(void)411 static Int p_vsc_wait(void)
412 {
413 while (!vsc_wait);
414 vsc_wait=1;
415 return(TRUE);
416 }
417
418 void
Yap_InitLowLevelTrace(void)419 Yap_InitLowLevelTrace(void)
420 {
421 Yap_InitCPred("start_low_level_trace", 0, p_start_low_level_trace, SafePredFlag);
422 #if THREADS
423 Yap_InitCPred("start_low_level_trace", 1, p_start_low_level_trace2, SafePredFlag);
424 #endif
425 Yap_InitCPred("stop_low_level_trace", 0, p_stop_low_level_trace, SafePredFlag);
426 Yap_InitCPred("show_low_level_trace", 0, p_show_low_level_trace, SafePredFlag);
427 Yap_InitCPred("total_choicepoints", 1, p_total_choicepoints, SafePredFlag);
428 Yap_InitCPred("reset_total_choicepoints", 0, p_reset_total_choicepoints, SafePredFlag);
429 Yap_InitCPred("vsc_wait", 0, p_vsc_wait, SafePredFlag);
430 }
431
432 #endif
433
434
435
436