Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.05.18;
Скачать: CL | DM;

Вниз

Почемуто переменная сама меняется :(   Найти похожие ветки 

 
andreil ©   (2008-04-16 10:20) [0]

Процедура, в которой собственно идет ошибка:
function TGcf.ValidateItemInternal(const Item: ulong): TValidation;
var
 _Checksum: ulong;
 buf: array of byte;
 bufSize: ulong;
 ReadSize, ReadingSize, RSize, ReadPos, n, CheckNum, CheckOffs, i: ulong;
begin
 result:=HL_VALIDATES_OK;
 bufSize:=lpDirectoryEntries[Item].ItemSize;
 SetLength(buf, HL_GCF_CHECKSUM_LENGTH);
 Self.BuildFileInfo(Item, @Self.SectorsTable);
 i:=0;
 ReadingSize:=BUFFER_SIZE;
 RSize:=0;
 CheckNum:=0;
 CheckOffs:=0;
 repeat
     if Exit_ then
       Exit;
     ReadSize:=0;
     for n:=i to length(SectorsTable[Item])-1 do
     begin
       inc(ReadSize, BUFFER_SIZE);
       ReadingSize:=BUFFER_SIZE;
       ReadPos:=pDataBlockHeader.FirstSectorOffset+
        (pDataBlockHeader.PhysicalSectorSize*SectorsTable[Item][n]);
       if ReadSize+RSize>=lpDirectoryEntries[Item].ItemSize then
       begin
         ReadingSize:=lpDirectoryEntries[Item].ItemSize-RSize-ReadSize+BUFFER_SIZE;
         ReadSize:=ReadSize-BUFFER_SIZE+ReadingSize;
       end;
       GcfStream.Seek(ReadPos, spBegin);
       GcfStream.Read(buf[CheckNum*BUFFER_SIZE], ReadingSize);
       inc(CheckNum);
       if CheckNum=4 then
       begin
         CheckNum:=0;
         _Checksum:=Checksum(@buf[0], HL_GCF_CHECKSUM_LENGTH);
         if _checksum<>Self.lpChecksumEntries[lpChecksumMapEntries[Self.lpDirectoryEntries[I tem].ChecksumIndex].FirstChecksumIndex+CheckOffs].Checksum then
         begin
           result:=HL_VALIDATES_INCOMPLETE;
           Exit;
         end;
         inc(CheckOffs);
       end;
       if (ReadSize=BUFFER_SIZE*64) or (n=(length(SectorsTable[Item])-1)) then
       begin
         break;
       end;
     end;
     i:=n+1;
     inc(RSize, ReadSize);
   until i>=length(SectorsTable[Item]);
end;

Проблема заключается в том, что при чтении одного из потока переменная CheckNum произвольно меняется :(
В чем может быть проблема?
Да, меняется переменная не при первом чтении, а где-то после 5-7.


 
Сергей М. ©   (2008-04-16 10:24) [1]

Что показывает отладчик ?


 
Семеныч   (2008-04-16 10:26) [2]

Можно поставить точку останова на изменение переменной.


 
palva ©   (2008-04-16 10:44) [3]

Может переполнение буфера? Неправильно вычисляем размер чтения.


 
andreil ©   (2008-04-16 11:10) [4]

Отладчик показывает, что до чтения зачение было менее 4, а после чтения зашкалило за 100000.
Переполнения буфера нету, тк если убрать все, что относится к вычислению КС, те блок
inc(CheckNum);
      if CheckNum=4 then
      begin
        CheckNum:=0;
        _Checksum:=Checksum(@buf[0], HL_GCF_CHECKSUM_LENGTH);
        if _checksum<>Self.lpChecksumEntries[lpChecksumMapEntries[Self.lpDirectoryEntries[I  tem].ChecksumIndex].FirstChecksumIndex+CheckOffs].Checksum then
        begin
          result:=HL_VALIDATES_INCOMPLETE;
          Exit;
        end;
        inc(CheckOffs);
      end;

то никаких ошибок нету, да и читает правильно...


 
Сергей М. ©   (2008-04-16 11:25) [5]

Значит проблема здесь:

> GcfStream.Read(buf[CheckNum*BUFFER_SIZE], ReadingSize);


Контролируй выход за пределы буфера.


 
andreil ©   (2008-04-16 11:30) [6]

Сделал так:
1) убрал расчет КС из самого чтения.
2) вынес его в конец процедуры.
В итоге файл читается нормально, что доказал сброс дампа на диск с его сверкой (1 к 1 с оригиналом). Значит, чтение нормально.
Расчет КС получился таков:
 for i:=0 to lpChecksumMapEntries[Self.lpDirectoryEntries[Item].ChecksumIndex].ChecksumCount-1 do
 begin  
   _Checksum:=Checksum(@buf[i*HL_GCF_CHECKSUM_LENGTH], HL_GCF_CHECKSUM_LENGTH);
   if _checksum<>Self.lpChecksumEntries[lpChecksumMapEntries[Self.lpDirectoryEntries[I tem].ChecksumIndex].FirstChecksumIndex+i].Checksum then
   begin
     result:=HL_VALIDATES_INCOMPLETE;
     Exit;
   end;
 end;

В итоге, при одном из обращний к буфферу выскакивает ошибка. Причем номер этого обращения колеблется (первый раз было 3, сейчас 1).
Что за фигня?

ЗЫ: Сам расчет КС находится в С++ ДЛЛке, откуда и вызавается. Все, что имеет отношение к этому вызову, расписано правильно, тк иначе при первом же обращении вылазилабы ошибка.


 
Сергей М. ©   (2008-04-16 11:38) [7]


> при одном из обращний к буфферу выскакивает ошибка


Какая конкретно - это военная тайна ?


 
andreil ©   (2008-04-16 11:53) [8]

Все, уже не выскакивает :) Перевел эту ДЛЛку на дельфи. благо, там только две функции (Adler32 & CRC32). Помощь больше не нужна ;)


 
Сергей М. ©   (2008-04-16 11:56) [9]

Полагаю, dll здесь была ни причем.


 
han_malign ©   (2008-04-16 13:24) [10]


> Полагаю, dll здесь была ни причем.

- ну почему же - если в DLL Checksum() объявлена как stdcall, а в программе как cdecl, то на 4-м проходе(if CheckNum=4) после вызова Checksum указатель стека сдвигается на лишних 8-мь байт, и в аккурат на 5-ом проходе при GcfStream.Seek и GcfStream.Read как раз на место CheckNum и попадает адрес возврата...

> Все, что имеет отношение к этому вызову, расписано правильно,
>  тк иначе при первом же обращении вылазилабы ошибка.

- ну-ну, стек и не такое стерпит... до поры - до времени...


 
Сергей М. ©   (2008-04-16 13:27) [11]


> если в DLL Checksum() объявлена как stdcall, а в программе
> как cdecl


То это точно не проблема dll, это проблема автора, проставившего соглашение от балды)



Страницы: 1 вся ветка

Текущий архив: 2008.05.18;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.022 c
15-1207059668
asdf2
2008-04-01 18:21
2008.05.18
Есливставить вторую видюху и подключить ко второму монитору


2-1208611624
Алексей К.
2008-04-19 17:27
2008.05.18
получение имен в TStringList


2-1208127399
HF-Trade
2008-04-14 02:56
2008.05.18
Размер файла в сети


4-1188934685
SKIPtr
2007-09-04 23:38
2008.05.18
Как выполнить действия при сворчивании


11-1189391943
Grademax
2007-09-10 06:39
2008.05.18
Обработка клавиш Up, Down в ListEdit е