Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   forum.boolean.name > Программирование игр для компьютеров > Blitz3D > FAQ

FAQ Туториалы и часто задаваемые вопросы

Ответ
 
Опции темы
Старый 10.01.2006, 18:14   #1
impersonalis
Зануда с интернетом
 
Аватар для impersonalis
 
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений
(для 20,935 пользователей)
Смущение

"DebugLog и память" или "юзаем аккуратно".
На создание этой заметки меня сподвиг факт существования культа авторитета и культа мнения большинства.
Или как называл эти тормозящие процесс познания явления Френсис Бэкон: призраки рынка и призраки театра.
Но не будем вдаваться в подробности поиска метода познания в период Нового Времени и вернёмся к b3d.
Помнится многие рьяно уверяли меня в том, что b3d адекватно отображает кирилический текст произвольной длины командой Text...
Пока Morpher и Tormoz не подтвердили этот обидный недостаток... Часто проблема обнаружения уязвимости заключается в сложности провоцирования ошибки.
На этот раз сбой при выполнении команды Debuglog.
К сожалению чётко сформулировать условия сбоя пока не удалось, но происходит он при
многократном вызове функций ( в т.ч. рекурсивно) и юзании конструкций типа:
Function a(x)
	DebugLog x
	Return x
End Function

DebugLog a(x)
В приведённом ниже примере, уменьшение кол-ва вызовов команды debuglog ведёт к повышению устойчивости, а запуск программы вне отладочного режима ( что эквивалентно полному избавлению кода от команд отладки) даёт 100%-правильный результат вычилений при любом кол-ве вызовов.
Собственно, сам пример:
В примере набо функций и тип для выичсления определителя кв.матрицы произвольного ограниченного размера.
Конкретно считается вот такой определитель:

Нетрудно заметить пропорциональность строк, на основании чего сделать вывод - матрица имеет нулевой
детерминант.
Вот b3d реализация:
Graphics 800,600
SetFont LoadFont("arial cur",20)
Const TMatrixMaxIndex2D=99
Type TMatrix
	Field Buffer#[TMatrixMaxIndex2D]
	Field StringSize
	Field CSize
End Type

Function TMatrix_Create.TMatrix(size,size2=-1)
	M.TMatrix=New TMatrix
	M\StringSize=size
	M\CSize=size2
	If M\CSize=-1 M\CSize=size
	Return M
End Function

Function TMatrix_IN(M.TMatrix,SNumber,CNumber,Z$)
	Local Index2d=(SNumber-1)*M\StringSize+(CNumber-1)
	M\Buffer[Index2d]=Z$
End Function


Function TMatrix_OUT(M.TMatrix,SNumber,CNumber)
	Local Index2d=(SNumber-1)*M\StringSize+(CNumber-1)
	Return M\Buffer[Index2d]
End Function

Function TMatrix_Delete(M.TMatrix)
	Delete M
End Function

Function TMatrix_Determinant#(M.TMatrix) 

	SS=M\StringSize 
	CS=M\CSize 
	
	If SS=1 And CS=1 
	DebugLog "determ ="+M\buffer[0] 
	Return Float(M\buffer[0]) 
	EndIf 
	Local DET#=0 
	For i=1 To SS 
 *MINOR.TMATRIX=TMatrix_minor(M,1,i) 
 *DebugLog ""+DET+"+"+((-1)^(i+1))+"*"+TMatrix_Determinant(MINOR)+"*"+TMatrix_OUT(M,1,i)
 *DET=DET+(-1)^(i+1)*TMatrix_Determinant(MINOR)*Float(TMatrix_OUT(M,1,i)) 
 *DebugLog "="+DEt 
 *TMatrix_Delete(MINOR) 
	Next 
	DebugLog "determ ="+DET 
	Return DET 
End Function

Function TMatrix_minor.TMatrix(M.TMatrix,NS,NC) 
	minSS=M\StringSize-1 
	minCS=M\CSize-1 
	Minor.TMatrix=TMATRIX_Create(minSS,minCS) 
	Local Smin=1 
	For S=1 To M\CSize 
 *Local Cmin=1 
 *For C=1 To M\StringSize 
 *	If C=NC 
 *	Cmin=Cmin-1 
 *	Else 
 *	TMatrix_IN(Minor,Smin,Cmin,TMatrix_OUT(M,S,C)) 
 *	EndIf 
 *	Cmin=Cmin+1 
 *Next 
 *If S=NS 
 *Smin=Smin-1 
 *EndIf 
 *Smin=Smin+1 
	Next 
	Return Minor 
