• Страница 1 из 1
  • 1
Модератор форума: No_MaTTeR, staford11  
MaNGOS One - краш при добивании прислужников нпц дотами
Explain
Капрал
Приветствую. В общем ядро крашится, если добить скажем суккуба пирата-лока(или любого другого прислужника любого другого моба) в тернистой долине какой-либо дотой. За обычными мобами такого не наблюдается. Дебажить я не мастер - потому прошу помочь.
Место краша: https://ibb.co/dEmdf7
Репозиторий: https://github.com/mangosone/server
Файл: https://github.com/mangoso....Auras.h
Единственное, что я смог сделать - это посмотреть значение переменной "uint32 m_in_use" перед крашем - 3722304989. Но немного не понимаю, как переменная достигает такого значения, перед вычитанием стоит проверка "if (m_in_use)", а при сложении я в принципе не вижу, чтобы переменная увеличивалась даже до значения 3.
P. S. Использую MaNGOS One в образовательных целях, потому прошу не придираться к Win10 и перегонять на CMaNGOS.
Буду благодарен любой помощи.
Сообщение # 1 отредактировано Explain - Воскресенье, 04.03.2018, 13:57
p620
Маршал
С технической точки зрения:
В режиме отладки обычно предусмотрено особое поведение аллокатора, предписывающее, в числе прочего, заполнять память особыми бинарными паттернами в определенных ситуациях, дабы лишний раз указать программисту на недопустимость проблемного кода. Таким образом предоставленное Вами значение дает существенное количество информации для разрешения возникшей проблемы.
Код
dec(3722304989) = hex(DDDDDDDD)
Этот паттерн устанавливается на память кучи, которая была освобождена. Семантически такая память более недоступна для программы; попытка взаимодействия с ней была пресечена, о чем и повествует встреченная Вами ошибка. Так или иначе, необходимо ознакомиться с родительским контекстом, дабы иметь возможность сделать какие-либо более конкретные выводы. Для этого Вы можете обратиться к стеку вызовов и представить здесь соответствующие контексты.
С логической точки зрения:
В первую очередь я бы проверил, воспроизводима ли проблема в более общем случае (например на любом призванном существе где/когда-угодно). Предположительно где-то в ядре имеет место нарушение очередности обработки аур (или даже существ, а то и еще чего более крупного), что приводит к попыткам обращения к объектам, которые уже не существуют.
Сообщение # 2 отредактировано p620 - Понедельник, 05.03.2018, 20:15
Explain
Капрал
Цитата p620 ()
Так или иначе, необходимо ознакомиться с родительским контекстом, дабы иметь возможность сделать какие-либо более конкретные выводы. Для этого Вы можете обратиться к стеку вызовов и представить здесь соответствующие контексты.

Прошу прощения, но не совсем понимаю, что подразумевается под "родительским конткекстом"(гуглил - не нагуглил), на счёт остального понял, большое спасибо за объяснение.
Прикрепляю стек вызовов:
https://ibb.co/hQsr3S
Цитата p620 ()
С логической точки зрения:
В первую очередь я бы проверил, воспроизводима ли проблема в более общем случае (например на любом призванном существе где/когда-угодно). Предположительно где-то в ядре имеет место нарушение очередности обработки аур (или даже существ, а то и еще чего более крупного), что приводит к попыткам обращения к объектам, которые уже не существуют.

Проверил более досконально. Проблема воспроизводится только с существами, призванными с помощью эффекта 56 SPELL_EFFECT_SUMMON_PET. Под именем существа написано, что это Minion. C петами охотников или c существами от эффекта 28 SPELL_EFFECT_SUMMON проблемы нет.
Сообщение # 3 написано 05.03.2018 в 22:17
p620
Маршал
Цитата Explain ()
Прошу прощения, но не совсем понимаю, что подразумевается под "родительским контекстом"

На простом примере:
Код
void b(void); void a(void) { b(); }

