Форум: "Прочее";
Текущий архив: 2011.08.28;
Скачать: [xml.tar.bz2];
ВнизКак влияет Range check на работу результирующего кода? Найти похожие ветки
← →
@!!ex © (2011-05-02 20:39) [0]Ситуация:
Есть OGG плеер.
Если установлен Range check в настройках проекта - то все отлично работает.
Если снимаю Range check и пересобираю проект - вместо звука шум.
Естественно проблема где-то в моем коде, но я не могу понять где конкретно...
не плохо было бы понять, как влияет Range check на работу кода, чтобы понять где ошибка.
← →
clickmaker © (2011-05-02 20:45) [1]> как влияет Range check на работу кода
контролирует выход за границы массива. Ошибки это может и не вызвать, но данные в стеке, например, могут быть испорчены
← →
Дмитрий Тимохов (2011-05-02 21:36) [2]ну а может на ERangeError логика построена...
← →
Германн © (2011-05-03 01:10) [3]
> Ситуация:
> Есть OGG плеер.
> Если установлен Range check в настройках проекта - то все
> отлично работает.
> Если снимаю Range check и пересобираю проект - вместо звука
> шум.
>
Не верю!
← →
имя (2011-05-03 12:40) [4]Удалено модератором
← →
@!!ex © (2011-05-03 14:08) [5]> [1] clickmaker © (02.05.11 20:45)
> > как влияет Range check на работу кода
>
> контролирует выход за границы массива. Ошибки это может
> и не вызвать, но данные в стеке, например, могут быть испорчены
Я понимаю для чего сделан Range Check. Я не понимаю как он физически на код влияет.
> ну а может на ERangeError логика построена...
Там С++ либа. Я только методы из нее дергаю.
Соответственно Range Check как-то влияет на мой код, а на поведение либы влиять не может - либу то я не пересобираю.
> Не верю!
Последовательность действий:
ставлю Range check
пересобираю проект
все отлично работает
убираю Range check
пересобираю проект
вместо звука - шум
ставлю Range check
пересобираю проект
все отлично работает
← →
clickmaker © (2011-05-03 14:19) [6]> Я не понимаю как он физически на код влияет
посмотри в отладчике, в CPU window, один и тот же код с выключенным и включенным RC
← →
clickmaker © (2011-05-03 14:29) [7]если кратко, то в код вставляется сравнение текущего значения счетчика с размером массива (либо значения числа с мин/макс значениями), и при выходе за пределы вызывается BoundErr
← →
QAZ (2011-05-03 14:53) [8]какая разница как он работает("обрезает" до границы) ? в любом случае ошибку надо править
проверяй все типы переменых которые передаеш функциям из либы
← →
Sapersky (2011-05-03 15:14) [9]в код вставляется сравнение текущего значения счетчика с размером массива
Ещё Range Check проверяет выход переменных из диапазона (напр., Word - 0..65535).
← →
RWolf © (2011-05-03 15:22) [10]
> Sapersky (03.05.11 15:14) [9]
а не Overflow checking?
← →
Sapersky (2011-05-03 17:34) [11]Range check проверяет при присвоении, например, такой код вылетает:
Var i : Integer;
w : Word;
i := 65536; w := i;
хелп:
The $R directive enables or disables the generation of range-checking code. In the {$R+} state, all array and string-indexing expressions are verified as being within the defined bounds, and all assignments to scalar and subrange variables are checked to be within range. If a range check fails, an ERangeError exception is raised (or the program is terminated if exception handling is not enabled).
Неожиданно, да. Сам недавно включил RC в проекте и потом долго думал, отчего он начал вылетать на ровном месте через два часа работы (счётчик у таймера переполнялся).
Overflow проверяет ещё кое-что дополнительно:
w := 65536; Inc(w);
но если так:
w := 65536; w := w + 1;
то это считается случаем Range Check :)
В общем, разработчики явно рассчитывали на то, что включаться и выключаться будет всё вместе: "The $Q switch is usually used in conjunction with the $R switch".
← →
@!!ex © (2011-05-03 17:46) [12]> какая разница как он работает("обрезает" до границы) ? в
> любом случае ошибку надо править
> проверяй все типы переменых которые передаеш функциям из
> либы
ФИгово, когда не понимаешь что написано?
Я для этого и пытаюсь разобраться как работает range check - чтобы ошибку найти.
потому что я весь код прошерстил и не понимаю что в нем не так.
← →
IPranker © (2011-05-03 18:14) [13]
> @!!ex © (03.05.11 17:46) [12]
Без кода не разобраться. :)
← →
Sha © (2011-05-03 21:57) [14]> @!!ex
Ты так и не сказал, предусмотрена ли у тебя обработка
соответствующей ошибки и не привел кода обработки.
← →
KSergey © (2011-05-04 07:15) [15]Исключения где-либо через try/except отлавливаются?
← →
Думкин © (2011-05-04 07:15) [16]
> KSergey © (04.05.11 07:15) [15]
так в 17-й строке, вестимо.
← →
Sha © (2011-05-04 08:21) [17]Если код чужой, имеет смысл поискать что-нибудь похожее
на самопальный патчер кода в памяти или защиту от взлома.
При смене опций компилятора длина процедур изменяется, что может быть
причиной неработоспособности такого рода кода, если в нем жестко заданы
длины или контрольные суммы.
← →
@!!ex © (2011-05-04 08:33) [18]Вот набросал код, который меняет свое поведение в зависимости от опции Range check
function read_func (ptr:Pointer; size:integer; nmemb:integer; datasource:Pointer):integer; cdecl;
var
F:Cardinal;
begin
F:=Cardinal(datasource);
Result:=FileRead(F,ptr^,size*nmemb);
end;
function seek_func (datasource:pointer; offset:int64; whence:integer):integer; cdecl;
var
F:Cardinal;
begin
F:=Cardinal(datasource);
FileSeek(F,offset,whence);
Result:=0;
end;
function close_func(datasource:pointer):integer; cdecl;
begin
Result:=0;
end;
function tell_func (datasource:pointer):integer; cdecl;
var
F:Cardinal;
begin
F:=Cardinal(datasource);
Result:=FileSeek(F,0,1);
end;
const OGG_BUFFER_SIZE = 1048576;
var
buffer:array[0..OGG_BUFFER_SIZE-1] of char;
procedure alutLoadOGGFile(fname: string; var format: TALenum; var data: TALvoid; var size: TALsizei; var freq: TALsizei; var loop: TALint);
var
F:Cardinal;
cb:ov_callbacks;
info:Pvorbis_info;
oggFile:OggVorbis_File;
bytes:integer;
endian:integer;
bitStream:integer;
begin
endian:=0;
F:=FileOpen(fname,fmOpenRead);
cb.read_func:=read_func;
cb.seek_func:=seek_func;
cb.close_func:=close_func;
cb.tell_func:=tell_func;
ov_open_callbacks( Pointer(f), @oggFile, nil, -1, cb);
Info := ov_info(@oggFile, -1);
if (Info.channels = 1) then
format := AL_FORMAT_MONO16
else
format := AL_FORMAT_STEREO16;
// end if
// The frequency of the sampling rate
freq := Info.rate;
size:=0;
data:=nil;
repeat
bytes := ov_read(@oggFile, @Buffer[0], OGG_BUFFER_SIZE, endian, 2, 1, @bitStream);
// Append to end of buffer
size:=size+bytes;
data:=ReallocMemory(Data,size);
CopyMemory(Pointer(Integer(Data)+size-bytes),@Buffer[0],bytes);
until bytes=0;
ov_clear(@oggFile);
FileClose(F);
end;
← →
clickmaker © (2011-05-04 11:55) [19]> меняет свое поведение в зависимости от опции Range check
меняет как?
ov_read вызывает read_func? все данные и правильно читаются этой функцией?
смущают вот такие тайпкасты Pointer(Integer(Data)+size-bytes)
по-хорошему, надо бы не Integer, а Cardinal, поскольку адрес - все-таки величина беззнаковая
← →
QAZ (2011-05-04 12:24) [20]
> ФИгово, когда не понимаешь что написано?
> Я для этого и пытаюсь разобраться как работает range check
> - чтобы ошибку найти.
читать умею и понимаю,только непонятно каким образом это поможет найти ошибку
> потому что я весь код прошерстил и не понимаю что в нем
> не так.
ну видимо вот это Pointer(Integer(Data)+size-bytes)
:)))
← →
Игорь Шевченко © (2011-05-04 13:14) [21]
> поскольку адрес - все-таки величина беззнаковая
для Delphi ?
← →
clickmaker © (2011-05-04 13:19) [22]> для Delphi ?
то есть?
← →
Anatoly Podgoretsky © (2011-05-04 13:23) [23]> clickmaker (04.05.2011 13:19:22) [22]
Что есть.
← →
Игорь Шевченко © (2011-05-04 13:49) [24]
> то есть?
ну у программ на delphi адресное пространство от 0 до почти $7FFFFFFF
← →
DVM © (2011-05-04 17:57) [25]
> у у программ на delphi адресное пространство от 0 до почти
> $7FFFFFFF
Адресное пространство программ на делфи, как и любых 32 разрядных программ в Windows - 4 Гб. 32-х битный указатель может быть любым числом от 0 до 4"294"967"296 (от $00000000 до $FFFFFFFF).
А вот пользовательская часть простирается почти до $7FFFFFFF с дырками внутри возможно. Но пользовательскую часть можно и подвинуть попробовать до 3 гб.
← →
Игорь Шевченко © (2011-05-04 20:34) [26]DVM © (04.05.11 17:57) [25]
> 32-х битный указатель может быть любым числом от 0 до 4"294"967"296
> (от $00000000 до $FFFFFFFF).
если не секрет, откуда возьмется в программе на Delphi указатель больше $7FFFFFFF и куда он будет указывать ?
> Но пользовательскую часть можно и подвинуть попробовать
> до 3 гб.
На delphi ? Сильно сомневаюсь
← →
Sha © (2011-05-04 21:08) [27]Что знаковое, что беззнаковое - все равно команды сложения те же.
Судя по тому, что ТС тему исключений упорно замалчивает,
исключения у него не возникают.
Остается только спросить, как автор узнал, что приведенный код меняет свое поведение?
И почему сумев узнать, что дело в этих 40 строчках, он не узнал, в какой из них?
← →
DVM © (2011-05-05 00:16) [28]
> Игорь Шевченко © (04.05.11 20:34) [26]
> На delphi ? Сильно сомневаюсь
Наверное ты читал это уже, но тут как раз о выделении памяти за пределами 2 гб:
http://www.gunsmoker.ru/2011/04/windows-spin-off.html
← →
DVM © (2011-05-05 00:22) [29]
> http://www.gunsmoker.ru/2011/04/windows-spin-off.html
Я не проверял, но утверждается, что в 64 бит системах 32 бит программа и 4 гб выделить может.
← →
Игорь Шевченко © (2011-05-05 00:34) [30]DVM © (05.05.11 00:16) [28]
> Наверное ты читал это уже,
Читал.
Вот про трюк с $SetPEFlags я, честно говоря, напрочь забыл
← →
han_malign (2011-05-05 09:25) [31]
> по-хорошему, надо бы не Integer, а Cardinal
- на 32-битах(еще и без 3GB флага) по барабану(и $R+, по моему, в пролете), но лучше - PAnsiChar(Data)+size-bytes
на вскидку вижу:
> function read_func (ptr:Pointer; size:integer; nmemb:integer; datasource:Pointer):integer; cdecl;size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource);
- size_t - обычно unsigned long,
но запрос больше 2Гб - как то маловероятен, и - вопрос, что библиотека с левым исключением делает...
Надо посмотреть что там в size и nmemb приходит...
← →
DVM © (2011-05-05 13:40) [32]
> по-хорошему, надо бы не Integer, а Cardinal
По хорошему так:
NativeUInt(Data)+size-bytes
← →
@!!ex © (2011-05-05 15:36) [33]> Судя по тому, что ТС тему исключений упорно замалчивает,
>
> исключения у него не возникают.
Не понял, что я замалчиваю?
Исключения не возникает.
> Остается только спросить, как автор узнал, что приведенный
> код меняет свое поведение?
> И почему сумев узнать, что дело в этих 40 строчках, он не
> узнал, в какой из них?
Как я узнал - Сообщение номер 5.
Сократить до менее чем 40 строчек у меня пока не получилось.
← →
@!!ex © (2011-05-05 15:37) [34]> Надо посмотреть что там в size и nmemb приходит...
size=1
nmemb=65536
← →
@!!ex © (2011-05-05 15:53) [35]> Не понял, что я замалчиваю?
Я понял что я замалчивал. почему-то мозг постоянно игнорировал слово исключение.
Только на четвертное прочитание я все таки увидел слово "исключение".
Да, исключений нет никаких. Единственное проявление проблем - шум вместо звука.
← →
clickmaker © (2011-05-05 15:59) [36]сравни содержимое Data с RC и без. Хотя бы на предмет различий
← →
@!!ex © (2011-05-05 16:01) [37]там мегабайты данных...
Поверхностно проверял. те участки которые проверял - выглядат одинаково.
проверял выхлоп ov_read.
может Realloc гадость творит?
Сейчас попробую выделить метров 100 сразу и не делать Realloc
← →
@!!ex © (2011-05-05 16:04) [38]не в реаллоке дело.
сделал выделение одним блоком - ничего не поменялось.
однако!
сделал итератор, вместо вычисления указателяsize:=0;
data:=AllocMem(100000000);// nil;
it:=data;
repeat
bytes := ov_read(@oggFile, @Buffer[0], OGG_BUFFER_SIZE, endian, 2, 1, @bitStream);
// Append to end of buffer
size:=size+bytes;
// data:=ReallocMemory(Data,size);
// CopyMemory(Pointer(cardinal(Data)+size-bytes),@Buffer[0],bytes);
CopyMemory(it,@Buffer[0],bytes);
inc(it,bytes);
until bytes=0;
и все заработало... Так отчего же старое не работало?
← →
clickmaker © (2011-05-05 16:13) [39]> Так отчего же старое не работало?
сравни сгенеренный asm-код закомментированного места с RC и без
← →
@!!ex © (2011-05-05 16:22) [40]Добавилось 4 строки:
0045985D 8B4DE8 mov ecx,[ebp-$18]
00459860 85C9 test ecx,ecx
00459862 7905 jns $00459869
00459864 E863A0FAFF call @BoundErr
BoundErr не вызывается ни разу. То есть сам эксцепшн не возникает. Именно сопутствующий код как-то влияют.
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2011.08.28;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.006 c