kevinlawler / kona

Open-source implementation of the K programming language
ISC License
1.36k stars 138 forks source link

Crash when repeating typo of :6 for 6: #611

Closed gitonthescene closed 2 years ago

gitonthescene commented 2 years ago

I meant to run 6: `"quote.csv" but instead typed :6 `"quote.csv" which led to a crash. Oddly, the crash happens only when running this twice, which makes me think it's upsetting the state of the interpreter somehow.

$ ./k       
kona      \ for help. \\ to exit.

  :6 `"quote.csv"
rank error
>  :6 `"quote.csv"
[1]    11957 segmentation fault  ./k
$
tavmem commented 2 years ago

How k2.8 handles this:

K 2.8 2000-10-10 Copyright (C) 1993-2000 Kx Systems
\ for help. \\ to exit.

  :6 `"quote.csv"
rank error
:6 `"quote.csv"
 ^
>  :6 `"quote.csv"
rank error
6 `"quote.csv"
^
>>  :6 `"quote.csv"
rank error
6 `"quote.csv"
^
>>>  \
>>  \
>  \
tavmem commented 2 years ago

Without the leading colon, kona is OK:

[tom@localhost kona]$ rlwrap -n ./k
kona      \ for help. \\ to exit.

  6 `"quote.csv"
rank error
>  6 `"quote.csv"
rank error
>>  6 `"quote.csv"
rank error
>>>  6 `"quote.csv"
rank error
>>>>  \
>>>  \
>>  \
>  \
tavmem commented 2 years ago

Using tavmem/ks, the final lines are:

cdp: aaaaaaaaaa      fln: 1      s[0]: :
Segmentation fault (core dumped)

Using 'grep' to fiind the location:

[tom@localhost ks]$ grep "cdp:" src/*.c
src/kc.c:  O("s: %s\n",s); O("cdp: %s      fln: %lld      s[0]: %c\n",cdp,fln,s[0]);
src/kc.c:      O("cfnc: %lld   ocr: %lld   cprm-1: %lld   fnc: %s   cdp: %s\n",cfnc,ocr,cprm-1,fnc,cdp);

In src/kc.c we find

  O("s: %s\n",s); O("cdp: %s      fln: %lld      s[0]: %c\n",cdp,fln,s[0]);
  if(fln&&(s[0]=='#' && s[1]=='!')) GC;
  if(fCheck && s[0]==':' && (lineA || flc))
  { I i,j,jj;
    if(*a)
    { for(j=0; j<10; j++)if(cdp[j]==*ofnc)break;
      for(i=0; i<strlen(lineC); i++)if(lineC[i]==cdp[j+1])break;
      *n=0; appender(a,n,lineC,i+1); }
    else
    { I cfnc=0; for(i=0; i<strlen(lineC); i++)if(lineC[i]==*fnc)cfnc++;
      I cprm=0; for(i=0; cdp[i]!='a'; i++)cprm++;
      O("cfnc: %lld   ocr: %lld   cprm-1: %lld   fnc: %s   cdp: %s\n",cfnc,ocr,cprm-1,fnc,cdp);
      if(cfnc!=ocr && !(cfnc==ocr && cdp[cprm-1]==*fnc))        //else throw away complete lineC
      { I cfl=0,cfc=0;                         //cfl = count of *fnc in lineC, cfc= count in cdp
        for(i=strlen(lineC)-1; i>0; i--)
        { if(lineC[i]==*fnc)cfl++;
          if(cfl==ocr)break; }                 //have loc of ocr in lineC, need loc of next primitive
        for(j=0; j<10; j++)
        { if(cdp[j]==*fnc)cfc++;
          if(cfc==ocr)break; }                 //next primitive to be executed is cdp[j+1]
        for(jj=i-1; jj>0; jj--) if(lineC[jj]==cdp[j+1])break;
        O("lineC: %s\n",lineC);
        O("i: %lld   j: %lld   jj: %lld\n",i,j,jj);
        appender(a,n,lineC,jj+1); } }
    O("1st *a: %s\n",*a);

Note in the 3rd line: s[0]==':' which is exactly what we have.

If we comment out that complete "if clause" kona we get:

[tom@localhost kona]$ rlwrap -n ./k
kona      \ for help. \\ to exit.

  :6 `"quote.csv"
rank error
>  :6 `"quote.csv"
rank error
>>  :6 `"quote.csv"
rank error
>>>  :6 `"quote.csv"
rank error
>>>>  \
>>>  \
>>  \
>  \

which is exactl what we want. This begs the question: Why is this "if clause" there?

tavmem commented 2 years ago

Leaving the "if clause" commented out, the full set of tests pass:

[tom@localhost kona]$ rlwrap -n ./k_test
t:0
t:50
t:100
t:150
t:200
t:250
t:300
t:350
t:400
t:450
t:500
t:550
t:600
t:650
t:700
t:750
t:800
t:850
t:900
t:950
t:1000
t:1050
t:1100
Test pass rate: 1.0000, Total: 1134, Passed: 1101, Skipped: 33, Failed: 0, Time: 0.396991s
OK
kona      \ for help. \\ to exit.

But, the "if clause" was put in for some reason. The next step is to examine history (when it was added) to find out why.

tavmem commented 2 years ago

The "if clause" was introduced and developed in Nov, 2019 to address issues 566, 567, 569 and 570, all related to resume. So ... the next step is to identify what is unique about the current issue & to create a test to skip the contents of the "if clause".