My Project
Loading...
Searching...
No Matches
sdb.cc
Go to the documentation of this file.
1/****************************************
2* Computer Algebra System SINGULAR *
3****************************************/
4/*
5* ABSTRACT: Singular debugger
6*/
7
8#include "kernel/mod2.h"
9#include "omalloc/omalloc.h"
10#include "misc/options.h"
11#include "reporter/si_signals.h"
12#include "Singular/tok.h"
13#include "Singular/ipshell.h"
14#include "Singular/ipid.h"
15#include "Singular/fevoices.h"
17#include "Singular/sdb.h"
18
19#include <unistd.h> // for unlink,fork,execlp,getpid
20#include <sys/wait.h> // for wait
21
22
23#ifdef HAVE_SDB
24// We use 8 breakpoints - corresponding to a bit in a char variable in procinfo
25// bit 1..7 force a breakpoint, if lineno==sdb_lines[i-1],
26// (for displaying only: file sdb_files[i-1])
27// bit 0 force a breakpoint in every line (used for 'n')
28
29VAR int sdb_lines[]={-1,-1,-1,-1,-1,-1,-1,-1};
30VAR char * sdb_files[6];
32
34{
35 int i;
36 char ff=f>>1;
37 for(i=0;i<7;i++)
38 {
39 if((ff & 1) && (yylineno==sdb_lines[i]))
40 return i+1;
41 ff>>=1;
42 if (ff==0) return 0;
43 }
44 return 0;
45}
46
47static char *sdb_find_arg(char *p)
48{
49 p++;
50 while (*p==' ') p++;
51 char *pp=p;
52 while (*pp>' ') pp++;
53 *pp='\0';
54 return p;
55}
56
58{
59 for(int i=0; i<7;i++)
60 if (sdb_lines[i]!= -1)
61 Print("Breakpoint %d: %s::%d\n",i+1,sdb_files[i],sdb_lines[i]);
62}
63
64BOOLEAN sdb_set_breakpoint(const char *pp, int given_lineno)
65{
67 if ((h==NULL)||(IDTYP(h)!=PROC_CMD))
68 {
69 PrintS(" not found\n");
70 return TRUE;
71 }
72 else
73 {
75 #ifdef HAVE_DYNAMIC_LOADING
76 if (p->language!=LANG_SINGULAR)
77 {
78 PrintS("is not a Singular procedure\n");
79 return TRUE;
80 }
81 #endif
82 int lineno;
83 if (given_lineno >0) lineno=given_lineno;
84 else lineno=p->data.s.body_lineno;
85 int i;
86 if (given_lineno== -1)
87 {
88 i=p->trace_flag;
89 p->trace_flag &=1;
90 Print("breakpoints in %s deleted(%#x)\n",p->procname,i &255);
91 return FALSE;
92 }
93 i=0;
94 while((i<7) && (sdb_lines[i]!=-1)) i++;
95 if (sdb_lines[i]!= -1)
96 {
97 PrintS("too many breakpoints set, max is 7\n");
98 return TRUE;
99 }
100 sdb_lines[i]=lineno;
101 sdb_files[i]=p->libname;
102 i++;
103 p->trace_flag|=(1<<i);
104 Print("breakpoint %d, at line %d in %s\n",i,lineno,p->procname);
105 return FALSE;
106 }
107}
108
110{
111 char * filename = omStrDup("/tmp/sdXXXXXX");
112 int f=mkstemp(filename);
113 if (f==-1)
114 {
115 Print("cannot open %s\n",filename);
116 omFree(filename);
117 return;
118 }
119 if (pi->language!= LANG_SINGULAR)
120 {
121 Print("cannot edit type %d\n",pi->language);
122 si_close(f);
123 }
124 else
125 {
126 const char *editor=getenv("EDITOR");
127 if (editor==NULL)
128 editor=getenv("VISUAL");
129 if (editor==NULL)
130 editor="vi";
131 editor=omStrDup(editor);
132
133 if (pi->data.s.body==NULL)
134 {
136 if (pi->data.s.body==NULL)
137 {
138 PrintS("cannot get the procedure body\n");
139 si_close(f);
140 si_unlink(filename);
141 omFree(filename);
142 return;
143 }
144 }
145
146 ssize_t res=write(f,pi->data.s.body,strlen(pi->data.s.body));
147 si_close(f);
148 if (res==-1)
149 {
150 PrintS("cannot write the procedure body\n");
151 si_unlink(filename);
152 omFree(filename);
153 return;
154 }
155
156 int pid=fork();
157 if (pid!=0)
158 {
159 si_wait(&pid);
160 }
161 else if(pid==0)
162 {
163 if (strchr(editor,' ')==NULL)
164 {
165 execlp(editor,editor,filename,NULL);
166 Print("cannot exec %s\n",editor);
167 }
168 else
169 {
170 size_t len=strlen(editor)+strlen(filename)+2;
171 char *p=(char *)omAlloc(len);
172 snprintf(p,len,"%s %s",editor,filename);
173 int res=system(p);
174 if (res<0)
175 {
176 Print("cannot call `%s`\n",editor);
177 }
178 }
179 exit(0);
180 }
181 else
182 {
183 PrintS("cannot fork\n");
184 }
185
186 FILE* fp=fopen(filename,"r");
187 if (fp==NULL)
188 {
189 Print("cannot read from %s\n",filename);
190 }
191 else
192 {
193 fseek(fp,0L,SEEK_END);
194 long len=ftell(fp);
195 fseek(fp,0L,SEEK_SET);
196
197 omFree((ADDRESS)pi->data.s.body);
198 pi->data.s.body=(char *)omAlloc((int)len+1);
199 myfread( pi->data.s.body, len, 1, fp);
200 pi->data.s.body[len]='\0';
201 fclose(fp);
202 }
203 }
204 si_unlink(filename);
205 omFree(filename);
206}
207
209
210void sdb(Voice * currentVoice, const char * currLine, int len)
211{
212 int bp=0;
213 if ((len>1)
214 && ((currentVoice->pi->trace_flag & 1)
215 || (bp=sdb_checkline(currentVoice->pi->trace_flag)))
216 )
217 {
218 loop
219 {
220 char gdb[80];
221 char *p=(char *)currLine+len-1;
222 while ((*p<=' ') && (p!=currLine))
223 {
224 p--; len--;
225 }
226 if (p==currLine) return;
227
228 currentVoice->pi->trace_flag&= ~1; // delete flag for "all lines"
229 Print("(%s,%d) >>",currentVoice->filename,yylineno);
230 fwrite(currLine,1,len,stdout);
231 Print("<<\nbreakpoint %d (press ? for list of commands)\n",bp);
232 p=fe_fgets_stdin(">>",gdb,80);
233 while (*p==' ') p++;
234 if (*p >' ')
235 {
236 sdb_lastcmd=*p;
237 }
238 Print("command:%c\n",sdb_lastcmd);
239 switch(sdb_lastcmd)
240 {
241 case '?':
242 case 'h':
243 {
244 PrintS(
245 "b - print backtrace of calling stack\n"
246 "B <proc> [<line>] - define breakpoint\n"
247 "c - continue\n"
248 "d - delete current breakpoint\n"
249 "D - show all breakpoints\n"
250 "e - edit the current procedure (current call will be aborted)\n"
251 "h,? - display this help screen\n"
252 "n - execute current line, break at next line\n"
253 "p <var> - display type and value of the variable <var>\n"
254 "q <flags> - quit debugger, set debugger flags(0,1,2)\n"
255 " 0: stop debug, 1:continue, 2: throw an error, return to toplevel\n"
256 "Q - quit Singular\n");
257 int i;
258 for(i=0;i<7;i++)
259 {
260 if (sdb_lines[i] != -1)
261 Print("breakpoint %d at line %d in %s\n",
263 }
264 break;
265 }
266 case 'd':
267 {
268 Print("delete break point %d\n",bp);
269 currentVoice->pi->trace_flag &= (~Sy_bit(bp));
270 if (bp!=0)
271 {
272 sdb_lines[bp-1]=-1;
273 }
274 break;
275 }
276 case 'D':
277 sdb_show_bp();
278 break;
279 #if 0
280 case 'l':
281 {
282 extern void listall(int showproc);
283 listall(FALSE);
284 break;
285 }
286 #endif
287 case 'n':
288 currentVoice->pi->trace_flag|= 1;
289 return;
290 case 'e':
291 {
293 sdb_flags=2;
294 return;
295 }
296 case 'p':
297 {
300 Print("variable `%s`at level %d",p,myynest);
301 idhdl h=ggetid(p);
302 if (h==NULL)
303 PrintS(" not found\n");
304 else
305 {
306 sleftv tmp;
307 memset(&tmp,0,sizeof(tmp));
308 tmp.rtyp=IDHDL;
309 tmp.data=h;
310 Print("(type %s):\n",Tok2Cmdname(tmp.Typ()));
311 tmp.Print();
312 }
313 break;
314 }
315 case 'b':
317 break;
318 case 'B':
319 {
321 Print("procedure `%s` ",p);
323 break;
324 }
325 case 'q':
326 {
328 if (*p!='\0')
329 {
330 sdb_flags=atoi(p);
331 Print("new sdb_flags:%d\n",sdb_flags);
332 }
333 return;
334 }
335 case 'Q':
336 m2_end(999);
337 case 'c':
338 default:
339 return;
340 }
341 }
342 }
343}
344#endif
int BOOLEAN
Definition auxiliary.h:88
#define TRUE
Definition auxiliary.h:101
#define FALSE
Definition auxiliary.h:97
void * ADDRESS
Definition auxiliary.h:120
CanonicalForm FACTORY_PUBLIC pp(const CanonicalForm &)
CanonicalForm pp ( const CanonicalForm & f )
Definition cf_gcd.cc:676
int i
Definition cfEzgcd.cc:132
int p
Definition cfModGcd.cc:4086
CanonicalForm fp
Definition cfModGcd.cc:4110
FILE * f
Definition checklibs.c:9
Class used for (list of) interpreter objects.
Definition subexpr.h:83
int Typ()
Definition subexpr.cc:1048
int rtyp
Definition subexpr.h:91
void * data
Definition subexpr.h:88
void Print(leftv store=NULL, int spaces=0)
Called by type_cmd (e.g. "r;") or as default in jPRINT.
Definition subexpr.cc:63
#define Print
Definition emacs.cc:80
CanonicalForm res
Definition facAbsFact.cc:60
size_t myfread(void *ptr, size_t size, size_t nmemb, FILE *stream)
Definition feFopen.cc:195
VAR int yylineno
Definition febase.cc:40
VAR int myynest
Definition febase.cc:41
char * getenv()
char *(* fe_fgets_stdin)(const char *pr, char *s, int size)
Definition feread.cc:32
VAR Voice * currentVoice
Definition fevoices.cc:49
void VoiceBackTrack()
Definition fevoices.cc:77
const char * Tok2Cmdname(int tok)
Definition gentable.cc:137
#define STATIC_VAR
Definition globaldefs.h:7
#define EXTERN_VAR
Definition globaldefs.h:6
#define VAR
Definition globaldefs.h:5
@ PROC_CMD
Definition grammar.cc:281
idhdl ggetid(const char *n)
Definition ipid.cc:558
#define IDDATA(a)
Definition ipid.h:126
#define IDTYP(a)
Definition ipid.h:119
char * iiGetLibProcBuffer(procinfo *pi, int part)
Definition iplib.cc:197
STATIC_VAR Poly * h
Definition janet.cc:971
#define pi
Definition libparse.cc:1145
#define SEEK_SET
Definition mod2.h:115
#define SEEK_END
Definition mod2.h:111
void m2_end(int i)
Definition misc_ip.cc:1102
#define omStrDup(s)
#define omAlloc(size)
#define omFree(addr)
#define NULL
Definition omList.c:12
#define Sy_bit(x)
Definition options.h:31
void PrintS(const char *s)
Definition reporter.cc:284
idrec * idhdl
Definition ring.h:22
BOOLEAN sdb_set_breakpoint(const char *pp, int given_lineno)
Definition sdb.cc:64
VAR int sdb_flags
Definition sdb.cc:31
void sdb_edit(procinfo *pi)
Definition sdb.cc:109
VAR char * sdb_files[6]
Definition sdb.cc:30
void sdb(Voice *currentVoice, const char *currLine, int len)
Definition sdb.cc:210
static char * sdb_find_arg(char *p)
Definition sdb.cc:47
void sdb_show_bp()
Definition sdb.cc:57
VAR int sdb_lines[]
Definition sdb.cc:29
int sdb_checkline(char f)
Definition sdb.cc:33
STATIC_VAR char sdb_lastcmd
Definition sdb.cc:208
#define loop
Definition structs.h:71
procinfo * procinfov
Definition structs.h:56
@ LANG_SINGULAR
Definition subexpr.h:22
#define IDHDL
Definition tok.h:31