Posted: Sun Nov 09, 2014 5:11 am Post subject:
Access violation at address 00405AFA
Subject description: 3.38 Beta 14 (3.37.99.014)
The crash happens every time when closing. It aborts closing, so only Task Manager can end the tool.
Error stemming from FormMain.pas line 1574:
Code:
for count := 0 to (MaxOpenFiles - 1) do
BlockWriteString(F,OpenFilesList[count]);
If MaxOpenFiles is 0, which it is in my case, this is decremented to become non-zero. This will make the initial check pass because MaxOpenFiles is an unsigned word and decrementing 0 makes it the largest value. Thus, the loop will run, and there is no data. This causes 0 to be dereferenced.
The stickied topic says I shouldn't post suggestions here, but I suggest this :
Code:
for count := 1 to MaxOpenFiles do
BlockWriteString(F,OpenFilesList[count - 1]);
Similar potential issues in lines 1260, 1367, 1389, 1411, 1433, 1460, and 1487. Haven't checked other files. _________________ QUICK_EDIT
Also Known As: banshee_revora (Steam) Joined: 15 Aug 2002 Location: Brazil
Posted: Sun Nov 09, 2014 9:58 am Post subject:
if MaxOpenFiles = 0, this for does not execute at all.
It will not make the initial check pass. It would do if instead of:
Code:
for count := 0 to (MaxOpenFiles - 1) do
I had:
Code:
for count := 0 downto (MaxOpenFiles - 1) do
I do not underestimate your Access Violation here, but I'm just not sure if this is really the reason behind it.... unless Delphi processes (MaxOpenFiles - 1) as a longword and in this case -1 becomes a very high number. QUICK_EDIT
if MaxOpenFiles = 0, this for does not execute at all.
It only appears like that. But it does.
count is a word, MaxOpenFiles is a word. 0x0 - 0x1 = 0xffff. This is compared to the initial value (:= 0) to see whether the loop should execute. It cannot be below, because no unsigned value can be less than 0. If it's higher, the loop executes, and if it's equal to 0, it will also execute, even if only once (which is once more than there is data available). It will always execute.
Assembler ahead! This is the real compiled code:
Code:
movzx esi, word ptr [ebx+MaxOpenFiles] // copy to esi and make the word a longword
dec esi // subract one. esi is now (MaxOpenFiles - 1)
test si, si // test the *word* part of esi. this is like doing "test MaxOpenFiles-1"
// if MaxOpenFiles was 0, si will be 0xffff now...
jb Done // jumps if si (the lower word of esi) is *below 0*, which
// is impossible. so, no jump.
.... process items here or crash ....
Done:
Technical stuff time!
JB jumps if the tested or compared values are less than 0. This is checked using a flag in the processor called CF. If CF=1 then it jumps, if CF=0, then it doesn't. The TEST instruction by design always sets CF=0. Always. This conditional jump is guaranteed to *never* jump. That's how the x86 works.
Banshee wrote:
I do not underestimate your Access Violation here, but I'm just not sure if this is really the reason behind it.... unless Delphi processes (MaxOpenFiles - 1) as a longword and in this case -1 becomes a very high number.
I have limited knowledge of the language and the source code, but I think you do . This error has been there since the first revision available in SVN, and a forum search shows many incarnations with different addresses for different compiled version, but I suspect it's always the same one. It always crashes for me when closing, but altering it like I described made it go away. I'm fairly certain this is the cause.
Code:
for count := 0 downto (MaxOpenFiles - 1) do
I don't know Pascal, but this should not execute for anything other than MaxOpenFiles = 1. _________________ QUICK_EDIT
You can post new topics in this forum You can reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum