Shop OBEX P1 Docs P2 Docs Learn Events
Memory Storage Management - bug??? — Parallax Forums

Memory Storage Management - bug???

GaylanGaylan Posts: 3
edited 2013-03-29 08:54 in Propeller 1
I am getting wierd results when I use "ES" as the Key to store a string.
When I use "Es" or any other character such as "E1" it works properly.

These are the values I write, followed by those read back.

______________________________________________________________________
MemWriteAll

Key : Data
SE!!!!!! : SE,0,0,0,0,2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Code: -1
VI!!!!!! : VI,0,50,50!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Code: -1
F0!!!!!! : F0,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Code: -1
F1!!!!!! : F1,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Code: -1
F2!!!!!! : F2,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Code: -1
F3!!!!!! : F3,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Code: -1
F4!!!!!! : F4,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Code: -1
F5!!!!!! : F5,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Code: -1
PT!!!!!! : PT,NNNNNNNNNNNNNNNNNNNNNNNNNNNNNN,1000!!!!!!!!! Code: -1
ES!!!!!! : ES,50,50,150,100,50,100,0,1,150,150!!!!!!!!!!!! Code: -1
Free Table Entries: 1014
Free Name Space: 16224
Free Data Space: 7647

MemReadAll

Full list of names: 10
F3!!!!!! : F3,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
F5!!!!!! : F5,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
F4!!!!!! : F4,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
SE!!!!!! : SE,0,0,0,0,2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
PT!!!!!! : PT,NNNNNNNNNNNNNNNNNNNNNNNNNNNNNN,1000!!!!!!!!!
F0!!!!!! : F0,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
F1!!!!!! : F1,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
VI!!!!!! : VI,0,50,50!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
F2!!!!!! : F2,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ES!!!!!! : F2,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

_____________________________________________________________________
When I change the key "ES" to "Es" it works properly.

MemWriteAll

Key : Data
SE!!!!!! : SE,0,0,0,0,2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Code: -1
VI!!!!!! : VI,0,50,50!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Code: -1
F0!!!!!! : F0,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Code: -1
F1!!!!!! : F1,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Code: -1
F2!!!!!! : F2,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Code: -1
F3!!!!!! : F3,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Code: -1
F4!!!!!! : F4,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Code: -1
F5!!!!!! : F5,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Code: -1
PT!!!!!! : PT,NNNNNNNNNNNNNNNNNNNNNNNNNNNNNN,1000!!!!!!!!! Code: -1
Es!!!!!! : Es,50,50,150,100,50,100,0,1,150,150!!!!!!!!!!!! Code: -1
Free Table Entries: 1014
Free Name Space: 16224
Free Data Space: 7647

MemReadAll

Full list of names: 10
Es!!!!!! : Es,50,50,150,100,50,100,0,1,150,150!!!!!!!!!!!!
F3!!!!!! : F3,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
F5!!!!!! : F5,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
F4!!!!!! : F4,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
SE!!!!!! : SE,0,0,0,0,2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
PT!!!!!! : PT,NNNNNNNNNNNNNNNNNNNNNNNNNNNNNN,1000!!!!!!!!!
F0!!!!!! : F0,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
F1!!!!!! : F1,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
VI!!!!!! : VI,0,50,50!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
F2!!!!!! : F2,80,80,0,0,100!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

_______________________________________________________________
This is the code creating the string for "ES"

