source: git/kernel/sdb.cc @ 5fdd0f

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