source: git/Singular/sdb.cc @ c232af

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