Pri MemSaveEStim1
MemClearVars 'I clear the variable strings using ByteFill and set them to "!" so they display easily
Tx[0]:="E"
TxPtr.byte:=1
Tx[TxPtr++]:="S" 'This is where I can change the "S" to "s" or "1" or "2" or anything else that I have tested!
Tx[TxPtr++]:=","
ByteMove(@StrKey,@Tx,2)
RF.str(@StrKey)
RF.str(String(" : "))
DecToString(EStimStart)
Tx[TxPtr++]:=","
DecToString(EStimEnd)
Tx[TxPtr++]:=","
DecToString(EStimFreq1)
Tx[TxPtr++]:=","
DecToString(EStimFreq2)
Tx[TxPtr++]:=","
DecToString(EStimPower1)
Tx[TxPtr++]:=","
DecToString(EStimPower2)
Tx[TxPtr++]:=","
DecToString(EStimOn)
Tx[TxPtr++]:=","
DecToString(EStimPolarity)
Tx[TxPtr++]:=","
DecToString(EStimPW1)
Tx[TxPtr++]:=","
DecToString(EStimPW2)
'Tx[TxPtr]:=0
ByteMove(@StrData,@Tx,TxPtr)
RF.str(@Tx)
RF.str(String(" Code: "))
RF.dec(MEM.Create_Str(@StrKey,@StrData))
RF.Str(string(RF#NL,RF#LF))

Return

_________________________________________________________
It does the same thing if I use
MEM.Edit_Create_Str(@StrKey,@StrData)

I have tried changing locations in EProm, as well as the welterweight module.

For now, I will just change to a "s" so I can finish my project.

If anyone wants more code, email me. Gaylan@WardOffice.com

Thanks,

Gaylan

Comments

  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2013-03-28 09:35
    I'm the author of that object. It would help if you used some [ code] [ /code] tags. Or if you attach the complete program, I can definitely try to help. It's really hard to follow what's happening by what you posted.

    EDIT: I just did a quick test with a value name of "ES" and nothing special seemed to happen, but I would like to understand how you encountered the bug some more to try to replicate it.
    EDIT2: I think I see what is happening, "ES" and "F2" both produce the same hash/checksum (but it should know that and still not mess up), so it does appear to be a bug, let me try some more things.
    EDIT3: I just did another simple test of storing to both "ES" and "F2" and it calls the values back correctly. I'm going to need a copy of your program to continue...

    What version of MSM are you using?
  • GaylanGaylan Posts: 3
    edited 2013-03-28 10:24
    Here is my test program. It should show the problem using the standard Parallax Serial Terminal and default settings for your MEMORY_STORE.
    Thanks for responding. You wrote a great EProm storage program! Thanks! -Gaylan
    MemTest.spin
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2013-03-28 11:41
    OK, I have a fix, but I don't have a reason. Maybe someone can help me on this (seems unlikely -- maybe I'll post another thread). The name string was getting overwritten when a specific read was being performed, and so the test to make sure that the address was correct was always returning true. Anyway, all you have to do is replace the existing getaddr method with this one:
    PRI getaddr (nameAddr, tblAddr) | v[2], ptr, ptr2, n[name_size / 4]
    '' return address for an existing entry
    
      name_truncate(nameAddr)
    
      ptr2 := ptr := gethash(nameAddr) 
    
      bytemove(@n, nameAddr, name_size)                     ' for an unknown reason, nameAddr gets overwritten when the read() is called below, so it must be backed up
    
      REPEAT UNTIL (ptr + 2 == ptr2)
        longmove(@v, @table[ptr], 2)
    
        IF (v[0] == 0)
          QUIT
    
        IF (strcomp(read(v[0] >> 16, v.byte[1]), @n))  
          bytemove(tblAddr, @v, 8)
          RETURN ptr                                   
        
        IF ((ptr += 2) => table_size)
          ptr := 0
      
      bytefill(tblAddr, 0, 8)
      RETURN -1
    


    Let me know how that works out for you.
  • GaylanGaylan Posts: 3
    edited 2013-03-28 13:26
    Thanks, that seems to work properly! -Gaylan
  • kuronekokuroneko Posts: 3,623
    edited 2013-03-29 00:03
    Bobb Fwed wrote: »
    OK, I have a fix, but I don't have a reason.
    The display loop calls next_name (calling read which populates val[]). This address is used as is for the call to get_str (calling getaddr which calls read populating/overwriting val[]). I think you can see where this is going. A solution would be to take a private copy of the names returned by next_name & Co before they're fed back into the storage object.
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2013-03-29 08:54
    kuroneko wrote: »
    The display loop calls next_name (calling read which populates val[]). This address is used as is for the call to get_str (calling getaddr which calls read populating/overwriting val[]). I think you can see where this is going. A solution would be to take a private copy of the names returned by next_name & Co before they're fed back into the storage object.
    Ah thank you. That makes perfect sense. I knew it would be some simple mistake like that, because I remember doing extensive testing when I wrote the object to prevent just this problem. But I was doing testing without the name list. I will remove the change I just made, but put a note that says names need to be stored locally before being used to get a value. It is all on the programmer to keep it functional.

    It makes me happy knowing there isn't really a bug, because I rely on this object a lot in day-to-day use, and I just assumed it was working correctly from my previous testing and lack of anomalies. Good to have peace of mind.

    This all brings to light, though, the poorly executed hash/checksum method I have. I didn't spend a whole lot of time on it, and now I think I should spend more time. Collisions like that shouldn't be so common.
Sign In or Register to comment.