source: git/Singular/sdb.cc @ 020ef9

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