You are not logged in.
Pages: 1
Hi,
just updated to the last and greatest mORMot from git, from a while ago.
A strange behaviour is hitting me. I tracked down the issue to the method
TDynArrayHashed.HashAdd(const Elem; aHashCode: Cardinal; var result: integer);
var n,cap: integer;
begin
n := Count;
SetCount(n+1); // reserve space for a void element in array
cap := Capacity;
if cap*2-cap shr 3>=fHashsCount then begin
// fHashs[] is too small -> recreate
ReHash;
result := HashFind(aHashCode,Elem); // fHashs[] has changed -> recompute
assert(result<0);
end;
with fHashs[-result-1] do begin // HashFind returned negative index in fHashs[]
Hash := aHashCode;
Index := n;
end;
result := n;
end;
I do not use this class direclty, it is used by SynDB since I'm connecting to a SQL Server 2008 to access axtrernal data.
in my findings when the statement
n := Count;
sets n to zero, fHashs is not properly allocated, thus resulting in an AV when the statement
with fHashs[-result-1] do begin // HashFind returned negative index in fHashs[]
Hash := aHashCode;
executes.
I temporarily solved commenting out the check
//if cap*2-cap shr 3>=fHashsCount then begin
and thus always executing ReHash;
Of course in this way all your speed optimizations are gone with the problem
Verified with XE4/XE7 targeting win32, under Win7 64 bit.
I'm sorry but I was not able to better track the 'root' issue, I suspect this is only a consequance effect of something more deep.
If you need more details I'm here to help.
Offline
How is Count reset to 0 in your case?
Sound like if fHashCount is > 0 whereas Count = 0 in your case.
I was not able to reproduce it here.
HashAdd() should always be predecessed by a HashFind() call, which set the proper result value.
What is the call stack from SynDB?
Are you using the latest revision of the framework?
Offline
Hi ab,
here is the call stack:
SynCommons.TDynArrayHashed.HashAdd((no value),102850746,-1)
SynCommons.TDynArrayHashed.FindHashedForAdding((no value),True,102850746)
SynCommons.TDynArrayHashed.AddAndMakeUniqueName('ID')
SynOleDB.TOleDBStatement.BindColumns(Pointer($3B97368) as IColumnsInfo,$2D4C880,((0, 0, 0, 0, nil, nil, nil, 0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, nil, nil, nil, 0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, nil, nil, nil, 0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, nil, nil, nil, 0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, nil, nil, nil, 0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, nil, nil, nil, 0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, nil, nil, nil, 0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, nil, nil, nil, 0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, nil, nil, nil, 0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, nil, nil, nil, 0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, nil, nil, nil, 0, 0, 0, 0, 0, 0, 0, 0)))
SynOleDB.TOleDBStatement.FromRowSet(Pointer($3B97360) as IRowset)
SynOleDB.TOleDBStatement.ExecutePrepared
SynDB.TSQLDBConnectionProperties.Execute('SELECT F.ID, F.DESCRIZIONE, F.IDPADRE, F.TITOLOFORM, F.ABILITATO, F.ID_CMTMODULI,PROF.bAbilitaInsert, PROF.bAbilitaEdit, PROF.bAbilitaDelete,MENU.FUNZIONE, MENU.NOME_ICONA FROM CMTFUNZIONI F JOIN SYS_FUNZIONI_HTML5 MENU ON F.ID = MENU.ID_CMTFUNZIONI LEFT OUTER JOIN CMTFUNZIONI PADRE ON F.IDPADRE = PADRE.ID JOIN CMTMODULI ON F.ID_CMTMODULI = CMTMODULI.ID JOIN CMTEXPROFILIFUNZIONI PROF ON PROF.ID_CMTFUNZIONI = F.ID OR Prof.ID_CMTFUNZIONI=0 JOIN CMTEXUTENTIPROFILI C ON Prof.ID_CMTEXPROFILIUTENTE = C.ID_CMTEXPROFILIUTENTE JOIN CMTUTENTI U ON C.ID_CMTUTENTI = U.ID WHERE U.ID=? AND ((F.ID_CMTMODULI=? AND F.VISIBILE=''T'') OR ( F.VISIBILE=''F'' AND F.ABILITATO=''F'' AND F.EXE_PARAMS=''HTML5'' )) ORDER BY PADRE.INDICE, F.INDICE',(...),nil,False)
BFiveService.UtenteService.TUtenteService.Profilo($30C5278,$2E214F0,$30D4F10)
The framework is updated at Now()
The statement in my code that originates the problem is something like
Qry := ConnectionProperties.Execute(SQLText, [User.ID_CMTUTENTI, ModuleID]);
The statement is used in a loop, executed a few times with differents parameter's values
Offline
Pages: 1