Какие бывают причины фатал еррора? Схватил фатал еррор. Теперь нужно узнать из-за чего она.
Знаю что:
  1. Юнит не должен выйти за пределы карты
  2. Индекс игрока не должен быть отрицательным числом.
Какие еще есть причины словить фатал еррор? Добавьте свои списки причин

ESI=0CFB7EAC
В краш репорте засветился указатель на способность. В .dmp файле сохранена память стека потоков и еще некоторые регионы памяти. Среди них оказалась и область со способностью, в которой виден её равкод: 0x41304F4A или A0OJ. Эта способность основана на Aave (CAbilityAvengerForm).
Также видно равкод владельца — Hmgd.
Что на счет события — во время моих тестов оно срабатывало в начале и в конце перевополощения.
Загруженные файлы
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
23
Похожие вопросы:

ответ
Увы нет, смотреть из за чего ошибка и потом смотреть что в коде могло её вызвать.
Так же нелишним будет собрать статистику а что именно происходило в этот момент и изучать код, кторый работал в этот момент.
Фаталить могут даже дефолтные способности.
ответ
Попробуй отключить триггеры, для начала, и затем проверь, запустится ли карта в игре. Особенно те, которые были созданы/редактированы относительно недавно до появления фатала.
ответ
Lodnar:
quq_CCCP:
Lodnar, интересно сударь а то вы забыли в 1.27б? Мб иллюзии не могут появится из за примирения в "узком" месте.
Я забыл в 1.27b поддержку карт свыше 8 мегабайт.
Да, проверил, игра вылетела при попытке использования "в окружении союзников", а вот когда кидал в окружении стен из рельефа, то герой просто "пробил её" появившись с другой стороны.
Это как-то подвержено исправлениям или нет?
Совет тебе друг - скачай 1.26 чистый, кинь себе в папку исправленую game.dll, и удали русификатор тригеров (если его юзаешь). И будешь играть и спокойно работать с вариком. Все версии после 1.26 с определенными косяками, которые сложно (если вообще возможно) фиксить и обходить. DLL тебе снимет лимит на размер карты. А русификаторы ломают редактор (тут даже говорить не стоит). Все это можно загуглить.
Если же ты уверен что проблема РЕАЛЬНО в заклинании иллюзия (что странно), добавь больший радиус\область применения. Сделай меньше иллюзий. МОжно поработать с коллиженами у модели иллюзий, но это все если заморачиваться......
ответ
Бафф с равкодом B005, проверяй что это за баф и с чем он связан. краш из-за него.
ps. аура на мертвом?))))
ответ
Инструкция по адресу 0x6F430C91 попыталась прочесть память по адресу 0x00000020, но так как там ничего не было — она крашнулась.
Этот код расположен в пределах game.dll (0x6F000000 - 0x6FBB5000 F:\Warcraft III 1.26S\Game.dll), что видно в разделе Loaded Modules. Учтите, что пусть эта библиотека и предпочитает распологаться по адресу 0x6F000000, но операционная система может загрузить её куда либо еще и тогда, с теми же смещениями, абсолютные адреса будут отличаться. К примеру, если библиотека будет по адресу 0x24F00000, то вместо 0x6F430C91 вы увидите 0x25330C91 (0x24F00000 + 0x430C91).
По смещению 0x430C91 находится код функции CGameState::GetAgentHandle, которая принимает указатель на агент и возвращает его хэндл.
В дампе памяти стека видны значения трёх сохраненных регистров (0x00000010 0x0019DFE8 0xFFFFFFFF), а также адрес возврата 0x6F3BBB58 и полученные аргументы: agent=0x00000010, auto_free=0x00000000. Кто-то передал кривой указатель 0x10, который ссылается на нечитаемую память.
Адрес возврата ведет к нативке Player. В стеке можно увидеть сохраненное ею значение регистра (0x6F9473BE), адрес возврата к коду виртуальной машины (0x6F45D1B8) и полученный ею аргумент (number=0xFFFFFFFF), который в виде знакового целого равняется числу -1.
Вывод: кто-то вызвал нативку Player с параметром -1, что и привело к крашу.
Найти конкретного виновника поможет программа, ссылку на которую я скинул выше.
Начало дампа стека
Обратите внимание, что дамп стека выровнен по границе 16 байт, так что, на самом деле вершина стека находится не по адресу 0x0019DF10, а как написано ниже — 0x0019DF18, так что, в данном случае, первые 8 байт можно пропустить (зачеркнуты).
Синим выделены сохраненные значения регистров, зеленым — адреса возврата, а красным — кривые параметры, приведшие к крашу.
Stack: 1024 bytes starting at (ESP = 0019DF18)
= addr ** *
0019DF10: E8 DF 19 00 75 91 45 6F 10 00 00 00 E8 DF 19 00 ....u.Eo........
0019DF20: FF FF FF FF 58 BB 3B 6F 10 00 00 00 00 00 00 00 ....X.;o........
0019DF30: BE 73 94 6F B8 D1 45 6F FF FF FF FF A4 D1 45 6F .s.o..Eo......Eo
начало метода CGameState::GetAgentHandle
.text:6F430C80 ; int __thiscall CGameState::GetAgentHandle(CGameState *this, CAgent *agent, BOOL AutoFree)
.text:6F430C80 CGameState__GetAgentHandle proc near    ; CODE XREF: CUnit__PostEvent+8F↑p
.text:6F430C80                                         ; CUnit__NotifyAboutInstantOrder+195↑p ...
.text:6F430C80
.text:6F430C80 agent           = dword ptr  4
.text:6F430C80 AutoFree        = dword ptr  8
.text:6F430C80
.text:6F430C80                 push    ebx
.text:6F430C81                 push    ebp
.text:6F430C82                 mov     ebp, [esp+8+agent]
.text:6F430C86                 test    ebp, ebp
.text:6F430C88                 push    esi
.text:6F430C89                 mov     ebx, ecx
.text:6F430C8B                 jz      loc_6F430D9B
.text:6F430C91                 mov     esi, [ebp+10h]
нативка Player
.text:6F3BBB30 ; DWORD __cdecl Jass::Common::Player(int number)
.text:6F3BBB30 Jass__Common__Player proc near          ; DATA XREF: InitJass+3007↓o
.text:6F3BBB30
.text:6F3BBB30 number          = dword ptr  4
.text:6F3BBB30
.text:6F3BBB30                 mov     eax, [esp+number]
.text:6F3BBB34                 mov     ecx, CGameWar3__Instance
.text:6F3BBB3A                 push    esi
.text:6F3BBB3B                 push    eax
.text:6F3BBB3C                 call    CGameWar3__GetPlayer
.text:6F3BBB41                 mov     ecx, CGameWar3__Instance
.text:6F3BBB47                 mov     esi, eax
.text:6F3BBB49                 call    CGameWar3__GetGameState
.text:6F3BBB4E                 push    0
.text:6F3BBB50                 push    esi
.text:6F3BBB51                 mov     ecx, eax
.text:6F3BBB53                 call    CGameState__GetAgentHandle
.text:6F3BBB58                 pop     esi
.text:6F3BBB59                 retn
.text:6F3BBB59 Jass__Common__Player endp

