Что нового

[Ошибки] Как найти стоку ошибки в скомпилированном скрипте?

dimcomp

Новичок
Сообщения
66
Репутация
0
Доброго времени суток. Через, примерно, сутки работы программы вылазит ошибка recursion level has been exceeded и пишет строку где её искать, но программа обфусцирована и скомпилирована, поэтому строки не совпадают. Как найти где ошибка?
P.S. У меня она не выскакивает, поэтому запустив нескомпилированный скрипт у себя вычислить не могу.
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Обфускатор на помойку. На данном языке золота не напишешь. Можно просто набыдлокодить и сам черт рога сломает, пытаясь постичь логику :smile:
По теме. Смотри исходник после обфускации. В нем номер строки. Смотри циклы с рекурсией. Где то пропущено условие. И превышается колличество циклрв рекурсии
 
Автор
D

dimcomp

Новичок
Сообщения
66
Репутация
0
joiner сказал(а):
По теме. Смотри исходник после обфускации. В нем номер строки. Смотри циклы с рекурсией. Где то пропущено условие. И превышается колличество циклрв рекурсии
Если верить номеру строки ошибки после обфускации то ошибка в подключаемом инклюде GuiStatusBar.au3 в функции
Код:
Func _GUICtrlStatusBar_SetText($hWnd, $sText = "", $iPart = 0, $iUFlag = 0)
	If $Debug_SB Then __UDF_ValidateClassName($hWnd, $__STATUSBARCONSTANT_ClassName)

	Local $fUnicode = _GUICtrlStatusBar_GetUnicodeFormat($hWnd)

	Local $iBuffer = StringLen($sText) + 1
	Local $tText
	If $fUnicode Then
		$tText = DllStructCreate("wchar Text[" & $iBuffer & "]")
		$iBuffer *= 2
	Else
		$tText = DllStructCreate("char Text[" & $iBuffer & "]")
	EndIf
	DllStructSetData($tText, "Text", $sText)
	If _GUICtrlStatusBar_IsSimple($hWnd) Then $iPart = $SB_SIMPLEID
	Local $iRet
	If _WinAPI_InProcess($hWnd, $__ghSBLastWnd) Then
		$iRet = _SendMessage($hWnd, $SB_SETTEXTW, BitOR($iPart, $iUFlag), $tText, 0, "wparam", "struct*")
	Else
		Local $tMemMap
		Local $pMemory = _MemInit($hWnd, $iBuffer, $tMemMap)
		_MemWrite($tMemMap, $tText)
		If $fUnicode Then
			$iRet = _SendMessage($hWnd, $SB_SETTEXTW, BitOR($iPart, $iUFlag), $pMemory, 0, "wparam", "ptr")
		Else
			$iRet = _SendMessage($hWnd, $SB_SETTEXT, BitOR($iPart, $iUFlag), $pMemory, 0, "wparam", "ptr")
		EndIf
		_MemFree($tMemMap)
	EndIf
	Return $iRet <> 0
EndFunc   ;==>_GUICtrlStatusBar_SetText

а именно в строке
Код:
If $Debug_SB Then __UDF_ValidateClassName($hWnd, $__STATUSBARCONSTANT_ClassName)

Что тут не так?)
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
dimcomp
как вариант - запустить код в редакторе. пусть работает сутки. тогда точно строку найдешь.
насчет рекурсии - смотри свои функции( не библиотечные), в которых есть рекурсии
 
Автор
D

dimcomp

Новичок
Сообщения
66
Репутация
0
joiner сказал(а):
насчет рекурсии - смотри свои функции( не библиотечные), в которых есть рекурсии
Вобщем ошибка всё-таки в инклюде GuiStatusBar.au3 717 строка Return _SendMessage($hWnd, $SB_GETUNICODEFORMAT) <> 0
вот сама функция
Код:
Func _GUICtrlStatusBar_GetUnicodeFormat($hWnd)
	If $Debug_SB Then __UDF_ValidateClassName($hWnd, $__STATUSBARCONSTANT_ClassName)

	Return _SendMessage($hWnd, $SB_GETUNICODEFORMAT) <> 0
EndFunc   ;==>_GUICtrlStatusBar_GetUnicodeFormat

Я примерно подсчитал, выходит после примерно 5000 записей в статус баре программа закрывается.
Что можно сделать? :'(
 

hedji

