Многопоточность и выход за пределы диапазона

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Ответить
Сквозняк
энтузиаст
Сообщения: 1159
Зарегистрирован: 29.06.2006 22:08:32

Многопоточность и выход за пределы диапазона

Сообщение Сквозняк »

Компилятор 2.4.0, ос линукс, имеется проблема с узнаванием о факте выхода за пледелы диапазона массивов. Если не используется лазарус, то всё замечательно, если он есть, валится его стек, но это хоть какая-то информация. А если выход за пределы диапазона происходит внутри потока, то догадаться об этом можно очень нескоро и только по странному поведению программы. А желательно знать сразу чтобы оперативно исправить ошибку. Вот некошерная но точная модель кода

Код: Выделить всё

{$MODE OBJFPC}
{$GOTO ON}
{$R+}
{$H-}

USES
{$IFDEF LINUX}
cthreads,
{$ENDIF}
classes, sysutils;

var
Q3,W3: byte;
WW3: array[1..100] of byte;
LABEL 100;


Type
TPotok_Nitj_1 = class(TThread)
private
procedure ShowStatus;
protected
procedure Execute; override;
public
Constructor Create(CreateSuspended: boolean);
end;


constructor TPotok_Nitj_1.Create(CreateSuspended : boolean);
begin
FreeOnTerminate := True;
inherited Create(CreateSuspended);
end;

procedure TPotok_Nitj_1.ShowStatus;
begin
end;



PROCEDURE VKLJUCENIE_POTOKA_Nitj_1;
var
Potok_Nitj_1: TPotok_Nitj_1;
BEGIN
Potok_Nitj_1:=TPotok_Nitj_1.Create(true);

Potok_Nitj_1.Resume;
END;


procedure pererolnenie_massiva;
label
1;
begin
1:
WRITELN('PROVERKA 1');
WW3[1]:=200;
WW3[WW3[1]]:=100;
WRITELN('PROVERKA 2');
WRITELN(WW3[WW3[1]]);
WRITELN('PROVERKA 3');
sleep(1000);
if q3<20 then goto 1;
w3:=1;
end;


procedure TPotok_Nitj_1.Execute;
begin
FreeOnTerminate:=true;
pererolnenie_massiva;
end;


begin
W3:=0;
VKLJUCENIE_POTOKA_Nitj_1;
for q3:=1 to 80 do begin
                   writeln('glavnij_potok ',q3);
                   if W3=1 then begin
                                writeln('polucen signal na vihod');
                                goto 100;
                                end;
                   sleep(200);
                   end;
100:
end.

Если стоит {$R+}, то поток дохнет а "машина едет дальше" как нивчём не бывало. А если поставить {$R-}, то поток не дохнет и создаётся впечатление будто никакого переполнения не было, а массив резиновый и удлиняется усилием мысли :D
Аватара пользователя
hinst
энтузиаст
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Сообщение hinst »

у меня такая же хрень, только "машина едет дальше" при любом исключении, выбрасываемом из потока, а не только EArrayOutOfBounds или как его там. Похоже, это баг :shock:
Mr.Smart
долгожитель
Сообщения: 1796
Зарегистрирован: 29.03.2008 00:01:11
Откуда: из леса!

Сообщение Mr.Smart »

Эксепшены из потока не передаются в основной поток программы. Возникший эксепшен помешается в свойство FatalException класса TThread.
Аватара пользователя
hinst
энтузиаст
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Сообщение hinst »

Mr.Smart а как тогда сделать, чтобы вытащить инфу по эксепшену, включая стэк вызовов?
Ответить