Jump to content

madf

Сitizens
  • Posts

    4,122
  • Joined

  • Last visited

  • Days Won

    22

Everything posted by madf

  1. Хочется 3-й версии? Спешу разочаровать, ее еще долго не будет. Изменения планируемые на 3-ю версию слишком значительны. Непонятно - это как? Раз в тупик ставит - значит с этим что-то надо делать... Keen говорил, что периодичность повторения бага у него составляла от 2 до 48 часов - по этом и ждем 2 суток. Неплохо было-бы, если бы Keen, Silitra и Dimension отписали.
  2. Это не аллогизмы, это такая логика. Обработка начала месяца - запись и сброс трафика. К стати, перед вызовом в комментарии так и написано. Тут на самом деле полезного ничего не происходит, но на всякий случай, если вдруг потом навернем логику Connect/Disconnect Параметр true в этих двух вызовах говорит о том, что это не настоящие Connect и Disconnect. Физического отключения пользователя не происходит. Это, я думаю, из USER::MidnightResetSessionStat? Но там тоже в параметрах указано true. Собственно, те-же яйца, что и в USER::ProcessNewMonth.
  3. Я жду еще пару суток, после чего выкладываю beta-версию.
  4. В файле stglibs/common.lib/common.cpp в строке 794 заменить uint16_t на uint32_t; в строке 801 заменить uint16_t на uint64_t. Авторизация раньше тупила потому, что на самом деле пользователь не авторизовался. Благодаря этим исследованиям еще один баг обнаружился
  5. 2.405 последний
  6. Условия возникновения бага достаточно "узкие", по этому он не у всех проявляется и его так сложно было найти.
  7. inetaccess.cpp > 20:07:17 > --->>> cash: 10000 inetaccess.cpp > 20:07:17 > --->>> cash: 4135 И что думает об этом авторизатор? Проходит авторизация или нет?
  8. Смотри предыдущий пост
  9. Теоретическое обоснование Когда пакет добавляется в трафкаунтер (TRAFFCOUNTER::Process) для него проверяется наличие авторизованных пользователей, для которых он может быть исходящим или входящим. Если таковые существуют - их итераторы записываются в поля userU и userD и помечаются соответствующие флаги userUPresent и userDPresent (для итератора не существует определенного NULL-состояния). После этого пакет попадает во внутреннее дерево пакетов трафкаунтера. При чем это происходит даже в том случае, если не существует авторизованных пользователей, которым бы этот пакет принадлежал. Когда пакет становится "старше" FLUSH_TIME - трафкаунтер пытается отдать информацию о трафике пользователям из полей userU и userD, если таковые имеются в наличии. Если их нет - пакет живет до REMOVE_TIME и после этого стирается. Когда пользователь авторизуется для него происходит вызов TRAFCOUNTER::AddUser и USERS::AddToIPIdx. Например: traffcounter.cpp > 18:05:08 > AddUser: test users.cpp > 18:05:08 > Add IP Idx Первый вызов "пробегает" по всему дереву пакетов и проверяет, а не принадлежат ли какие-то из них новому юзеру. Если таковые находятся - для них выставляется соответствующий итератор и флаг. Второй вызов добавляет пользователя в индекс по ip-адресам. Эти два вызова следуют последовательно. При чем первый не блокирует добавление нового трафика. Если пользователь успеет сгенерировать хотя-бы один пакет в этот момент, а трафкаунтер успеет его принять и произвести поиск по индексу - этот пакет добавится в дерево, как не принадлежащий этому пользователю. Соответственно, его итераторы будут указывать в никуда. После этого пользователь попадает в индекс и все работает хорошо. И если пользователь остается авторизованным как минимум REMOVE_TIME времени - "плохой" пакет просто страется. А если пользователь отключается до того, как этот пакет пропадет из дерева - начинается цепочка вызовов, которая в конце концов приводит нас к TRAFFCOUNTER::DelUser. Он "пробегает" по дереву, в поисках пакетов, принадлежащих уходящему юзеру. И естественно он находит "плохой" пакет. Далее следует проверка ситуаци, когда в пакете обозначен этот пользователь, но итератор указывает не на него - это аварийная ситуация, потому что такого не может быть никогда. Тут старгейзер законно упадет, информируя о том, что в системе произошло нечто СТРАШНОЕ. Потому что такого действительно никогда не может произойти. Но это не наш случай. Условие не является сильным. Проверка по ip, userUPresent/userDPresent и итератору пропустит пакет в одном-едиснтвенном случае: если пакет действительно принадлежит пользователю, но userUPresent или userDPresent не установлен (и соответствующие итераторы невалидны). Тут-то как раз и происходит то, что описано в предыдущих постах. Мне удалось смоделировать такую ситуацию вставкой 5-секундной задержки на завершение вызова TRAFFCOUNTER::AddUser (уже после того как все пакеты просмотрены). Далее я авторизовался в системе, но Inetaccess еще 5 секунд продолжает гореть красным. В это время я быстро сгененрировал несколько пакетов, дождалася "позеленения" Inetaccess и разавторизовался. В результате я получил такое: traffcounter.cpp > 18:11:34 > DelUser: test traffcounter.cpp > 18:11:34 > Counting upload packet: 192.168.1.18 -> 195.5.61.70 traffcounter.cpp > 18:11:34 > Counting upload packet: 192.168.1.18 -> 195.5.61.68 traffcounter.cpp > 18:11:34 > Counting upload packet: 192.168.1.18 -> 192.168.1.7 traffcounter.cpp > 18:11:34 > Counting download packet: 192.168.1.7 -> 192.168.1.18 traffcounter.cpp > 18:11:34 > Counting abandoned packet: 192.168.1.18 -> 195.5.61.70 traffcounter.cpp > 18:11:34 > ALARM!!!!!!!!!!!!!!!!!!!!!!!!!!!! traffcounter.cpp > 18:11:34 > Counting abandoned packet: 192.168.1.18 -> 195.5.61.68 traffcounter.cpp > 18:11:34 > ALARM!!!!!!!!!!!!!!!!!!!!!!!!!!!! traffcounter.cpp > 18:11:34 > Counting upload packet: 192.168.1.18 -> 192.168.1.255 users.cpp > 18:11:34 > Del IP Idx Естественно, stargazer не упал, т.к. я поставил себе дополнительную проверку, которую порекомендовал выше. Но заодно я поставил и "ловушку", которая сработала и показала, что такая ситуация теоретически возможна. В реальной жизни такое может происходить когда пользователь генерирует большое количество пакетов даже еще не авторизовавшись в системе.
  10. Так, есть идея. В файле traffcounter.cpp в методе DelUser заменить условия: (у меня это строка 612) if (pi.first->second->second.dirU < DIR_NUM) на if (pi.first->second->second.dirU < DIR_NUM && pi.first->second->second.userUPresent) и (у меня это строка 636) if (pi.first->second->second.dirD < DIR_NUM) на if (pi.first->second->second.dirD < DIR_NUM && pi.first->second->second.userDPresent)
  11. Нашел интересную закономерность: когда ты первый раз сообщил о падении и предоставил лог - в STG_LOCKER передавался указатель на мьютекс с адресом 0x1F54 (явно вне адресуемого пространства процесса). Потом был еще лог со значением 0x1F60 (тоже рядом) и вчерашний лог - тоже с 0x1F60. Таким образом, в user.cpp:884 происходит вызов с уже невалидными параметрами. Далее интересные вещи творятся здесь (Keen): http://local.com.ua/forum/index.php?showto...amp;#entry99601 И здесь (Silitra): http://local.com.ua/forum/index.php?showto...mp;#entry100535 А именно (Keen): #6 0x080ab985 in USER::Unauthorize (this=0x83aade8, auth=0x80f0d80) at user.cpp:574 - тут вроде все хорошо, запоминаем this #3 0x080a4873 in TRAFFCOUNTER::DelUser (this=0x80f01a0, user= {_M_node = 0x83aade0}) at traffcounter.cpp:616 - тут тоже хорошо (_M_node - внутренности итератора, допускаем смещение на 8 байт ДО юзера) #2 0x080ac432 in USER::AddTraffStatU (this=0x8, dir=1, ip=3843359321, port=443, len=48) at user.cpp:884 - тут все плохо. this не может быть 8. И тут похоже (Silitra): #6 0x080a756f in USER::Unauthorize (this=0x28d22008, auth=0x2844e000) at user.cpp:583 - все так-же хорошо, обращаем внимание на this #3 0x0809f282 in TRAFFCOUNTER::DelUser (this=0x2843b060, user={_M_node = 0x28d22000}) at traffcounter.cpp:605 - тоже неплохо (такое-же смещение на 8 байт) #2 0x080a802a in USER::AddTraffStatU (this=0x8, dir=0, ip=3832810564, dport=59127, sport=47747, len=131) at user.cpp:911 - тут все поломалось В TRAFFCOUNTER::DelUser вызовы AddTraffStatU не используют полученный итератор а производят поиск по внутреннему индексу. Похоже, портится индекс... Пошел изучать дальше.
  12. Плохо-то как... Я уже начинаю подозревать сам мускул
  13. Лог valgrind получил, спасибо. Там много интересного!
  14. Трафик считает не "ключ". Трафик считается на сервере (или на сенсоре, если у вас NetFlow).
  15. Попробуй опять-же, запустить из-под gdb. После падения сделать bt В первой строке будет что-то вроде: #0 0xf730db38 in MYSQL_STORE::GetMessage () from /usr/lib/stg/mod_store_mysql.so 0xf730db38 - адрес (будет по идее другой) Сделай list *0xf730db38 (только подставь тот адрес который у тебя будет вместо 0xf730db38)
  16. А модуль mysql - тот который идет в архиве?
  17. "База на спарке, сервер СТГ на интеле он подключается к БД на спарк " А, вот даже как... Блин, почему оно номера строк не показывает
  18. А падает все время на одном и том-же юзере? Выхлоп valgrind был бы очень полезен...
  19. Сборка была отладочной? Попробуй запустить старгейзер из-под gdb: $ gdb /path/to/stargazer (gdb) run и когда упадет сделать (gdb) bt И еще попробуй запустить старгейзер из-под valgrind: $ valgrind /path/to/stargazer Естественно интересует выхлоп в момент падения. PS: сообщение "Backtrace stopped: previous frame identical to this frame (corrupt stack?)", судя по гуглю, характерно для gdb на не-x86 архитектурах. Боюсь, что из этого ничего не получится
  20. Сделать отладочный билд, получить корку (перед запуском выполнить ulimit -c 10000), после этого $ gdb ./stargazer (gdb) core-file <файл_корки> (gdb) bt И выхлоп мне
  21. projects/stargazer/build:167 - заменить 0 на 1 в строке if [ $? == 0 ]
  22. Еще один патч. Применять как и предыдущий. Запустишь, попробуешь авторизоваться, а потом кинешь мне консольный лог старгейзера. endianess.patch.txt
  23. Хм, а при запуске точно используются либы и плагины текущей сборки? Не могло случиться такого, что stargazer продолжает использоват старые либы и плагины? Или новые либы и старые плагины?
  24. Покажи, плиз, шапку компиляции (там где проверки проходят)
×
×
  • Create New...