xref: /titanic_44/usr/src/lib/libpp/common/pptrace.c (revision da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968)
1*da2e3ebdSchin /***********************************************************************
2*da2e3ebdSchin *                                                                      *
3*da2e3ebdSchin *               This software is part of the ast package               *
4*da2e3ebdSchin *           Copyright (c) 1986-2007 AT&T Knowledge Ventures            *
5*da2e3ebdSchin *                      and is licensed under the                       *
6*da2e3ebdSchin *                  Common Public License, Version 1.0                  *
7*da2e3ebdSchin *                      by AT&T Knowledge Ventures                      *
8*da2e3ebdSchin *                                                                      *
9*da2e3ebdSchin *                A copy of the License is available at                 *
10*da2e3ebdSchin *            http://www.opensource.org/licenses/cpl1.0.txt             *
11*da2e3ebdSchin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12*da2e3ebdSchin *                                                                      *
13*da2e3ebdSchin *              Information and Software Systems Research               *
14*da2e3ebdSchin *                            AT&T Research                             *
15*da2e3ebdSchin *                           Florham Park NJ                            *
16*da2e3ebdSchin *                                                                      *
17*da2e3ebdSchin *                 Glenn Fowler <gsf@research.att.com>                  *
18*da2e3ebdSchin *                                                                      *
19*da2e3ebdSchin ***********************************************************************/
20*da2e3ebdSchin #pragma prototyped
21*da2e3ebdSchin /*
22*da2e3ebdSchin  * Glenn Fowler
23*da2e3ebdSchin  * AT&T Research
24*da2e3ebdSchin  *
25*da2e3ebdSchin  * preprocessor library trace and debug support
26*da2e3ebdSchin  */
27*da2e3ebdSchin 
28*da2e3ebdSchin #include "pplib.h"
29*da2e3ebdSchin #include "ppfsm.h"
30*da2e3ebdSchin 
31*da2e3ebdSchin #include <ctype.h>
32*da2e3ebdSchin 
33*da2e3ebdSchin /*
34*da2e3ebdSchin  * convert token string to printable form
35*da2e3ebdSchin  */
36*da2e3ebdSchin 
37*da2e3ebdSchin char*
38*da2e3ebdSchin pptokstr(register char* s, register int c)
39*da2e3ebdSchin {
40*da2e3ebdSchin 	register char*	t;
41*da2e3ebdSchin 
42*da2e3ebdSchin 	static char	buf[8];
43*da2e3ebdSchin 
44*da2e3ebdSchin 	if (t = s)
45*da2e3ebdSchin 	{
46*da2e3ebdSchin 		while (*t == ' ' || *t == '\t') t++;
47*da2e3ebdSchin 		c = *t ? *t : *s;
48*da2e3ebdSchin 	}
49*da2e3ebdSchin 	switch (c)
50*da2e3ebdSchin 	{
51*da2e3ebdSchin 	case 0:
52*da2e3ebdSchin 	case 0400:
53*da2e3ebdSchin 		return("`EOF'");
54*da2e3ebdSchin 	case ' ':
55*da2e3ebdSchin 		return("`space'");
56*da2e3ebdSchin 	case '\f':
57*da2e3ebdSchin 		return("`formfeed'");
58*da2e3ebdSchin 	case '\n':
59*da2e3ebdSchin 		return("`newline'");
60*da2e3ebdSchin 	case '\t':
61*da2e3ebdSchin 		return("`tab'");
62*da2e3ebdSchin 	case '\v':
63*da2e3ebdSchin 		return("`vertical-tab'");
64*da2e3ebdSchin 	case T_TOKCAT:
65*da2e3ebdSchin 		return("##");
66*da2e3ebdSchin 	default:
67*da2e3ebdSchin 		if (iscntrl(c) || !isprint(c)) sfsprintf(buf, sizeof(buf), "`%03o'", c);
68*da2e3ebdSchin 		else if (s) return(s);
69*da2e3ebdSchin 		else sfsprintf(buf, sizeof(buf), "%c", c);
70*da2e3ebdSchin 		return(buf);
71*da2e3ebdSchin 	}
72*da2e3ebdSchin }
73*da2e3ebdSchin 
74*da2e3ebdSchin #if DEBUG & TRACE_debug
75*da2e3ebdSchin 
76*da2e3ebdSchin #include "ppdebug.h"
77*da2e3ebdSchin 
78*da2e3ebdSchin /*
79*da2e3ebdSchin  * return input stream name given index
80*da2e3ebdSchin  */
81*da2e3ebdSchin 
82*da2e3ebdSchin char*
83*da2e3ebdSchin ppinstr(register struct ppinstk* p)
84*da2e3ebdSchin {
85*da2e3ebdSchin 	register int	i;
86*da2e3ebdSchin 
87*da2e3ebdSchin 	static char	buf[128];
88*da2e3ebdSchin 
89*da2e3ebdSchin 	for (i = 0; i < elementsof(ppinmap); i++)
90*da2e3ebdSchin 		if (p->type == ppinmap[i].val)
91*da2e3ebdSchin 		{
92*da2e3ebdSchin 			switch (p->type)
93*da2e3ebdSchin 			{
94*da2e3ebdSchin 			case IN_MACRO:
95*da2e3ebdSchin #if MACDEF
96*da2e3ebdSchin 			case IN_MULTILINE:
97*da2e3ebdSchin #endif
98*da2e3ebdSchin 				if (p->symbol)
99*da2e3ebdSchin 				{
100*da2e3ebdSchin 					sfsprintf(buf, sizeof(buf), "%s=%s", ppinmap[i].nam, p->symbol->name);
101*da2e3ebdSchin 					return(buf);
102*da2e3ebdSchin 				}
103*da2e3ebdSchin 				break;
104*da2e3ebdSchin 			}
105*da2e3ebdSchin 			return(ppinmap[i].nam);
106*da2e3ebdSchin 		}
107*da2e3ebdSchin 	sfsprintf(buf, sizeof(buf), "UNKNOWN[%d]", p->type);
108*da2e3ebdSchin 	return(buf);
109*da2e3ebdSchin }
110*da2e3ebdSchin 
111*da2e3ebdSchin /*
112*da2e3ebdSchin  * return string given fsm lex state
113*da2e3ebdSchin  */
114*da2e3ebdSchin 
115*da2e3ebdSchin char*
116*da2e3ebdSchin pplexstr(register int lex)
117*da2e3ebdSchin {
118*da2e3ebdSchin 	register int	i;
119*da2e3ebdSchin 	int		splice;
120*da2e3ebdSchin 	static char	buf[64];
121*da2e3ebdSchin 
122*da2e3ebdSchin 	if (lex < 0) lex &= ~lex;
123*da2e3ebdSchin 	splice = (lex & SPLICE);
124*da2e3ebdSchin 	lex &= 0x7f;
125*da2e3ebdSchin 	for (i = 0; i < (elementsof(pplexmap) - 1) && (lex > pplexmap[i].val || lex == pplexmap[i+1].val); i++);
126*da2e3ebdSchin 	if (lex != pplexmap[i].val)
127*da2e3ebdSchin 	{
128*da2e3ebdSchin 		if (pplexmap[i].val < 0) sfsprintf(buf, sizeof(buf), "%s|0x%04x%s", pplexmap[i].nam, lex, splice ? "|SPLICE" : "");
129*da2e3ebdSchin 		else sfsprintf(buf, sizeof(buf), "%s+%d", pplexmap[i-1].nam, lex - pplexmap[i-1].val, splice ? "|SPLICE" : "");
130*da2e3ebdSchin 		return(buf);
131*da2e3ebdSchin 	}
132*da2e3ebdSchin 	if (splice)
133*da2e3ebdSchin 	{
134*da2e3ebdSchin 		sfsprintf(buf, sizeof(buf), "%s|SPLICE", pplexmap[i].nam);
135*da2e3ebdSchin 		return(buf);
136*da2e3ebdSchin 	}
137*da2e3ebdSchin 	return(pplexmap[i].nam);
138*da2e3ebdSchin }
139*da2e3ebdSchin 
140*da2e3ebdSchin /*
141*da2e3ebdSchin  * return string given map p of size n and flags
142*da2e3ebdSchin  */
143*da2e3ebdSchin 
144*da2e3ebdSchin static char*
145*da2e3ebdSchin ppflagstr(register struct map* p, int n, register long flags)
146*da2e3ebdSchin {
147*da2e3ebdSchin 	register int	i;
148*da2e3ebdSchin 	register int	k;
149*da2e3ebdSchin 	register char*	s;
150*da2e3ebdSchin 
151*da2e3ebdSchin 	static char	buf[128];
152*da2e3ebdSchin 
153*da2e3ebdSchin 	s = buf;
154*da2e3ebdSchin 	for (i = 0; i < n; i++)
155*da2e3ebdSchin 		if (flags & p[i].val)
156*da2e3ebdSchin 		{
157*da2e3ebdSchin 			k = strlen(p[i].nam);
158*da2e3ebdSchin 			if ((elementsof(buf) - 2 - (s - buf)) > k)
159*da2e3ebdSchin 			{
160*da2e3ebdSchin 				if (s > buf) *s++ = '|';
161*da2e3ebdSchin 				strcpy(s, p[i].nam);
162*da2e3ebdSchin 				s += k;
163*da2e3ebdSchin 			}
164*da2e3ebdSchin 		}
165*da2e3ebdSchin 	*s = 0;
166*da2e3ebdSchin 	return(buf);
167*da2e3ebdSchin }
168*da2e3ebdSchin 
169*da2e3ebdSchin /*
170*da2e3ebdSchin  * return string given pp.mode
171*da2e3ebdSchin  */
172*da2e3ebdSchin 
173*da2e3ebdSchin char*
174*da2e3ebdSchin ppmodestr(register long mode)
175*da2e3ebdSchin {
176*da2e3ebdSchin 	return(ppflagstr(ppmodemap, elementsof(ppmodemap), mode));
177*da2e3ebdSchin }
178*da2e3ebdSchin 
179*da2e3ebdSchin /*
180*da2e3ebdSchin  * return string given pp.option
181*da2e3ebdSchin  */
182*da2e3ebdSchin 
183*da2e3ebdSchin char*
184*da2e3ebdSchin ppoptionstr(register long option)
185*da2e3ebdSchin {
186*da2e3ebdSchin 	return(ppflagstr(ppoptionmap, elementsof(ppoptionmap), option));
187*da2e3ebdSchin }
188*da2e3ebdSchin 
189*da2e3ebdSchin /*
190*da2e3ebdSchin  * return string given pp.state
191*da2e3ebdSchin  */
192*da2e3ebdSchin 
193*da2e3ebdSchin char*
194*da2e3ebdSchin ppstatestr(register long state)
195*da2e3ebdSchin {
196*da2e3ebdSchin 	return(ppflagstr(ppstatemap, elementsof(ppstatemap), state));
197*da2e3ebdSchin }
198*da2e3ebdSchin 
199*da2e3ebdSchin #include <sig.h>
200*da2e3ebdSchin 
201*da2e3ebdSchin /*
202*da2e3ebdSchin  * io stream stack trace
203*da2e3ebdSchin  * sig==0 registers the handler
204*da2e3ebdSchin  */
205*da2e3ebdSchin 
206*da2e3ebdSchin void
207*da2e3ebdSchin pptrace(int sig)
208*da2e3ebdSchin {
209*da2e3ebdSchin 	register char*			s;
210*da2e3ebdSchin 	register char*			x;
211*da2e3ebdSchin 	register struct ppinstk*	p;
212*da2e3ebdSchin 	static int			handling;
213*da2e3ebdSchin 
214*da2e3ebdSchin 	if (!sig)
215*da2e3ebdSchin 	{
216*da2e3ebdSchin #ifdef SIGBUS
217*da2e3ebdSchin 		signal(SIGBUS, pptrace);
218*da2e3ebdSchin #endif
219*da2e3ebdSchin #ifdef SIGSEGV
220*da2e3ebdSchin 		signal(SIGSEGV, pptrace);
221*da2e3ebdSchin #endif
222*da2e3ebdSchin #ifdef SIGILL
223*da2e3ebdSchin 		signal(SIGILL, pptrace);
224*da2e3ebdSchin #endif
225*da2e3ebdSchin 		signal(SIGQUIT, pptrace);
226*da2e3ebdSchin 		return;
227*da2e3ebdSchin 	}
228*da2e3ebdSchin 	s = fmtsignal(sig);
229*da2e3ebdSchin 	if (handling)
230*da2e3ebdSchin 	{
231*da2e3ebdSchin 		sfprintf(sfstderr, "\n%s during io stack trace\n", s);
232*da2e3ebdSchin 		signal(handling, SIG_DFL);
233*da2e3ebdSchin 		sigunblock(handling);
234*da2e3ebdSchin 		kill(getpid(), handling);
235*da2e3ebdSchin 		pause();
236*da2e3ebdSchin 		error(PANIC, "signal not redelivered");
237*da2e3ebdSchin 	}
238*da2e3ebdSchin 	handling = sig;
239*da2e3ebdSchin 	sfprintf(sfstderr, "\n%s - io stack trace\n", s);
240*da2e3ebdSchin 	for (p = pp.in; p->prev; p = p->prev)
241*da2e3ebdSchin 	{
242*da2e3ebdSchin 		sfprintf(sfstderr, "\n[%s]\n", ppinstr(p));
243*da2e3ebdSchin 		if ((s = pp.in->nextchr) && *s)
244*da2e3ebdSchin 		{
245*da2e3ebdSchin 			if (*s != '\n') sfputc(sfstderr, '\t');
246*da2e3ebdSchin 			x = s + 256;
247*da2e3ebdSchin 			while (*s && s < x)
248*da2e3ebdSchin 			{
249*da2e3ebdSchin 				sfputc(sfstderr, *s);
250*da2e3ebdSchin 				if (*s++ == '\n' && *s && *s != '\n') sfputc(sfstderr, '\t');
251*da2e3ebdSchin 			}
252*da2e3ebdSchin 			if (*s) sfprintf(sfstderr, " ...");
253*da2e3ebdSchin 		}
254*da2e3ebdSchin 	}
255*da2e3ebdSchin 	sfprintf(sfstderr, "\n");
256*da2e3ebdSchin 	handling = 0;
257*da2e3ebdSchin 	signal(sig, SIG_DFL);
258*da2e3ebdSchin 	sigunblock(sig);
259*da2e3ebdSchin 	kill(getpid(), sig);
260*da2e3ebdSchin 	pause();
261*da2e3ebdSchin 	error(PANIC, "signal not redelivered");
262*da2e3ebdSchin }
263*da2e3ebdSchin 
264*da2e3ebdSchin #endif
265