В данном случае для "b" родительским контекстом (местом вызова, ибо подпрограмма) будет тело "a". По сути это не термин, а просто короткий синоним длинного описания. Если некоторое описание событий (в данном случае программный код: инструкции + данные) формирует текущий контекст, то родительским контекстом будет описание тех событий (или кода), которые привели к возникновению искомых.
Что до Вашей проблемы - нужно просматривать все эти вызовы, прорабатывая теорию того, что они уже происходить не должны, для начала. Необходимо выяснить, какая именно сущность уже не существует. Можете посмотреть, удален ли уже только экземпляр ауры, или же все существо. Так определится контекст с ошибкой, на просторах которого ее и потребуется выискивать.

Добавлено (06.03.2018, 00:56)
---------------------------------------------

Цитата Explain ()
Проблема воспроизводится только с существами, призванными с помощью эффекта 56 SPELL_EFFECT_SUMMON_PET.

Вот это, кстати, тоже может Вам существенно помочь. Как установите проблемный контекст - выясняйте, в чем заключается различие реализации существ такого типа и всех остальных.
Сообщение # 4 отредактировано p620 - Вторник, 06.03.2018, 00:55
Explain
Капрал
Видимо Вы правы, вот вырезка из логов:
Цитата
PeriodicTick: Player Test (Guid: 11) attacked Pet (Petnumber: 43 Guid: 3) for 206 dmg inflicted by 25368
DealDamageStart
deal dmg:206 to health:196
DealDamage Player Test (Guid: 11) Killed Pet (Petnumber: 43 Guid: 3)
DealDamageAttackStop
SET JUST_DIED
Aura 3 now is remove mode 4
Aura 79 now is remove mode 0
AURA MOD DAMAGE type:126 negative:0
Aura 79 now is remove mode 0
AURA MOD DAMAGE type:126 negative:0
Aura 137 now is remove mode 0
Aura 137 now is remove mode 0
Aura 57 now is remove mode 0
Aura 52 now is remove mode 0
Aura 87 now is remove mode 0
DealDamageEnd returned 206 damage - после этого лога получаем краш

Т. е. если я правильно понимаю проблема в том, что ауры уже нет.

Добавлено (06.03.2018, 10:41)
---------------------------------------------
Нашёл такой код в
Код
void Unit::RemoveAura(Aura* Aur, AuraRemoveMode mode)

Может быть комментарии к коду от разработчиков дадут какую-нибудь информацию.
Код
// some auras also need to apply modifier (on caster) on remove
    if (mode == AURA_REMOVE_BY_DELETE)
    {
        switch (Aur->GetModifier()->m_auraname)
        {
                // need properly undo any auras with player-caster mover set (or will crash at next caster move packet)
            case SPELL_AURA_MOD_POSSESS:
            case SPELL_AURA_MOD_POSSESS_PET:
                Aur->ApplyModifier(false, true);
                break;
            default: break;
        }
    }
    else
        { Aur->ApplyModifier(false, true); }

Здесь на краше вызывается блок под оператором "else", поскольку в моём случае mode == AURA_REMOVE_BY_DEATH. Пробовал ради интереса добавлять в условие "if" AURA_REMOVE_BY_DEATH, но изменений не получил.

Добавлено (06.03.2018, 10:43)
---------------------------------------------
Само удаление ауры(сразу после кода выше):
Код
// If aura in use (removed from code that plan access to it data after return)
    // store it in aura list with delayed deletion
    if (Aur->IsInUse())
        { m_deletedAuras.push_back(Aur); }
    else
        { delete Aur; }
Сообщение # 5 отредактировано Explain - Вторник, 06.03.2018, 11:33
p620
Маршал
Здесь я Вам уже не подскажу, поскольку не просматриваются такие вещи по столь маленьким сниппетам, да еще и на форуме. Подозреваю, что Вы на верном пути, впрочем.
Сообщение # 6 написано 06.03.2018 в 15:14
  • Страница 1 из 1
  • 1
Поиск: