source: git/Singular/sdb.cc @ 9f7665

spielwiese
Last change on this file since 9f7665 was 9f7665, checked in by Oleksandr Motsak <motsak@…>, 10 years ago
Removed HAVE_CONFIG guards fix: fixed the inclusion of configure-generated *config.h's
  • Property mode set to 100644
File size: 7.2 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT: Singular debugger
6*/
7
8#include <unistd.h>   // for unlink,fork,execlp,getpid
9#include <sys/wait.h> // for wait
10
11
12
13#include <kernel/mod2.h>
14#include <Singular/tok.h>
15#include <misc/options.h>
16#include <omalloc/omalloc.h>
17#include <kernel/febase.h>
18#include <Singular/ipshell.h>
19#include <Singular/ipid.h>
20#include <Singular/sdb.h>
21#include <reporter/si_signals.h>
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
29int sdb_lines[]={-1,-1,-1,-1,-1,-1,-1,-1};
30char * sdb_files[6];
31int sdb_flags=0;
32
33int sdb_checkline(char f)
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
57void sdb_show_bp()
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{
66  idhdl h=ggetid(pp);
67  if ((h==NULL)||(IDTYP(h)!=PROC_CMD))
68  {
69    PrintS(" not found\n");
70    return TRUE;
71  }
72  else
73  {
74    procinfov p=(procinfov)IDDATA(h);
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
109void sdb_edit(procinfo *pi)
110{
111  char * filename = omStrDup("/tmp/sd000000");
112  sprintf(filename+7,"%d",getpid());
113  FILE *fp=fopen(filename,"w");
114  if (fp==NULL)
115  {
116    Print("cannot open %s\n",filename);
117    omFree(filename);
118    return;
119  }
120  if (pi->language!= LANG_SINGULAR)
121  {
122    Print("cannot edit type %d\n",pi->language);
123    fclose(fp);
124    fp=NULL;
125  }
126  else
127  {
128    const char *editor=getenv("EDITOR");
129    if (editor==NULL)
130      editor=getenv("VISUAL");
131    if (editor==NULL)
132      editor="vi";
133    editor=omStrDup(editor);
134
135    if (pi->data.s.body==NULL)
136    {
137      iiGetLibProcBuffer(pi);
138      if (pi->data.s.body==NULL)
139      {
140        PrintS("cannot get the procedure body\n");
141        fclose(fp);
142        si_unlink(filename);
143        omFree(filename);
144        return;
145      }
146    }
147
148    fwrite(pi->data.s.body,1,strlen(pi->data.s.body),fp);
149    fclose(fp);
150
151    int pid=fork();
152    if (pid!=0)
153    {
154      si_wait(&pid);
155    }
156    else if(pid==0)
157    {
158      if (strchr(editor,' ')==NULL)
159      {
160        execlp(editor,editor,filename,NULL);
161        Print("cannot exec %s\n",editor);
162      }
163      else
164      {
165        char *p=(char *)omAlloc(strlen(editor)+strlen(filename)+2);
166        sprintf(p,"%s %s",editor,filename);
167        system(p);
168      }
169      exit(0);
170    }
171    else
172    {
173      PrintS("cannot fork\n");
174    }
175
176    fp=fopen(filename,"r");
177    if (fp==NULL)
178    {
179      Print("cannot read from %s\n",filename);
180    }
181    else
182    {
183      fseek(fp,0L,SEEK_END);
184      long len=ftell(fp);
185      fseek(fp,0L,SEEK_SET);
186
187      omFree((ADDRESS)pi->data.s.body);
188      pi->data.s.body=(char *)omAlloc((int)len+1);
189      myfread( pi->data.s.body, len, 1, fp);
190      pi->data.s.body[len]='\0';
191      fclose(fp);
192    }
193  }
194  si_unlink(filename);
195  omFree(filename);
196}
197
198static char sdb_lastcmd='c';
199
200void sdb(Voice * currentVoice, const char * currLine, int len)
201{
202  int bp=0;
203  if ((len>1)
204  && ((currentVoice->pi->trace_flag & 1)
205    || (bp=sdb_checkline(currentVoice->pi->trace_flag)))
206  )
207  {
208    loop
209    {
210      char gdb[80];
211      char *p=(char *)currLine+len-1;
212      while ((*p<=' ') && (p!=currLine))
213      {
214        p--; len--;
215      }
216      if (p==currLine) return;
217
218      currentVoice->pi->trace_flag&= ~1; // delete flag for "all lines"
219      Print("(%s,%d) >>",currentVoice->filename,yylineno);
220      fwrite(currLine,1,len,stdout);
221      Print("<<\nbreakpoint %d (press ? for list of commands)\n",bp);
222      p=fe_fgets_stdin(">>",gdb,80);
223      while (*p==' ') p++;
224      if (*p >' ')
225      {
226        sdb_lastcmd=*p;
227      }
228      Print("command:%c\n",sdb_lastcmd);
229      switch(sdb_lastcmd)
230      {
231        case '?':
232        case 'h':
233        {
234          PrintS(
235          "b - print backtrace of calling stack\n"
236          "B <proc> [<line>] - define breakpoint\n"
237          "c - continue\n"
238          "d - delete current breakpoint\n"
239          "D - show all breakpoints\n"
240          "e - edit the current procedure (current call will be aborted)\n"
241          "h,? - display this help screen\n"
242          "n - execute current line, break at next line\n"
243          "p <var> - display type and value of the variable <var>\n"
244          "q <flags> - quit debugger, set debugger flags(0,1,2)\n"
245          "Q - quit Singular\n");
246          int i;
247          for(i=0;i<7;i++)
248          {
249            if (sdb_lines[i] != -1)
250              Print("breakpoint %d at line %d in %s\n",
251                i,sdb_lines[i],sdb_files[i]);
252          }
253          break;
254        }
255        case 'd':
256        {
257          Print("delete break point %d\n",bp);
258          currentVoice->pi->trace_flag &= (~Sy_bit(bp));
259          if (bp!=0)
260          {
261            sdb_lines[bp-1]=-1;
262          }
263          break;
264        }
265        case 'D':
266          sdb_show_bp();
267          break;
268        case 'n':
269          currentVoice->pi->trace_flag|= 1;
270          return;
271        case 'e':
272        {
273          sdb_edit(currentVoice->pi);
274          sdb_flags=2;
275          return;
276        }
277        case 'p':
278        {
279          p=sdb_find_arg(p);
280          Print("variable `%s`",p);
281          idhdl h=ggetid(p);
282          if (h==NULL)
283            PrintS(" not found\n");
284          else
285          {
286            sleftv tmp;
287            memset(&tmp,0,sizeof(tmp));
288            tmp.rtyp=IDHDL;
289            tmp.data=h;
290            Print("(type %s):\n",Tok2Cmdname(tmp.Typ()));
291            tmp.Print();
292          }
293          break;
294        }
295        case 'b':
296          VoiceBackTrack();
297          break;
298        case 'B':
299        {
300          p=sdb_find_arg(p);
301          Print("procedure `%s` ",p);
302          sdb_set_breakpoint(p);
303          break;
304        }
305        case 'q':
306        {
307          p=sdb_find_arg(p);
308          if (*p!='\0')
309          {
310            sdb_flags=atoi(p);
311            Print("new sdb_flags:%d\n",sdb_flags);
312          }
313          return;
314        }
315        case 'Q':
316          m2_end(999);
317        case 'c':
318        default:
319          return;
320      }
321    }
322  }
323}
324#endif
Note: See TracBrowser for help on using the repository browser.