LINUX.ORG.RU

История изменений

Исправление X512, (текущая версия) :

Так-то в любой программе ловить переполнение стэка не составляет труда.

GCC и Clang без дополнительных флагов не умеют корректно обрабатывать переполнение стека для больших массивов на стеке, возможно перепрыгивание защитной страницы и порча памяти перед блоком памяти стека.

Передать указатель на массив в стэке?

Нельзя. С указателями можно делать только две манипуляции: выделение памяти в куче со сборщиком мусора через NEW(ptr) или присвоение другому указателю. Указатели в Обероне — это по сути идентификаторы объектов в куче. Чтобы делать адресную арифметику, надо использовать unsafe режим (IMPORT SYSTEM).

Но можно передавать ссылки на что угодно в VAR-параметрах процедур. В случае массивов передаётся скрытый параметр длины массива если длина не указана в типе параметра.

MODULE A;
	
	PROCEDURE Fill (VAR a: ARRAY OF INTEGER);
		VAR i: INTEGER;
	BEGIN
		i := 0; WHILE i < LEN(a) DO
			a[i] := -i;
		INC(i) END;
	END Fill;
	
	PROCEDURE Do*;
		VAR a: ARRAY 10000H OF INTEGER; (* вызывает $StackAlloc потому что есть вероятность перехода за защитную страницу *)
	BEGIN
		Fill(a);
		HALT(0);
	END Do;
	
END A.

(!) A.Do

Исходная версия X512, :

есть еще переполнение буфера, когда данные пишутся туда, где должны лежать адреса.

Так-то в любой программе ловить переполнение стэка не составляет труда.

GCC и Clang без дополнительных флагов не умеют корректно обрабатывать переполнение стека для больших массивов на стеке, возможно перепрыгивание защитной страницы и порча памяти перед блоком памяти стека.

Передать указатель на массив в стэке?

Нельзя. С указателями можно делать только две манипуляции: выделение памяти в куче со сборщиком мусора через NEW(ptr) или присвоение другому указателю. Указатели в Обероне — это по сути идентификаторы объектов в куче. Чтобы делать адресную арифметику, надо использовать unsafe режим (IMPORT SYSTEM).

Но можно передавать ссылки на что угодно в VAR-параметрах процедур. В случае массивов передаётся скрытый параметр длины массива если длина не указана в типе параметра.

MODULE A;
	
	PROCEDURE Fill (VAR a: ARRAY OF INTEGER);
		VAR i: INTEGER;
	BEGIN
		i := 0; WHILE i < LEN(a) DO
			a[i] := -i;
		INC(i) END;
	END Fill;
	
	PROCEDURE Do*;
		VAR a: ARRAY 10000H OF INTEGER; (* вызывает $StackAlloc потому что есть вероятность перехода за защитную страницу *)
	BEGIN
		Fill(a);
		HALT(0);
	END Do;
	
END A.

(!) A.Do