End Function

a.tmatrix=tmatrix_create(3,3) 
 TMatrix_IN(a,1,1,1) 
 TMatrix_IN(a,1,2,2) 
 TMatrix_IN(a,1,3,3) 

 TMatrix_IN(a,2,1,4) 
 TMatrix_IN(a,2,2,5) 
 TMatrix_IN(a,2,3,6) 

 TMatrix_IN(a,3,1,7) 
 TMatrix_IN(a,3,2,8) 
 TMatrix_IN(a,3,3,9) 
For i=1 To 25
dd=TMatrix_Determinant(a) 
DebugLog dd 
Print "test#: "+i+"; * 0="+dd
Next
WaitKey()
End
Код вычурно перегружен отладочными командами и вызовами функций с целью показть уязвимость в действии.
Запустите его в ___ОТЛАДОЧНОМ____ режиме.
И понаблюдайте - сколько раз из 25 b3d докажет что 0<>0.
Теперь отключите отладку и сравните результаты. =)
Положив 2 часа на отладку полностью рабочего кода ( постоянно добавляя отладочные команды - чем ещё более усугублял совё положение) я перепробовал различные версии b3d - все подвержены данной ошибке, которая, судя по всему, заключается в затирании уже используемых пространств памяти.
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
(Offline)
 
Ответить с цитированием
Старый 10.01.2006, 18:25   #2
alex-mad
Модератор
 
Регистрация: 13.09.2005
Сообщений: 1,835
Написано 6 полезных сообщений
(для 10 пользователей)
Плохо

гы... когда я услышал по скайпу ответ b3d этой матрицы (за минуту до этого проверил формулы написанные Импером) я почти упал со стула!
будьте осторожны!
(Offline)
 
Ответить с цитированием
Старый 10.01.2006, 22:06   #3
AsmLover
 
Сообщений: n/a
Originally posted by impersonalis@Jan 10 2006, 05:14 PM
Код вычурно перегружен отладочными командами и вызовами функций с целью показть уязвимость в действии.
Запустите его в ___ОТЛАДОЧНОМ____ режиме.
И понаблюдайте - сколько раз из 25 b3d докажет что 0<>0.
Теперь отключите отладку и сравните результаты. =)
Положив 2 часа на отладку полностью рабочего кода ( постоянно добавляя отладочные команды - чем ещё более усугублял совё положение) я перепробовал различные версии b3d - все подвержены данной ошибке, которая, судя по всему, заключается в затирании уже используемых пространств памяти.

К сожалению, это не баг, а всего лишь неграмотное применение отладчика в примере, который привел Impersonalis. Отлачик в функции TMatrix_Determinant рекурсивно вызывает эту же функцию, что, естественно, неизбежно вызывает исчерпание стека (хорошо еще, что встроенные отладчики имеют свою стековую машину, а то бы вообще все рунуло).

Правильно делать так:
Function TMatrix_Determinant#(M.TMatrix) 
   SS=M\StringSize 
   CS=M\CSize 

   If SS=1 And CS=1 
    DebugLog "determ ="+M\buffer[0] 
    Return Float(M\buffer[0]) 
   EndIf
 
   Local DET#=0 
   For i=1 To SS 
     MINOR.TMATRIX=TMatrix_minor(M,1,i) 
     TMD#=TMatrix_Determinant(MINOR)
     DebugLog ""+DET+"+"+((-1)^(i+1))+"*"+TMD+"*"+TMatrix_OUT(M,1,i)
     DET=DET+(-1)^(i+1)*TMD*Float(TMatrix_OUT(M,1,i)) 
     DebugLog "="+DEt 
     TMatrix_Delete(MINOR) 
   Next 
   DebugLog "determ ="+DET 
  Return DET 
End Function
Теперь никаких ошибок не будет.

В нормальном режиме и дебаггера достаточно ресурсов для своей работы.
Собственно, DebugLog предназначен для формирования строки вывода и имеет буфер строки более 16 Кбайт, это легко проверить с помощью
a$=""
For j=1 To 16000
  For i=0 To 9 
   a$=a$+i
  Next 
Next

DebugLog a$

WaitKey
Разумеется, ничего не мешает Марку установить и размер стека, не вызывающий проблем в нормальном режиме - для простого блитца он может вообще иметь пару килобайт, а его переполнение ошибки не вызывает (что тоже странно, однако). Правда ошибки в блитце не вызывает и отсутствие вызываемой DLL при динамическом связывании, что не менее странно (а при статическом связывании при этом сразу появится ошибка).

