#1 2013-03-13 17:30:38

chapa
Member
Registered: 2012-04-30
Posts: 117

function TSQLRestServerStaticInMemory.EngineDeleteWhere - AV

Accessing object data inside TSQLRestServerStaticInMemory.EngineDeleteWhere is not protected with Lock/UnLock.
This leads to AV in heavy usage of TSQLRestServerStaticInMemory including Delete.

Offline

#2 2013-03-13 18:20:45

chapa
Member
Registered: 2012-04-30
Posts: 117

Re: function TSQLRestServerStaticInMemory.EngineDeleteWhere - AV

Here is the scenario.

I have two threads.
1 thread: doing RestClient.Retrieve and if not found RestClient.Add for StaticInMemory
2 thread. doing RestClient.Delete

Retrieve() is done by searching for int64 stored false hashed property.
Delete() is done by sqlrecord id

when 2nd thread delete a record and 1st thread try to retrieve and than add same record values following stack trace happens after many iterations:

20130313 20083522 EXCOS 	EAccessViolation (C0000005) at 00174C79 mORMot.GetInt64Prop (10718)  stack trace 00009A3C System.@NewAnsiString 000058D6 System.@FreeMem 00184CF2 mORMot.TSQLRestClientURI.ExecuteList (20431) 0000A2F6 System.@LStrCat 0018524B mORMot.TSQLRestClientURI.InternalListJSON (20567) 001834BF mORMot.TSQLRest.Retrieve (19526) 00183687 mORMot.TSQLRest.Retrieve (19589)
...
20130313 20083736 EXC   	ESynException ("HashInit found dup") at 0015F278 SynCommons.TObjectHash.HashInit (21350)  stack trace 0000A448 System.@LStrCatN 00186D8A mORMot.TSQLRestClientURI.EngineAdd (21115) 0019105E mORMot.TSQLRestClient.Add (25307)
...

code line numbers may differ from official source codes in mormot units.

Tried to Lock/Unlock EngineDeleteWhere, but no success.

Offline

#3 2013-03-13 19:24:38

chapa
Member
Registered: 2012-04-30
Posts: 117

Re: function TSQLRestServerStaticInMemory.EngineDeleteWhere - AV

After some debugging I am here

In TSQLRestServerStaticInMemory.FindWhereEqual (at the time when EngineDeleteWhere occur):
1. TSQLRestServerStaticInMemory.FindWhereEqual: ndx := Find(fSearchRec)
2. TObjectHash.Find():   result := HashFind(Hash(Item),Item);
3. TObjectHash.HashFind:  if fHashs=nil then HashInit(Count);
4. TObjectHash.HashInit:     
      O := Get(i); <-- return nil
      H := Hash(O); //Hash on nil object
5. TListFieldHash.Hash(nil):   result := fProp.GetHash(Item,CaseInsensitive); <-- here AV occur on nil object

Offline

#4 2013-03-13 19:46:40

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 13,192
Website

Re: function TSQLRestServerStaticInMemory.EngineDeleteWhere - AV

Such multi thread process was not fully tested.

In fact, remote RESTful access is thread safe, but such direct calls may not be protected.

We have created the following ticket:
http://synopse.info/fossil/info/28545a4ce0

Thanks for the report.

Offline

Board footer

Powered by FluxBB