16
На самом деле целая куча. Например битая моделька или текстура, утечки. Еще у меня как то был случай, когда я использовал даммика для каста способности, не выдав ему атаку и когда даммик заканчивал каст, то был промежуток времени, между окончанием каста и исчезнованием даммика, который хоть и измерялся в милисекундах, но даммику его хватало, чтобы закрашить игру, потому что у него не было атаки, а рядом был враг. Причем срабатывало это только в том случае, если даммик принадлежал нейтрально-враждебному игроку. Движок обращался за атакой и получал nullprt...
13
  1. Утечки 2. Скрытые кнопки 3.Поломанная модель(но тут не помню краш или вылет) 4.Деформация земли (сюда же относится способность топот горного короля) 5. Молнии могут крашить при неправильном использовании 6.Мемхак 7. Действия с мертвыми (ауры и т.д) 8. xgm.guru/p/wc3/Fatalnaya-oshibka-u-artilerii-XUc 9. Функции с установкой высоты по Z 10. Превращение юнитов в героев и обратно
возможно еще есть
Загруженные файлы
7
SoulRazor, А скрытие кнопки парулировать (0, -11) может крашануть?
7
Нашел такую прогу Jass View
Она позволяет увидеть последний триггер перед фаталом я так понял?
19
Так что в итоге показала программа? В момент краша исполнялся какой-то скрипт?
Еще, если бы ты выложил файл с краш-репортом, то было бы больше шансов понять причину.
По скриншоту понятно лишь то, что крашнулось в методе CAgent::GetParent.
Загруженные файлы
7
IceFog, вот вот, не могу теперь поймать этот фатал. Он возник случайно и насторожил меня)
Создал пустую карту и пытаюсь сымитировать фатал пробуя разные варианты, работает только вылет юнита за пределы карты и отрицательный индекс игрока. Но вот на готове сижу, если на своей карте возникнет фатал, то сразу запущу прогу.
Краш-репорт - это .dmp файл?
19
Была вызвана следующая цепочка методов:
CAbilityMorph::OnEvent
CAbilityMorph::FinishMorphing
CAbility::EnableOrders
CAbility::ShowUI
CAgent::GetParent
При попытке получить владельца некой способности превращения был получен краш из-за нулевого указателя.
Странно что, судя по моим наблюдениями, содержащее владельца поле CAbility::m_owner_unit не было nullptr. Краш произошел при попытке обратиться к вышестоящему агенту через другой способ, который требует наличия сетевого ID у объекта. Возможно, способность уже была убита, но кто-то всё равно вызвал её обработчик событий.
19
Принятый ответ
ESI=0CFB7EAC
В краш репорте засветился указатель на способность. В .dmp файле сохранена память стека потоков и еще некоторые регионы памяти. Среди них оказалась и область со способностью, в которой виден её равкод: 0x41304F4A или A0OJ. Эта способность основана на Aave (CAbilityAvengerForm).
Также видно равкод владельца — Hmgd.
Что на счет события — во время моих тестов оно срабатывало в начале и в конце перевополощения.
Загруженные файлы
16
IceFog, и вот ты еще одного кодера выручил, выяснив, какая именно абилка вызывает фатал. На самом деле большое тебе спасибо, я до сих пор помню и благодарен, как ты мне помог с моим параличом у кастомного героя.
7
В общем, у меня походу не явный фатал, иногда срабатывает, а иногда нет. Подозреваю что это обращение к обнуленному юниту.
32
Вручение 'ANeg' и её клона не героям, абилка попытается настроить иконки для изучения но не найдет их, так как она тупо идет по смещению Адресс юнита + оффсет, по которому лежит 'Aher' способность героя (красный плюс), поэтому её нельзя вручать не героям (да близарды редиски), аналогично ведут себя книги на увеличение характеристик героя, игра падает с фаталом. Обычные предметы на + к статам, проверяют является ли владелец героем.
7
A0OJ - эта абилка пустышка, внутри которой вручается руна, которая содержит способность морфа на основе Aave (Сфинкс). В общем наземный герой превращается в летающего.
ChatGPT пишет что после передачи руны герою, не стоит с героем делать действия, так как в этот момент идет пересборка героя. Например, не менять ману герою:
call UnitAddItem(caster, it) //Даем руну-пустышку
call SetUnitState(caster, UNIT_STATE_MANA, mana) //Корректируем ману
Возможно из-за этого идет фатал, не знаю.
Старый код
//Эта функция чтобы определить какую руну дать в зависимости кто кастанул Дейдара или Какаси?
function WhoseItemDeidaraOrKakasi takes unit u returns integer
    local integer unitTypeId = GetUnitTypeId(u)

    //1) D E I D A R A
    if unitTypeId == HERO_DEIDARA then
        return 'I03B'   //Deidara Up
        
    //2) D E I D A R A    F L Y
    elseif unitTypeId == HERO_DEIDARA_FLY then
        return 'I03C'   //Deidara Down
        
    //3) K A K A S H I
    elseif unitTypeId == HERO_KAKASHI then
        return 'I001'   //Kakasi Up
        
    //4) K A K A S H I   F L Y
    elseif unitTypeId == HERO_KAKASHI_FLY then
        return 'I003'   //Kakasi Down
    endif
    
    return 0