В Help-файле написано, что аргументом DebugLog может быть текстовая переменная, строка, числовое значение. К сожалению, структура справки в целом нечеткая, поэтому трудно судить, запрещалось ли изначально в ней вычисление выражения. Но я пытался без рекурсии свалить стек, но при корректных вычислениях у меня не получилось. Но в любом случае, для вычисления выражений в приведенном Impersonalisom примере ограничивается стековое пространство при рекурсии.

Но есть программы, которые ведут себя странно со включенным Debug , причем DebugLog вообще там не используется, например партикловая система Lotus.
 
Ответить с цитированием
Старый 11.01.2006, 01:22   #4
impersonalis
Зануда с интернетом
 
Аватар для impersonalis
 
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений
(для 20,935 пользователей)
Ну в общем то целью заметки было предотвратить неосторожное юзание debuglog.
Ведь это сложнонаходимо.
Если переполнить стек программы она либо закрешится, либо молча зкроется - а тут всё считается.. но не правильно.

То что код так не пишут я знаю =)
Это пример.

В любом случае - спибо за автороитетное мнение и уточнение деталей.
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
(Offline)
 
Ответить с цитированием
Старый 11.01.2006, 03:06   #5
AsmLover
 
Сообщений: n/a
Originally posted by impersonalis@Jan 11 2006, 12:22 AM
Ну в общем то целью заметки было предотвратить неосторожное юзание debuglog.
Ведь это сложнонаходимо.
Если переполнить стек программы она либо закрешится, либо молча зкроется - а тут всё считается.. но не правильно.

То что код так не пишут я знаю =)
Это пример.

В любом случае - спибо за автороитетное мнение и уточнение деталей.
1) Хорошо сказал - неосторожное юзанье!
DebugLog можно и нужно использовать.
2)Насчет сложнонаходимо - у меня это заняло 1 минуту с проверкой. А для того, чтобы потренироваться со стеком - надо на Форте попробовать попрограммировать - там одновременно несколько стеков используется, вот где раздолье!
3)Во-первых тут стек не программы, а отладчика. Отладчик работает, как вариант, сохраняя кадр программы и переключая регистр BP на другую область стека. А во-вторых, так как DebugLog чисто информационный, из-за переполнения стека может быть получен только недостоверный результат, поскольку вычисление функции может прерваться в любом месте, но при этом происходит восстановление кадра программы (всех регистров, стека и флагов). То есть краха программы не будет.
Поэтому считается все правильно, только в последней рекурсии, на которой выделенный стек загнулся, вычисление обрывается с итоговым неправильным состоянием регистров микропроцессора, которое выдаст в неправильный результат DET.
 
Ответить с цитированием
Старый 11.01.2006, 03:15   #6
AsmLover
 
Сообщений: n/a
P.S. Естественно, под BP подразумевается EBP или RBP.
 
Ответить с цитированием
Старый 11.01.2006, 03:27   #7
AsmLover
 
Сообщений: n/a
Имеется в виду, что ESP юзается обычно в связки с EPB. Вообщем, это уже не Бейсик.
Что-то я размазался по трем постам.... Зарегиться, что ли, чтобы править можно было...
 
Ответить с цитированием
Старый 11.01.2006, 04:14   #8
impersonalis
Зануда с интернетом
 
Аватар для impersonalis
 
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений
(для 20,935 пользователей)
Смущение

Originally posted by AsmLover@Jan 11 2006, 02:27 AM
Зарегиться, что ли, чтобы править можно было...
ага
давно ждём, столь опытного кодера в своих рядах
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
(Offline)
 
Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Можно ли сделать так чтобы при нажатии "вверх" и "вниз" двигалась одна картинка, а при нажатии "вправо" и "влево" - другая Total_Nube_&_Lamo Основной форум 2 13.12.2009 22:00
"Кодирование/декодирование изображений", или "Давайте попробуем скрыть ресурсы мидлетов" Richik Библиотеки 17 03.06.2009 14:18
Игра "Три слова". Рассказ "Время планет" Ilyich Юмор 77 02.04.2007 17:49
"мапэд", или оживление "превед" культуры jimon Юмор 0 06.11.2006 17:45
"Пополнение рядов" или "Слава роботам!" impersonalis Юмор 1 15.08.2006 23:54


Часовой пояс GMT +4, время: 14:19.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com