Author Topic: [Solved] A problem with a Terminal  (Read 5245 times)

0 Members and 1 Guest are viewing this topic.

Offline Axenntio

  • LV3 Member (Next: 100)
  • ***
  • Posts: 41
  • Rating: +3/-0
    • View Profile
[Solved] A problem with a Terminal
« on: June 09, 2014, 11:23:17 am »
Hi Omnimaga !
I make a little terminal (juste for me :P and for practice)
And I have a bug...

I have this code, the bug comme from the COUT routine, L1 have all the chars of the command:
Code: [Select]
.TERMINAL
Fix 5
Fix 3
0->A->B
[1F5F1F5F5FFFFFFF1FDF1F5F1FFFFFFF1F5F5F5F1FFFFFFF]->Pic0
"WRMH  ?thetaVQLG  :ZUPKFC  YTOJEB  XSNIDA"->GDB0
"wrmh  !thetavqlg  :zupkfc  ytojeb  xsnida"->GDB00
"][ pi  '369)   .258(   0147,          "->GDB000
""->Str0
ref(0,0,96,64
Lbl Main
Repeat getKey(15)
    getKey->K
    If K=1
        B->A
        For(theta,0,A)
            {Str0+theta}->{L1+theta}
        End
    End
    If K=9 and (A!=0)
        A->B
        For(theta,0,A)
            {L1+theta}->{Str0+theta}
        End
        COUT(L1,1)
        COUT("Unknow command",1)
        0->A
    End
    Pt-Off(92,1,Pic0+(M*
    If K=48
        M=1?0->M,1->M
        While K=48
            getKey->K
        End
    End
    If K=54
        M=2?0->M,2->M
        While K=54
            getKey->K
        End
    End
    If K=56 and (A!=0)
        ref(1,57,96,7
        DispGraph
        A--
    End
    If K=15
        ref(1,56,94,7
        DispGraph
        0->A
        While K=15
            getKey->K
        End
    End
    If A<22
        If K>10 and (K<48)
            If M=0
                If {K+GDB0-11}->C
                    C->{A+L1}
                    A++
                End
            ElseIf M=1
                If {K+GDB00-11}->C
                    C->{A+L1}
                    A++
                End
            ElseIf M=2
                If {K+GDB000-11}->C
                    C->{A+L1}
                    A++
                End
            End
        End
    End
    0->{A+L1}
    Text(1,57,L1
    DispGraph
End
Fix 4
Fix 2
Return

Lbl COUT
    If {r2}=1
        ref(1,57,96,7
        Text(1,57,{r1}
    ElseIf {r2}=2
        ref(1,57,96,7
        Text(1,57,{r1}>Frac
    ElseIf {r2}=3
        ref(1,57,96,7
        Text(1,57,{r1}>Dec
    End
    For(theta,0,5)
        Vertical -
        ref(0,63,96,1)
        Pause 5
        DispGraph
    End
Return

http://gyazo.com/a351dd062b0e1ac7321888d12943f562

Normaly, the code output the command (here "HELP") and after "Unknow command" when I press ENTER key.
But see... He output "HELP" and after "ELP"...

(Test on wabbitemu and TI83+USB)
I think the problem come from the COUT routine but... I don't know where is the mistake(s)...

Thank you for the future help :3
« Last Edit: June 09, 2014, 01:37:36 pm by Axenntio »

Offline shmibs

  • しらす丼
  • Administrator
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2132
  • Rating: +281/-3
  • try to be ok, ok?
    • View Profile
    • shmibbles.me
Re: A problem with a Terminal
« Reply #1 on: June 09, 2014, 11:42:06 am »
i don't have time to actually look this over, as i'm running off to school right now, but here it is with whitespace:
Code: [Select]
.TERMINAL

Fix 5
Fix 3

0->A->B
[1F5F1F5F5FFFFFFF1FDF1F5F1FFFFFFF1F5F5F5F1FFFFFFF]->Pic0
"WRMH  ?thetaVQLG  :ZUPKFC  YTOJEB  XSNIDA"->GDB0
"wrmh  !thetavqlg  :zupkfc  ytojeb  xsnida"->GDB00
"][ pi  '369)   .258(   0147,          "->GDB000
""->Str0
ref(0,0,96,64

Lbl Main

Repeat getKey(15)

getKey->K

If K=1
B->A

For(theta,0,A)
{Str0+theta}->{L1+theta}
End
End

If K=9 and (A!=0)
A->B

For(theta,0,A)
{L1+theta}->{Str0+theta}
End
COUT(L1,1)
COUT("Unknow command",1)
0->A
End

Pt-Off(92,1,Pic0+(M*8)

If K=48
M=1?0->M,1->M

While K=48
getKey->K
End
End

If K=54
M=2?0->M,2->M

While K=54
getKey->K
End
End

If K=56 and (A!=0)
ref(1,57,96,7
DispGraph
A--
End

If K=15
ref(1,56,94,7
DispGraph
0->A

While K=15
getKey->K
End
End

If A<22

If K>10 and (K<48)

If M=0
If {K+GDB0-11}->C
C->{A+L1}
A++
End
ElseIf M=1
If {K+GDB00-11}->C
C->{A+L1}
A++
End
ElseIf M=2
If {K+GDB000-11}->C
C->{A+L1}
A++
End
End
End
End

0->{A+L1}
Text(1,57,L1
DispGraph
End

Fix 4
Fix 2

Return

Lbl COUT

If {r2}=1
ref(1,57,96,7
Text(1,57,{r1}
ElseIf {r2}=2
ref(1,57,96,7
Text(1,57,{r1}>Frac
ElseIf {r2}=3
ref(1,57,96,7
Text(1,57,{r1}>Dec
End

For(theta,0,5)
Vertical -
ref(0,63,96,1)
Pause 5
DispGraph
End

Return

Offline Runer112

  • Project Author
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2289
  • Rating: +639/-31
    • View Profile
Re: A problem with a Terminal
« Reply #2 on: June 09, 2014, 01:19:13 pm »
I can't definitively say that this is the only factor causing the issue, but I do definitely see a large factor:

Code: [Select]
""->Str0

Due to the challenges and costs that would be entailed by dynamic memory allocation, strings and other data types that might seem like they should be dynamically sized are in fact not. They will only have as much space available as you allocate for them.

In this case, you've allocated enough memory for a string of length zero (which is actually one byte, due to the zero byte that marks the end of the string). As you can imagine, this is not particularly useful, and as soon as you start trying to "append" to this string, you start overwriting whatever comes after it in memory. If you try to "append" the string "HELP", the 'H' will overwrite the zero byte that marks the end of the string, and the characters 'E', 'L', and 'P' will overwrite whatever three bytes come next in memory. In this case, they happen to be the next three bytes of data in your program: the first three bytes of the string "Unknow command" (Side note: the correct spelling is "unknown"). So when you later try to print that string, the first three bytes have been overwritten with "ELP" and that's what you see.

The usual way to fix this is to allocate a fixed size for the string buffer ahead of time (and don't allow the string to go over that size). There are three primary options:
  • Allocate the buffer inside the program with something like Buff(256)→Str0. Note that this will not work if you compile your code as an application, and that Buff( is really the det( token renamed.
  • Allocate the buffer externally by using a free static RAM reference like L1 in place of Str0, or make Str0 refer to the reference, like L1→Str0. As long as you can find the free RAM space for it, this is generally the preferred option. Note that you do not perform any active allocation; the "allocation" simply entails making a note that nothing else should be trying to use that area of RAM at the same time.
  • Allocate the buffer externally by asking the OS to allocate space for the buffer at runtime, like GetCalc("tmpBUF",256)→S. Note that since this is allocated at runtime, you have to save the reference in a variable instead of a static pointer like Str0. This may also fail if the space cannot be allocated due to not having enough free user RAM (in which case S will be zero), a problem which does not affect the other two options. tmp is really the w token (2nd+9), added in Axe 1.2.0, which results in the variable automatically being deleted when your program finishes.

If you want a dynamically-sized string, you can do that by either storing it in an OS variable and resizing it, or using the OS edit buffer. Both are much more complicated options, and unless you absolutely cannot use a fixed-size buffer, I would steer clear of them for now.

And a helpful reminder: in all of these cases, make sure the string always ends in a zero byte before you try to perform any operations like display or length(), or the results could be quite unexpected!
« Last Edit: June 09, 2014, 01:25:52 pm by Runer112 »

Offline Axenntio

  • LV3 Member (Next: 100)
  • ***
  • Posts: 41
  • Rating: +3/-0
    • View Profile
Re: A problem with a Terminal
« Reply #3 on: June 09, 2014, 01:37:17 pm »
Buff(22)->Str0
Correctly fix the issue !
Thanks you a lot Runner112 ! Problem solved ! :3

Offline Eeems

  • Mr. Dictator
  • Administrator
  • LV13 Extreme Addict (Next: 9001)
  • *************
  • Posts: 6265
  • Rating: +318/-36
  • little oof
    • View Profile
    • Eeems
Re: [Solved] A problem with a Terminal
« Reply #4 on: June 09, 2014, 02:17:44 pm »
And a helpful reminder: in all of these cases, make sure the string always ends in a zero byte before you try to perform any operations like display or length(), or the results could be quite unexpected!
But buffer overflows are fun!

That aside, have you ever thought about writing some advanced documentation on how Axe works at a lower level? I'm sure many people would find the deeper knowledge they could glean from that quite useful.
/e

Offline Runer112

  • Project Author
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2289
  • Rating: +639/-31
    • View Profile
Re: [Solved] A problem with a Terminal
« Reply #5 on: June 09, 2014, 02:42:30 pm »
And a helpful reminder: in all of these cases, make sure the string always ends in a zero byte before you try to perform any operations like display or length(), or the results could be quite unexpected!
But buffer overflows are fun!

That aside, have you ever thought about writing some advanced documentation on how Axe works at a lower level? I'm sure many people would find the deeper knowledge they could glean from that quite useful.

That sounds like it would take a lot of time and effort, which is probably why I haven't ever thought about doing it. :P But I tend to leave these mega-posts in lots of question topics, going way more in depth than was asked. Maybe all of my mega-posts could be compiled into some semblance of what you describe.

Offline Eeems

  • Mr. Dictator
  • Administrator
  • LV13 Extreme Addict (Next: 9001)
  • *************
  • Posts: 6265
  • Rating: +318/-36
  • little oof
    • View Profile
    • Eeems
Re: [Solved] A problem with a Terminal
« Reply #6 on: June 09, 2014, 04:35:18 pm »
And a helpful reminder: in all of these cases, make sure the string always ends in a zero byte before you try to perform any operations like display or length(), or the results could be quite unexpected!
But buffer overflows are fun!

That aside, have you ever thought about writing some advanced documentation on how Axe works at a lower level? I'm sure many people would find the deeper knowledge they could glean from that quite useful.

That sounds like it would take a lot of time and effort, which is probably why I haven't ever thought about doing it. :P But I tend to leave these mega-posts in lots of question topics, going way more in depth than was asked. Maybe all of my mega-posts could be compiled into some semblance of what you describe.
Somebody should do that :P
/e

Offline Runer112

  • Project Author
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2289
  • Rating: +639/-31
    • View Profile
Re: [Solved] A problem with a Terminal
« Reply #7 on: June 09, 2014, 05:23:21 pm »
And a helpful reminder: in all of these cases, make sure the string always ends in a zero byte before you try to perform any operations like display or length(), or the results could be quite unexpected!
But buffer overflows are fun!

That aside, have you ever thought about writing some advanced documentation on how Axe works at a lower level? I'm sure many people would find the deeper knowledge they could glean from that quite useful.

That sounds like it would take a lot of time and effort, which is probably why I haven't ever thought about doing it. :P But I tend to leave these mega-posts in lots of question topics, going way more in depth than was asked. Maybe all of my mega-posts could be compiled into some semblance of what you describe.
Somebody should do that :P

* Runer112 looks around, seeing nobody and realizing that that somebody is probably himself x.x