endfunction



function Fly_Timer takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local unit caster = LoadUnitHandle(Hash, id, 1)
    local real count = LoadReal(Hash, id, 303) + 0.25
    local item it
    local real mana = 0
    local integer c = LoadInteger(Hash, id, 999)    //Отсчет над головой врага. Равен длительностью морфа
    local texttag tt = LoadTextTagHandle(Hash, id, 1111)
    local real life = GetWidgetLife(caster)
    
    
    //Время морфа не истекло, мы живы и мы не запаузены перед дуэлью
    if c > 0 and life > 0.405 and not IsUnitPaused(caster) then
    
        if count == 1 then
            set count = 0
            set c = c - 1
            call SetTextTagVisibility(tt, true)
            call SetTextTagPosUnit(tt, caster, 75)
            call SetTextTagText(tt, I2S(c), (0.023))
        elseif count == 0.75 then
            call SetTextTagVisibility(tt, false)
        endif
        
        call SaveReal(Hash, id, 303, count)
        call SaveInteger(Hash, id, 999, c)
                
    //Мы мертвы, значит длительность морфа обнуляем. Дальше смотрим ниже, следующее условие...
    elseif life < 0.405 then
        set c = 0 //Чтобы вернуть в наземное состояние
        call SaveInteger(Hash, id, 999, c)
        call SetTextTagVisibility(tt, false)
    //Длительность морфа истек или мы только что возродились после смерти
    elseif c <= 0 and life > 0.405 then
        call DestroyTextTag(tt)
        set mana = GetUnitState(caster, UNIT_STATE_MANA)
        set it = CreateItem(WhoseItemDeidaraOrKakasi(caster), GetUnitX(caster), GetUnitY(caster))
        call UnitAddItem(caster, it)
        call RemoveItem(it)
        call SetUnitState(caster, UNIT_STATE_MANA, mana)
        call RemoveSavedHandle(Hash, GetHandleId(caster), StringHash("FlyTimer"))
        call PauseTimer(t)
        call DestroyTimer(t)
        call FlushChildHashtable(Hash, id)
    endif
    
    set t = null
    set caster = null
    set it = null
    set tt = null
