source: git/Singular/sdb.cc @ 8d1432e

spielwiese
Last change on this file since 8d1432e was 430af3, checked in by Hans Schoenemann <hannes@…>, 9 years ago
version 4.0.2p1
  • Property mode set to 100644
File size: 7.4 KB
Line 
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
13#include <Singular/tok.h>
14#include <Singular/ipshell.h>
15#include <Singular/ipid.h>
16#include <Singular/fevoices.h>
17#include <kernel/oswrapper/feread.h>
18#include <Singular/sdb.h>
19
20#include <unistd.h>   // for unlink,fork,execlp,getpid
21#include <sys/wait.h> // for wait
22
23
24#ifdef HAVE_SDB
25// We use 8 breakpoints - corresponding to a bit in a char variable in procinfo
26// bit 1..7 force a breakpoint, if lineno==sdb_lines[i-1],
27//                         (for displaying only: file sdb_files[i-1])
28// bit 0 force a breakpoint in every line (used for 'n')
29
30int sdb_lines[]={-1,-1,-1,-1,-1,-1,-1,-1};
31char * sdb_files[6];
32int sdb_flags=0;
33
34int sdb_checkline(char f)
35{
36  int i;
37  char ff=f>>1;
38  for(i=0;i<7;i++)
39  {
40    if((ff & 1) && (yylineno==sdb_lines[i]))
41      return i+1;
42    ff>>=1;
43    if (ff==0) return 0;
44  }
45  return 0;
46}
47
48static char *sdb_find_arg(char *p)
49{
50  p++;
51  while (*p==' ') p++;
52  char *pp=p;
53  while (*pp>' ') pp++;
54  *pp='\0';
55  return p;
56}
57
58void sdb_show_bp()
59{
60  for(int i=0; i<7;i++)
61    if (sdb_lines[i]!= -1)
62      Print("Breakpoint %d: %s::%d\n",i+1,sdb_files[i],sdb_lines[i]);
63}
64
65BOOLEAN sdb_set_breakpoint(const char *pp, int given_lineno)
66{
67  idhdl h=ggetid(pp);
68  if ((h==NULL)||(IDTYP(h)!=PROC_CMD))
69  {
70    PrintS(" not found\n");
71    return TRUE;
72  }
73  else
74  {
75    procinfov p=(procinfov)IDDATA(h);
76    #ifdef HAVE_DYNAMIC_LOADING
77    if (p->language!=LANG_SINGULAR)
78    {
79      PrintS("is not a Singular procedure\n");
80      return TRUE;
81    }
82    #endif
83    int lineno;
84    if (given_lineno >0) lineno=given_lineno;
85    else                 lineno=p->data.s.body_lineno;
86    int i;
87    if (given_lineno== -1)
88    {
89      i=p->trace_flag;
90      p->trace_flag &=1;
91      Print("breakpoints in %s deleted(%#x)\n",p->procname,i &255);
92      return FALSE;
93    }
94    i=0;
95    while((i<7) && (sdb_lines[i]!=-1)) i++;
96    if (sdb_lines[i]!= -1)
97    {
98      PrintS("too many breakpoints set, max is 7\n");
99      return TRUE;
100    }
101    sdb_lines[i]=lineno;
102    sdb_files[i]=p->libname;
103    i++;
104    p->trace_flag|=(1<<i);
105    Print("breakpoint %d, at line %d in %s\n",i,lineno,p->procname);
106    return FALSE;
107  }
108}
109
110void sdb_edit(procinfo *pi)
111{
112  char * filename = omStrDup("/tmp/sd000000");
113  sprintf(filename+7,"%d",getpid());
114  FILE *fp=fopen(filename,"w");
115  if (fp==NULL)
116  {
117    Print("cannot open %s\n",filename);
118    omFree(filename);
119    return;
120  }
121  if (pi->language!= LANG_SINGULAR)
122  {
123    Print("cannot edit type %d\n",pi->language);
124    fclose(fp);
125    fp=NULL;
126  }
127  else
128  {
129    const char *editor=getenv("EDITOR");
130    if (editor==NULL)
131      editor=getenv("VISUAL");
132    if (editor==NULL)
133      editor="vi";
134    editor=omStrDup(editor);
135
136    if (pi->data.s.body==NULL)
137    {
138      iiGetLibProcBuffer(pi);
139      if (pi->data.s.body==NULL)
140      {
141        PrintS("cannot get the procedure body\n");
142        fclose(fp);
143        si_unlink(filename);
144        omFree(filename);
145        return;
146      }
147    }
148
149    fwrite(pi->data.s.body,1,strlen(pi->data.s.body),fp);
150    fclose(fp);
151
152    int pid=fork();
153    if (pid!=0)
154    {
155      si_wait(&pid);
156    }
157    else if(pid==0)
158    {
159      if (strchr(editor,' ')==NULL)
160      {
161        execlp(editor,editor,filename,NULL);
162        Print("cannot exec %s\n",editor);
163      }
164      else
165      {
166        char *p=(char *)omAlloc(strlen(editor)+strlen(filename)+2);
167        sprintf(p,"%s %s",editor,filename);
168        system(p);
169      }
170      exit(0);
171    }
172    else
173    {
174      PrintS("cannot fork\n");
175    }
176
177    fp=fopen(filename,"r");
178    if (fp==NULL)
179    {
180      Print("cannot read from %s\n",filename);
181    }
182    else
183    {
184      fseek(fp,0L,SEEK_END);
185      long len=ftell(fp);
186      fseek(fp,0L,SEEK_SET);
187
188      omFree((ADDRESS)pi->data.s.body);
189      pi->data.s.body=(char *)omAlloc((int)len+1);
190      myfread( pi->data.s.body, len, 1, fp);
191      pi->data.s.body[len]='\0';
192      fclose(fp);
193    }
194  }
195  si_unlink(filename);
196  omFree(filename);
197}
198
199static char sdb_lastcmd='c';
200
201void sdb(Voice * currentVoice, const char * currLine, int len)
202{
203  int bp=0;
204  if ((len>1)
205  && ((currentVoice->pi->trace_flag & 1)
206    || (bp=sdb_checkline(currentVoice->pi->trace_flag)))
207  )
208  {
209    loop
210    {
211      char gdb[80];
212      char *p=(char *)currLine+len-1;
213      while ((*p<=' ') && (p!=currLine))
214      {
215        p--; len--;
216      }
217      if (p==currLine) return;
218
219      currentVoice->pi->trace_flag&= ~1; // delete flag for "all lines"
220      Print("(%s,%d) >>",currentVoice->filename,yylineno);
221      fwrite(currLine,1,len,stdout);
222      Print("<<\nbreakpoint %d (press ? for list of commands)\n",bp);
223      p=fe_fgets_stdin(">>",gdb,80);
224      while (*p==' ') p++;
225      if (*p >' ')
226      {
227        sdb_lastcmd=*p;
228      }
229      Print("command:%c\n",sdb_lastcmd);
230      switch(sdb_lastcmd)
231      {
232        case '?':
233        case 'h':
234        {
235          PrintS(
236          "b - print backtrace of calling stack\n"
237          "B <proc> [<line>] - define breakpoint\n"
238          "c - continue\n"
239          "d - delete current breakpoint\n"
240          "D - show all breakpoints\n"
241          "e - edit the current procedure (current call will be aborted)\n"
242          "h,? - display this help screen\n"
243          "n - execute current line, break at next line\n"
244          "p <var> - display type and value of the variable <var>\n"
245          "q <flags> - quit debugger, set debugger flags(0,1,2)\n"
246          "   0: stop debug, 1:continue, 2: throw an error, return to toplevel\n"
247          "Q - quit Singular\n");
248          int i;
249          for(i=0;i<7;i++)
250          {
251            if (sdb_lines[i] != -1)
252              Print("breakpoint %d at line %d in %s\n",
253                i,sdb_lines[i],sdb_files[i]);
254          }
255          break;
256        }
257        case 'd':
258        {
259          Print("delete break point %d\n",bp);
260          currentVoice->pi->trace_flag &= (~Sy_bit(bp));
261          if (bp!=0)
262          {
263            sdb_lines[bp-1]=-1;
264          }
265          break;
266        }
267        case 'D':
268          sdb_show_bp();
269          break;
270        #if 0
271        case 'l':
272        {
273          extern void listall(int showproc);
274          listall(FALSE);
275          break;
276        }
277        #endif
278        case 'n':
279          currentVoice->pi->trace_flag|= 1;
280          return;
281        case 'e':
282        {
283          sdb_edit(currentVoice->pi);
284          sdb_flags=2;
285          return;
286        }
287        case 'p':
288        {
289          p=sdb_find_arg(p);
290          extern int myynest;
291          Print("variable `%s`at level %d",p,myynest);
292          idhdl h=ggetid(p);
293          if (h==NULL)
294            PrintS(" not found\n");
295          else
296          {
297            sleftv tmp;
298            memset(&tmp,0,sizeof(tmp));
299            tmp.rtyp=IDHDL;
300            tmp.data=h;
301            Print("(type %s):\n",Tok2Cmdname(tmp.Typ()));
302            tmp.Print();
303          }
304          break;
305        }
306        case 'b':
307          VoiceBackTrack();
308          break;
309        case 'B':
310        {
311          p=sdb_find_arg(p);
312          Print("procedure `%s` ",p);
313          sdb_set_breakpoint(p);
314          break;
315        }
316        case 'q':
317        {
318          p=sdb_find_arg(p);
319          if (*p!='\0')
320          {
321            sdb_flags=atoi(p);
322            Print("new sdb_flags:%d\n",sdb_flags);
323          }
324          return;
325        }
326        case 'Q':
327          m2_end(999);
328        case 'c':
329        default:
330          return;
331      }
332    }
333  }
334}
335#endif
Note: See TracBrowser for help on using the repository browser.