Продвинутый
Сообщения
409
Репутация
94
Почитайте здесь и здесь
Общий совет - переписать без использования рекурсии.
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
dimcomp
откуда библиотека?
__UDF_ValidateClassName такой функции там нет.
насчет рекурсии,то я не увидел её в библиотеке
ошибка у тебя выпадает в функции с рекурсией. свои функции смотрел? анализировал?
ошибка ясно говорит, что превышен число циклов вызова функции в рекурсии. значит где-то в функциях,которые писал ты или скопировал с форума пропущено условие.
 
Автор
D

dimcomp

Новичок
Сообщения
66
Репутация
0
Всем спасибо! Дошло наконец))) Только я не пойму почему ошибка именно в этой строке появляется :scratch:. Нашёл в чём причина. Вот написал обрезанный код, но смысл тот же. Как исправить?
Код:
#include <APIConstants.au3>
#include <WinAPIEx.au3>
#include <GuiStatusBar.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

global $y=0, $Radio1, $Radio2, $StatusBar1

form()

Func form()
Local $msg

$Form = GUICreate("Пример", 200, 100, -1, -1)
$Radio1 = GUICtrlCreateRadio("1", 16, 16, 65, 17)
GUICtrlSetState(-1, $GUI_CHECKED)
$Radio2 = GUICtrlCreateRadio("2", 16, 46, 65, 17)

$StatusBar1 = _GUICtrlStatusBar_Create($Form)
Dim $StatusBar1_PartsWidth[7] = [200, -1]
_GUICtrlStatusBar_SetParts($StatusBar1, $StatusBar1_PartsWidth)
_GUICtrlStatusBar_SetText($StatusBar1, "Нажмите F1", 0)

GUISetState(@SW_SHOW)
	
HotKeySet("{F1}", "enter")
	
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd
    GUIDelete()
EndFunc

Func enter()

    If GUICtrlRead($Radio1) = 1 Then
	   $nF = 1
	Endif
	
	If GUICtrlRead($Radio2) = 1 Then
	   $nF = 2
	Endif

    While 1
	    Switch $nF
            Case 1
			    $nF = func1()
			Case 2
			    $nF = func2()
			Case 3
			    $nF = enter()	
        EndSwitch
    WEnd
	
EndFunc

func func1()
$y = $y + 1
_GUICtrlStatusBar_SetText($StatusBar1, $y, 0)
return 3
Endfunc

func func2()
MsgBox(4096, "Info", "Выберите радиокнопку '1'")
Endfunc
 

xXx

╚{■_■}╗
Меценат
Сообщения
248
Репутация
95
У меня сейчас нет помпа под рукой, но почитайте внимательно справку по функции
Код:
HotKeySet()


а затем сделайте так
Код:
...
; form()

; Func form()
Local $msg

$Form = GUICreate("Пример", 200, 100, -1, -1)
$Radio1 = GUICtrlCreateRadio("1", 16, 16, 65, 17)
GUICtrlSetState(-1, $GUI_CHECKED)
$Radio2 = GUICtrlCreateRadio("2", 16, 46, 65, 17)

$StatusBar1 = _GUICtrlStatusBar_Create($Form)
Dim $StatusBar1_PartsWidth[7] = [200, -1]
_GUICtrlStatusBar_SetParts($StatusBar1, $StatusBar1_PartsWidth)
_GUICtrlStatusBar_SetText($StatusBar1, "Нажмите F1", 0)

GUISetState(@SW_SHOW)
    
HotKeySet("{F1}", "enter")
    
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd
    GUIDelete()
; EndFunc
...


Добавлено:
Сообщение автоматически объединено:

Функцию enter() надо бы притормозить при помощи sleep().


Добавлено:
Сообщение автоматически объединено:

и еще, после нажатии F1 попробуйте закрыть GUI окно, что произойдет?
 
Автор
D

dimcomp

Новичок
Сообщения
66
Репутация
0
Вы имеете ввиду то что хоткей находится внутри функции? Да, пример составил не верно, но проблема не в этом. Функция энтер вызывает функцию1, а функция1 в свою очередь вызывает функцию энтер. Если я правильно понимаю это и есть рекурсия. А вот как избавиться от неё не знаю(. Тормоза энтера не спасут от рекурсии. При попытке закрыть окно счётчик замирает, после отпускания ЛКМ, продолжает дальше тикать, окно не закрывается и ждёт своего часа.
 
Автор
D

dimcomp

Новичок
Сообщения
66
Репутация
0
xXx сказал(а):
Не надо предпологать, нужно проверять.
Проверил, оттягивает время только.
dimcomp сказал(а):
.окно не закрывается и ждёт своего часа.
А что, так и задумано?
[/quote]
Нет не задумано, я думаю из-за того что программа работает и из-за этого не закрывается, если счётчик остановить, я думаю она бы закрылась. Это всего лишь пример, состряпанный на быструю руку, главное понять причину почему вылетает ошибка переполнения стека когда счётчик намотает 3894 очков. По этому примеру я уже исправлю основной скрипт.
 

xXx

╚{■_■}╗
Меценат
Сообщения
248
Репутация
95
dimcomp сказал(а):
главное понять причину почему вылетает ошибка
Вам уже разъяснили
hedji сказал(а):
Почитайте здесь и здесь
Общий совет - переписать без использования рекурсии.

Код:
#include <GuiStatusBar.au3>
#include <GUIConstantsEx.au3>

Opt("GUIOnEventMode", 1) ; Включает режим OnEvent
Global $iFlag = 0, $y = 0, $Radio1, $Radio2, $StatusBar1

HotKeySet("{F1}", "enter")
HotKeySet("{F2}", "enter_Stop")

$Form = GUICreate("Пример", 200, 100, -1, -1)
$Radio1 = GUICtrlCreateRadio("1", 16, 16, 65, 17)
GUICtrlSetState(-1, $GUI_CHECKED)
$Radio2 = GUICtrlCreateRadio("2", 16, 46, 65, 17)

$StatusBar1 = _GUICtrlStatusBar_Create($Form)
Dim $StatusBar1_PartsWidth[7] = [200, -1]
_GUICtrlStatusBar_SetParts($StatusBar1, $StatusBar1_PartsWidth)
_GUICtrlStatusBar_SetText($StatusBar1, "Нажмите F1", 0)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
GUISetState(@SW_SHOW)

While 1
	If $iFlag Then
		enter()
	Else
		Sleep(100)
	EndIf
WEnd

Func enter()
	If BitAND(GUICtrlRead($Radio2), $GUI_CHECKED) Then
		MsgBox(4096, "Info", "Выберите радиокнопку '1'")
		Return 0
	EndIf

	$iFlag = 1

	$y += 1
	_GUICtrlStatusBar_SetText($StatusBar1, $y, 0)
EndFunc   ;==>enter

Func enter_Stop()
	$iFlag = 0
EndFunc   ;==>enter_Stop

Func CLOSEClicked()
	Exit
EndFunc   ;==>CLOSEClicked



Добавлено:
Сообщение автоматически объединено:

А вот так таймер не будет останавливаться при перетаскивании окна
Код:
#include <Timers.au3>
#include <GuiStatusBar.au3>
#include <GUIConstantsEx.au3>

Global $y = 0, $Radio1, $Radio2, $StatusBar1

HotKeySet("{F1}", "enter")
HotKeySet("{F2}", "enter_Stop")

$Form = GUICreate("Пример", 200, 100, -1, -1)
$Radio1 = GUICtrlCreateRadio("1", 16, 16, 65, 17)
GUICtrlSetState(-1, $GUI_CHECKED)
$Radio2 = GUICtrlCreateRadio("2", 16, 46, 65, 17)
$StatusBar1 = _GUICtrlStatusBar_Create($Form)
Dim $StatusBar1_PartsWidth[7] = [200, -1]
_GUICtrlStatusBar_SetParts($StatusBar1, $StatusBar1_PartsWidth)
_GUICtrlStatusBar_SetText($StatusBar1, "Нажмите F1", 0)
GUISetState(@SW_SHOW)

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			ExitLoop
	EndSwitch
WEnd

Func _UbdateTimer($hWnd, $Msg, $iIDTimer, $dwTime)
	If BitAND(GUICtrlRead($Radio2), $GUI_CHECKED) Then
		enter_Stop()
		MsgBox(4096, "Info", "Выберите радиокнопку '1'")
		Return 0
	EndIf
	$y += 1
	_GUICtrlStatusBar_SetText($StatusBar1, $y, 0)
EndFunc   ;==>_UbdateTimer

Func enter()
	_Timer_SetTimer($Form, 10, '_UbdateTimer')
EndFunc   ;==>enter

Func enter_Stop()
	_Timer_KillAllTimers($Form)
EndFunc   ;==>enter_Stop
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Функция enter в рекурсии и никаких условий выхода из рекурсии. Варианты решений. Не использовать рекурсию или сделать выход по счетчику циклов рекурсии, или выход после выполнения вложенных функций в функцию enter , или переписать всю логику кода.
 
Автор
D

dimcomp

Новичок
Сообщения
66
Репутация
0
Всем спасибо! Буду разбираться.
 
Верх