endfunction



function Fly_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)
    local item it
    local real mana = GetUnitState(caster, UNIT_STATE_MANA) //Чтобы нормализовать ману
    local integer c = R2I(GetUnitState(caster, UNIT_STATE_MAX_MANA) / 50) //Отсчет над головой врага. Он равен длительности способности
    local timer tempT
    local texttag tt = TextTagPermanent(I2S(c), caster, 75, 10, 0, 100, 60, 0, true, false)


    
    //=========Если использовать морф еще раз, поверх первой=========//
    set tempT = LoadTimerHandle(Hash, GetHandleId(caster), StringHash("FlyTimer"))
    if tempT != null then
        set id = GetHandleId(tempT)
        set caster = LoadUnitHandle(Hash, id, 1)
        set mana = GetUnitState(caster, UNIT_STATE_MANA)
        call SetUnitState(caster, UNIT_STATE_MANA, mana)
        set it = CreateItem(WhoseItemDeidaraOrKakasi(caster), GetUnitX(caster), GetUnitY(caster))
        call UnitAddItem(caster, it)
        call RemoveItem(it)
        call DestroyTextTag(LoadTextTagHandle(Hash, id, 1111))
        call RemoveSavedHandle(Hash, GetHandleId(caster), StringHash("FlyTimer"))
        call FlushChildHashtable(Hash, id)
        call PauseTimer(tempT)
        call DestroyTimer(tempT)
        set tempT = null
        set id = GetHandleId(t)
        set caster = GetTriggerUnit()
    endif
    //=====================//
    
    
    set it = CreateItem(WhoseItemDeidaraOrKakasi(caster), GetUnitX(caster), GetUnitY(caster)) //Руна-пустышка с морфом внутри
    call UnitAddItem(caster, it) //Даем руну-пустышку Дейдаре
    call RemoveItem(it) //Против утечек
    call SetUnitState(caster, UNIT_STATE_MANA, mana) //Корректируем ману
    call SaveTimerHandle(Hash, GetHandleId(caster), StringHash("FlyTimer"), t)
    call SaveUnitHandle(Hash, id, 1, caster)
    call SaveInteger(Hash, id, 999, c)
    call SaveTextTagHandle(Hash, id, 1111, tt)
    call TimerStart(t, 0.25, true, function Fly_Timer)
    
    set caster = null
    set t = null
    set it = null
    set tt = null
endfunction



function Fly_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == ABIL_FLY
endfunction



function InitTrig_Fly takes nothing returns nothing
    set gg_trg_Fly = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Fly, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(gg_trg_Fly, Condition(function Fly_Conditions))
    call TriggerAddAction(gg_trg_Fly, function Fly_Actions)
endfunction

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.