В краш репорте засветился указатель на способность. В .dmp файле сохранена память стека потоков и еще некоторые регионы памяти. Среди них оказалась и область со способностью, в которой виден её равкод: 0x41304F4A или A0OJ. Эта способность основана на Aave (CAbilityAvengerForm).
Также видно равкод владельца — Hmgd.
Что на счет события — во время моих тестов оно срабатывало в начале и в конце перевополощения.
При попытке получить владельца некой способности превращения был получен краш из-за нулевого указателя.
Странно что, судя по моим наблюдениями, содержащее владельца поле CAbility::m_owner_unit не было nullptr. Краш произошел при попытке обратиться к вышестоящему агенту через другой способ, который требует наличия сетевого ID у объекта. Возможно, способность уже была убита, но кто-то всё равно вызвал её обработчик событий.
Так что в итоге показала программа? В момент краша исполнялся какой-то скрипт?
Еще, если бы ты выложил файл с краш-репортом, то было бы больше шансов понять причину.
По скриншоту понятно лишь то, что крашнулось в методе CAgent::GetParent.
darkowlom, связной список варкрафта является шаблонным типом из C++, так что для каждого варианта этого типа генерируется новый набор кода. Поэтому недостаточно найти одно место в коде и пропатчить его — необходимо найти все сгенерированные реализации, сколько бы их там ни было (кто знает сколько их там тысяч).
Вот тебе для примера краш одного игрока, который, как я полагаю, использовал подобный патч:
This application has encountered a critical error:
FATAL ERROR!
Program: D:\wc3\Warcraft III 1.26a LTD\War3.exe
Exception: 0xC0000005 (ACCESS_VIOLATION) at 0023:6F7C4BC2
The instruction at '0x6F7C4BC2' referenced memory at '0x7DB1FF4F'.
The memory could not be 'written'.
Вот как выглядит это место в коде игры:
До инверсии число 0x7DB1FF4F было указателем 0x824E00B0, который как раз находится в верхней половине памяти, которая обычно недоступна.
После того как связной список наткнулся на это место, произошел краш из-за попытки записи в недоступную память.
Это еще повезло, что неудалось произвести запись, а иначе можно было перезаписать случайную память и затем недоумевать, почему в карте творится всякая чертовщина.
Связные списки варкрафта оптимизированы с учетом доступности лишь первых 2 ГБ памяти. Если после разблокировки второй половины из неё будет выделен фрагмент для такого списка, то стоит ждать непредсказуемых последствий: случайные повреждения памяти, фатальные ошибки из-за обращений к недоступной памяти.
Спустя почти год перерыва я таки заглянул снова в игровые внутренности, но хороших новостей у меня нет.
Судя по тому что я вижу, во внутренних типах игры, хранящих информацию об игровой комнате, жестко ограничен размер строки с путем к карте — исправлять такое уже намного сложнее.
И даже если бы я это сделал, то еще остается проблема передачи информации по сети между клиентами, ведь придется уже менять протокол BNET/LAN на всех клиентах, чтобы это заработало.
Мод ничего не может сделать с ограничениями по сети, но всё равно от него есть польза, ведь так хотя бы не придется гадать, почему твоя карта не отображается в списке.
Dam3w, не могу утверждать на счет всех функций встроенных в этот файл, но вероятно он загружает все .mix файлы в папке с игрой уже на стадии инициализации DirectX, которая обрабатывается до игрового интерфейса. Не уверен, правда, будет ли он работать в режиме OpenGL.
Vampir_kolik, мне пока не удается найти исходники. В крайнем случае, можно было бы переписать с нуля, ведь кода там немного, но не знаю, найдется ли у меня на это время.
Пока я посоветовал бы тебе поискать ошибки у себя в коде, ведь RedirectCalls сам по себе не создает утечек и вообще никак не связан с движением юнитов. Он лишь создает в памяти функцию обертку на ASM для каждой JASS функции, что скрипт передает нативкам в качестве callback'ов. Сколько у тебя JASS callback'ов, столько и будет выделено памяти.
FDG89K, думаю, причина в том, что звуковая система инициализируется уже после графического интерфейса, так что файлы FDF уже были прочитаны к моменту загрузки твоего архив, почему и были проигнорированы.
Для таких модификаций нужно использовать какой-нибудь лаунчер, который загрузит твои MPQ архивы до запуска функции GameMain из Game.dll. Или сделать какой-нибудь мод, который перезагрузит GUI подсистему после твоего mix-архива.
makkad, все любопытствующие могут скачать утекшие бинарники с отладочной информацией и открыть в IDA или подобных программах для изучения.
В патче 1.26a содержимое не отличается.
Содержимое нативок
void __fastcall SetWidgetLife(unsigned int widgetHandle, const unreal *newLife)
{
CWidget *widget; // [rsp+20h] [rbp-18h]
widget = ConvertHandle<CWidget>(widgetHandle);
if ( widget )
widget->SetLife(widget, newLife);
}
void __fastcall KillUnit(unsigned int unitHandle)
{
CUnit *unit; // [rsp+20h] [rbp-18h]
unit = ConvertHandle<CUnit>(unitHandle);
if ( unit )
unit->SetLife(unit, &u_0);
}
Исправлен краш при выборе карты с ошибками в сценарии.
Добавлена поддержка отрицательного уровня отступа (использует '-' вместо табов).
Теперь логируется запуск/остановка потока и его код выхода, а также результат.
Теперь все потоки используют один глобальный уровень отступа, так что дочерние потоки будут логировать "глубже" своих родителей. Спящие потоки все также будут запоминать свой уровень отступа и восстанавливать его при пробуждении.
EugeAl, не понимаю, чего ты хочешь добиться.
Чтобы оно было "по дефолту", нужно чтобы близарды сами добавили эти нативки.
Если же хочется пользовательских модификаций, то нужно ставить моды, а как иначе?
LastUchiha, учти, что цикл также будет исполнять свои инструкции для проверки условий и прыжков. Можешь посмотреть во что компилируется функция при помощи JassView. Метки для прыжков это тоже инструкции, но которые ничего не делают и интерпретатор игнорирует их.
Если хочешь, чтобы накладные расходы цикла не сильно влияли на результат, то можешь совершать действие в его теле достаточно много раз, чтобы затенить их.
пример
function BenchmarkComparison takes nothing returns nothing
local integer i = 0
local integer start
local integer elapsed
call SetOperationLimitEnabled(false)
set start = GetTickCount()
loop
exitwhen i > 1000000
// ТВОЁ ДЕЙСТВИЕ
// ТВОЁ ДЕЙСТВИЕ
// ...
set i = i + 1
endloop
set elapsed = GetTickCount() - start
call BJDebugMsg("Time elapsed: " + R2S(elapsed / 1000.0) + " seconds.")
endfunction
Можно сделать два варианта действия для этой функции:
1
if MUIID == 0 then
set MUIID = GetHandleId( GetExpiredTimer() )
endif
После чего сделай функцию, которая многократно выполняет интересующее тебя действие и засеки время до и после исполнения, затем вычисли разницу.
Важно сделать так, чтобы функция исполнялась достаточно долго для того, чтобы погрешность была не слишком велика. Измерять одно действие смысла мало, а вот повторить его миллион раз уже может иметь смысл, чтобы на выполнение задачи ушли секунды, а не наносекунды, что может привести к погрешности ±100%.
Не забудь отключить лимит операций с помощью вызова SetOperationLimitEnabled(false), а иначе виртуальная машина убьет поток из-за превышения лимита.
Meddin, протестировал на карте DotA LoD 6.83i и не смог словить крашей ни после сохранения и последующей загрузки, ни после нажатия на кнопку "Начать заново".
Возможно, у тебя стоят какие-нибудь конфликтующие моды.
Без отчёта об ошибке и дампа виртуальной машины сложно что-то сказать.
This mod was written without the ability to support multiple versions, so adding support for new ones will be more difficult.
The source code is open, so you can add support for your version yourself, but I have no motivation to do that: on those rare occasions when I log into the game, I use version 1.26a. And I use other tools for debugging, so I haven't had any use for this mod yet.
Meddin, у тебя не сохраняется лог?
По идее, он должен сохраняться в любых обстоятельствах, ведь каждую строчку я сразу передаю функции FileWrite, а дальше уже дело за операционной системой.
Когда просишь помочь с крашем, то стоит скидывать отчет об ошибке, создаваемый игрой при сбое (файлы .txt и .dmp с датой краша в имени).
Также есть программа, которая позволяет просматривать состояние скрипта карты. Если повезет, с ней сразу раскроется причина.
Она умеет сохранять слепок состояния виртуальной машины, который ты тоже можешь скинуть сюда.
EasyMoney, в чем ты её пытаешься открыть? Если в редакторе, то она и не должна в нём открываться, ведь написано же, что она защищена.
А в игре она у меня запускается через WarCraft версии 1.26a.
» WarCraft 3 / Причины FATAL ERROR?
Ред. IceFog
» WarCraft 3 / Причины FATAL ERROR?
Также видно равкод владельца — Hmgd.
» WarCraft 3 / Причины FATAL ERROR?
» WarCraft 3 / Причины FATAL ERROR?
Еще, если бы ты выложил файл с краш-репортом, то было бы больше шансов понять причину.
По скриншоту понятно лишь то, что крашнулось в методе CAgent::GetParent.
Ред. IceFog
» WarCraft 3 / MemoryPatch (1.26a) - Расширение лимита оперативной памяти
После того как связной список наткнулся на это место, произошел краш из-за попытки записи в недоступную память.
» WarCraft 3 / MemoryPatch (1.26a) - Расширение лимита оперативной памяти
» WarCraft 3 / Снятие ограничения на длину пути в списке карт
Ред. IceFog
» Прочее / Деквадратизированные текстуры для OneShot
» WarCraft 3 / Самоподключающийся архив
» WarCraft 3 / Работа с нативными функциями
» WarCraft 3 / Самоподключающийся архив
Ред. IceFog
» WarCraft 3 / Jass MythBusters
В патче 1.26a содержимое не отличается.
» WarCraft 3 / Журналирование вызовов JASS
Прокрутить к ресурсу
Ред. IceFog
» WarCraft 3 / Неограниченое описание
Прокрутить к ресурсу
» WarCraft 3 / Открытая виртуальная машина
Чтобы оно было "по дефолту", нужно чтобы близарды сами добавили эти нативки.
Если же хочется пользовательских модификаций, то нужно ставить моды, а как иначе?
Ред. IceFog
» WarCraft 3 / Насколько быстро выполняется if ? - [Jass]
» WarCraft 3 / Журналирование вызовов JASS
Нужно будет потом глянуть.
Ред. IceFog
» WarCraft 3 / Насколько быстро выполняется if ? - [Jass]
natives.mix в папку с игрой и объяви в коде нативки:
Ред. IceFog
» WarCraft 3 / Журналирование вызовов JASS
Возможно, у тебя стоят какие-нибудь конфликтующие моды.
Без отчёта об ошибке и дампа виртуальной машины сложно что-то сказать.
» WarCraft 3 / Журналирование вызовов JASS
» WarCraft 3 / Журналирование вызовов JASS
» WarCraft 3 / Журналирование вызовов JASS
По идее, он должен сохраняться в любых обстоятельствах, ведь каждую строчку я сразу передаю функции FileWrite, а дальше уже дело за операционной системой.
Ред. IceFog
» WarCraft 3 / Помогите (ошибка)
Она умеет сохранять слепок состояния виртуальной машины, который ты тоже можешь скинуть сюда.
Ред. IceFog
» WarCraft 3 / Группы с несуществующими юнитами и FirstOfGroup
» WarCraft 3 / Последний приют 2
А в игре она у меня запускается через WarCraft версии 1.26a.