Работа любого программиста состоит из рутины и интересных задач. Обычно рутины очень много, а интересного исчезающе мало. Вот про такое, интересное, я и хотел бы поговорить.
Хотя просто говорить скучно, я предлагаю пост в формате квеста — я описываю проблему с которой я сталкивался и подробно отвечаю на наводящие вопросы: что в логе, что на экране, куда посмотреть, чего ответить. Во-первых хочется интерактива, во-вторых если выложить все карты на стол сразу отгадка будет на поверхности и многочасовой секс с кодам будет не оценен.
Если не формат, не интересно, никто не пишет на похапе (а у меня это основной язык) — удаляйте смело, первый пост же у меня.

Tagged with →  

87 Responses to Работа любого программиста состоит из рутины и интересных задач.

  1. Exewhite:

    Итак, вопрос первый:
    Контент-менеджер жалуется что расчудесный FCK editor вместо списка картиночек в папке отображает ошибку. Смотрю исходник — в первой же строчке XML
    «Headers already sent».
    Вопросы/предложения, куда смотреть/что присходило, наводящие вопросы и вообще?

  2. Exewhite:

    Хочу сразу заметить что задачи нифига не тривиальные — то что гуглится или лежит на поверхности я отношу к «рутине» и после такого длинного вступления не выкладывал бы.

  3. SKEVelo:

    плюнул пробел где-то или файл где-то начинается не с

  4. Exewhite:

    не смотря на то что CK editor проект не маленький, а я совсем не усидчивый в течении получаса я облазил ВСЕ файлы которые могли или даже не могли относится к CK — пробелов нет, все верно.

  5. SKEVelo:

    все, я не участвую, витенька параноик

  6. SKEVelo:

    бля парсер.
    *<?php (т.е. перед открывающим тегом что-то есть) или есть закрывающий php тег и мусор после него

  7. SKEVelo:

    а нет, это у него js обновлялка камментов кривая

  8. SKEVelo:

    перед открывающим тегом где-то что-то влезло или после закрывающего.

  9. SKEVelo:

    файрбагом посмотри что сервер отдает

  10. Exewhite:

    смотрел при помощи wireshark — таки да, перевод строки перед ошибкой похапе.
    Поиск по кода перевод строки не нашел.
    хинт: на сервере есть СВН
    хинт2: СВН показывает что файлы проекта не менялись, а еще вчера все работало

  11. SKEVelo:

    ну когда все работало, а потом сломалось, при том, что никто ничего не трогал (если верить свну), то проблема в том, что менялось — настройках сервера/проекта или данных (имена файлов, записи бд)

  12. Exewhite:

    да-да, почесывая яйца я пришел к тому же выводу.

    Но куда копать-то? (это же квест)

  13. SKEVelo:

    ну проверить настройки, менялись ли, проверить другие папки открываются ли с картинками, методом исключений определить область причины =) когда система чужая, сложно конкретные вещи писать

  14. Exewhite:

    1) зашел в /etc, смотрел на список файлов. По дате новых не нашел, недоверчиво закрыл.
    2) Другие папки открываются, статика отдается, html отдается, методом исключений пришли к похапе

  15. Xuagreen:

    похапе тебе в лог насрёт где хедеры обломились и где ты случайно насрал в аутпут. Топаешь туда и чинишь. Вот проблема-то…

  16. Exewhite:

    я же говорил — в лоб задача не решается.

    В логах типичный бред типа:
    PHP Warning: Cannot modify header information — headers already sent in Unknown on line 0

  17. Rerodin:

    Ммм… fck пытается писать что-нибудь куда-нибудь?

  18. Xuagreen:

    тады ясна. Да, тоже такой косяк вспомнил с FCK, давно было, как решал — забыл.

  19. UpaFcuk:

    он же пишет, откуда headers sent

  20. UpaFcuk:

    простите, увидел

  21. Rerodin:

    А вообще — какая версия пхп под прицелом?

  22. UpaFcuk:

    Да выруби нах error reporting для fck. Вообще все wysiwyg — непрофессиональная штука.

  23. RedSm:

    Контент-менеджеры, способные работать с голым html, стоят дороже обычных.

  24. RedSm:

    Русская и английская «с» находятся на одной клавише. Теперь я всегда проверяю.

  25. SKEVelo:

    любая IDE нормальная это подсвечивает =)

  26. LezSpb:

    это рутина или интересная задача?

  27. RedSm:

    А ещё она подсвечивает орфографические ошибки с точки зрения английского языка. И хрен разберешь где ей слово не нравится, а где такая вот ошибка. Говорю о PhpStorm.

  28. SKEVelo:

    я проверку орфографии отключил к херам. а вообще там можно настроить как чего выделять, чтобы легко было отличить синтаксическую от орфографической

  29. ZzoaTa:

    Анекдот про математика и поиск льва в пустыне, не?

    помоему вариниг in Unknown on line 0 пшется когда код в create_function находится

  30. Exewhite:

    дело не в fck, совсем.
    Просто он первый звоночек.

  31. Exewhite:

    5.1.х, но не принципиально

  32. Exewhite:

    да, но это не причем

  33. Exewhite:

    вырубить-то можно. но проблема не в нем — не отсылается хеадер content-type, т.к. в вывод уже что-то упало (перевод строки)

  34. Exewhite:

    нет.
    Что б нагнать немного саспеиенса скажу что создал тестовый файл test.php, в первой строке которого написано, и все равно перевод строки, прямо перед текстом.
    То есть дело не в FCK.

  35. Exewhite:

    это — интересная задача, я настаиваю.

  36. Orref:

    1. Раз скрипты не обновлялись — значит обновился интерпретатор. Обновить CKEditor.
    2. Прикрываем вывод хэдеров — смотрим, с чего начинается вывод. 95% — предупреждение какое-то.
    3. Скрипт, который выводит XML у нас есть, методом золотого сечения за 2 часа даже обезьяна найдёт, где начинается вывод.

  37. Yksin:

    Уверен, в этом виноваты жиды.

  38. Yksin:

    Или, как вариант, хохлы с татарами. Убивай по одному представителю этих наций, пока ошибка не исчезнет.

  39. LezSpb:

    это — унылое гавно.
    скорее всего твой эдитор ставит первый байт с обозначанием кодировки скрипта.
    смотри hexdump -C file.php

  40. Exewhite:

    эдитор — вим, прямо на сервере.
    Если взять любой другой файл в любом другом месте — будет та же фигня.

  41. Xuagreen:

    а я и не сказал, что в нём (:

  42. Exewhite:

    1. PHP не обновлялся, админ на ящик не заходил, больше некому.
    2. Вывод начинается с перевода строки
    3. даже пустой скрипт выводит перед собой перевод строки

  43. Exewhite:

    Интрига затянулась, народ не оценил.

    Итак, после получасового секса с xml/php отсекая ненужное я пришел к выводу что перед любым выводом РНР файла откуда-то берется перевод строки, который ломает все хедеры. Гуглинг (что поверхностный, что не поверхностный) ничего не дал. Опрошенные знакомые гуру задумчиво кивали или говорили что-то не то.

    В итоге я вспомнил про замечательную строчку в конфиге php.ini: auto_prepend_file.
    Протупив минут пять оценивая лог phpinfo в консоли (для которой, оказывается, отдельный PHP) я таки нашел что у нас появился новый скрипт, который запускается автоматически перед выводом каждого скрипта.

    С криками «ебтвоюжмать» я открыл этот скрипт, внутри оказалось строк 10 кода, которые анализировали гетовые переменные и, если в гете встречалась переменная cc_number отсылала полученные данные о кредитке на удаленный хост.
    И да, в конце этого чудного скрипта «хакер» оставил лишний перевод строки, он-то мне и валился везде где только можно. Если б не это я бы не нашел этот скрипт еще оочень долго.
    Мораль: никогда не ставьте закрывающий РНР тег.

  44. Oveer:

    мораль: пхп — ебаное говно

  45. PeeZlo:

    Может он конечно и «хакер» в кавычках, но рут то он походу поимел, раз в php.ini залез. Надеяться что он не оставил руткита и бэкдора в данном случае — глупо.

  46. Exewhite:

    само собой.
    Сервер оперативно свернули, развернули в другом месте тщательно проверив все принесенные с собой файлы.

  47. PeeZlo:

    А через что вас ломанули-то? А то просто свернуть-развернуть не обязательно поможет. Дыры то те же самые остались.

  48. Exewhite:

    это дело давно минувших дней, уже и сайта-то такого нет.
    Через багу в движке и ломанули. Код проинспектировали, по логам нашли как и позакрывали все что можно.

  49. Yksin:

    офигеть , какая интересная задача

  50. Exewhite:

    вообще пост предполагал массовые балалайки на тему, но то ли выходные, то ли всем как всегда.
    Она не то что бы интересная, но решение проблемы внезапно нестандартное.

    В любом случае продолжать не хочется, первый блин оказался и последним.

  51. Ycihlam:

    чувак, ты попробуй еще. Такой пост «ночных разговоров» в блоге нужен. Просто пример был не баги, а херни какой-то, извини. Я бы поддержал, но у меня всё какая-то рутина, я и забыл, когда у меня был какой-то интересный баг. А идея хороша

  52. JjrFcuk:

    Меня вот удивляет, как на практически идентичных проектах может все равно вылезти куча рутинного говна на ровном месте. То в миграции какой-то баг засядет, то сессия начнет отваливаться ни с того ни с сего, а в процессе разбирательства перестанет. И 50% времени это не процесс создания чего-то а просто ебля и разгребание чужих как.

    Еще хуже деплой, я точно знаю что в клубке различных путей я так или иначе допущу какую ни будь ошибку или опечатку, потом буду искать черти сколько, потом какое ни будь хитрый запрос не будет пролезать через прокси, потом я перепутаю ключи -u и -U и буду всю ночь материться и читать маны. С удивлением смотрю на людей, которые эту еблю воспринимают как романтичный подвиг.

    А если хочется баек, порадую может быть полезной для кого-то байкой об IE или как я долго вообще не мог понять в чем дело. И второй, очень похожей.

    Сидел, отлаживал js-обвес для интерфейса календаря sharepoint (спасибо, соболезнования принял), развлечение утомительное с элементами реверс-инжиниринга, все держится мягко говоря на микрософтовских соплях, но работает. Все у меня прекрасно, во всех браузерах все ок. Выкладываю в деплой. Через час письмо — все грохнулось, ничего не работет под IE. Открываю, прогоняю в свежих IE — работает. С другого конца меня продолжают уверять, что не работает. Потом уже смотрю на месте — действительно, не работает. Открываю IE-шный отладчик — внезапно работает.

    В результате выяснилась суть бага — у маня осталась отладочная строчка console.log(«что то там»); все бы хорошо, но именно в IE по умолчанию в scope нет никакого console или мокапа для нее. Когда происходит вызов выполнение почему-то тихо глушится и все тут.
    Console создается только когда открывается development tools. Логично, что у меня отладчик был всегда открыт и появления бага я заметить не мог.

    Еще одна байка — у меня аплоадер передавал питону файл, питон шипел и кушал файл и все было хорошо. Потом в методе появилась некая дополнительная проверка, в результате которой метод иногда сразу кидал return, ничего с переданным файлом не делая.

    Почему-то ответ сервера в таком случае вызывал у аплоадера панику. Запускаю на сервере отладчик по брейкоинтам — все ок, заработало. Выключаю — паника. Оказалось, что питон проявил свою ленивую природу и не соизволял получить тело post в том случае, если с ним ничего не делают. То есть post вроде как еще проходит, а сервер уже выплюнул ответ. Отладчик же включал интроспекцию и интересовался всем, что передают, тем самым не давая питону лениться с получением файла.

    В итоге на файл была повешена смывка и все заработало. Полдня ушло ни на что.

  53. Exewhite:

    вот примерно таких баек пост я и хотел.

    С console.log, к сожалению, частая фигня — то же самое происходит с нашим любимым FF, если не запустить фаербаг.

  54. Exewhite:

    Напишу еще байку как я имел долгих три часа жесточайшего дебага. В этот раз не в формате квеста, но может пригодится кому-то.

    Мигрировали проект на другое железо, попутно допиливая и перепиливая фичи. На новом сервере перестали работать куки. В HTTP версии сайта кука ставится, в HTTPS версии кука читается.
    Настройки php.ini, перехват пакетов и их анализ показали что все должно быть прекрасно — параметры session.cookie_domain устанавливается верно, все ну просто обязано надоелться.

    Более того, кука на http версии ставится, браузер ее получает, читает, передает на https версии и… в момент вызова session_start() файл сессии заменяется новым.

    Изначально сессии хранились в мемкеше и разносились между разными серверами, что б это отладить пришлось врубить сохранение в файлы — все то же самое. Видно как данные в файлах сессии подменяются в момент session_start() — в режиме отладки это отчетливо видно.

    По итогам гадания на гугле был найден некий suhosin patch поверх РНР, который шифрует файлы сессий по умолчанию. При этом разные домены не могут его расшифровать.
    Подключается он молча и тихо, в отдельном файле /etc/php5/php.d/suhosin.ini, все параметры в котором закоментированы.
    Что б вырубить эту фишечку надо сначала раскоментировать строку, а потом заменить ее на off.

  55. HabNo:

    Задача: разослать сообщения на почту всем пользователям сайта. Рассылка должна происходить через некий сторонний сервис, который работает медленно.
    Допустим, на сайте 800 пользователей. Предположим, 100 пользователей обрабатываются за 20 сек.
    На хостинге стоит ограничение на время выполнения скрипта — 1 мин.
    Господа знатоки, ваши варианты?

  56. PeeZlo:

    Не назвал бы это «интересной задачей», скорее «неприятным воспоминанием», но тут наверное такие байки хотят собирать.

    Имеется небольшая консольная утилита, которая хитрым образом считает хэш у файлов. Подсчет хеша делается так: функция берет некий численный параметр, использует его как seed для генерации случайных чисел, затем неким образом использует эти числа для подсчета хеша.

    Все вроде работает, потом вдруг оказывается что на другой машине в одном редком случае файлы хешируются не так. После танцев с бубном выясняется, что проблема в алгоритме генерации случайных чисел, который был заимствован из гугла первой ссылкой по запросу Mersenne Twister. Сам алгоритм конечно таков что там хрен поймешь где ошибка (тем более что ошибка-то возникает довольно редко а в основном всё работает). Еще танцы с бубном, находим что ошибка наблюдается только на специфическом значении seed и на машине, у которой int = 64bit, long = 64bit (а в любых других комбинациях работает).

    Смотрим в код алгоритма, обнаруживаем что там весь код на int и long, и #ifdef-ом где-то определяется размер первого. Шлем автору письма недовольства, заменяем алгоритм на другую реализацию (через пару месяцев автор пофиксил, но это уже не важно).

  57. Exewhite:

    какие уж тут варианты?
    Рассылать порциями по 100 штук за раз. после отправки делаем редирект на самого себя чуть ли не мета тегом, отправляем следующую порцию И так пока очередь не кончится.

  58. Oveer:

    вобще-то все ваши проблемы элементарно решаются одной строчкой кода:
    if(!window.console){window.console={log: function(){}}}

  59. HabNo:

    точно! можно рассылать через самого себя. я использовал идею ту же, но чуток сложнее: через аякс.
    сначала загружаю на клиентскую сторону список айдишников, и дальше последовательно в другой скрипт аяксом отправляю куски массива айди.

  60. Ylzen:

    или нормальным билд-скриптом

  61. Kkebad:

    разок обратились ко мне старые клиенты, у которых сайтик на MODx Revo сделан. примитивная статика, никаких каталогов и галерей даже. хостятся на VPS с 256мб памяти, хостер местный, скорость заебись.

    вдруг у меня запарка на работе, а они звонят и говорят что сайт упал. читаю логи, нахожу ругань на phpThumbnail.php или что-то такое. рядом же огроменная картинка. ну думаю ладно, бывает. отписался, мол, уменьшайте картинки на стороне клиента, а то сервер не справляется. VPS, ага. спустя час звонят снова, говорят, пробовали удалить картинку, сайт опять не работает. сел разбираться.

    захожу в админку, поглядывая в консольный top, жму «Сохранить документ», вдруг хуяк-хуяк мускул начинает жрать память и проц. жрет-жрет, начинает жрать своп. память кончается, сервер все. звоню админам, прошу ребутнуть, сам охуеваю, чойта. ну думаю, может софт старый с ошибками (а там PHP 5.1.6 и MySQL 5.0.7.7 из репов), дай-ка проверю дома на виндах.

    скачал значит копию себе, открываю админку, сохраняю документ, хуяк-хуяк, то же самое. кое-как через диспетчер задач прибил процесс, сел думу думать.

    параллельно в гугле искал ответы, ничего толком не нашел.

    обратил внимание, что из дерева документов пропала целая ветка. решил глянуть таблицу с документами. таблица с документами, помимо существенных полей, содержит донельзя родные id и parent_id. в общем, оказалось, у двух документов эти значения перекрестно сохранились (видимо кто-то нажал Stop во время сохранения), каждый думал, что он родитель другого. на сохранении документов сбрасывался кэш, дерево перестраивалось, мускулу сносило крышу от бесконечного цикла.

    вручную поправил, больше инцидент не повторился

  62. JjrFcuk:

    хороший костылек, но до того, что в глобале может не оказаться консоли еще догадаться надо.

  63. KriYes:

    блять, шарепойнт. Как я тебя понимаю.

  64. JjrFcuk:

    я все надеюсь, что внезапно появится человек, который скажет «да не, на самом деле в нем все просто и изящно, просто ты недопонял xxx и yyy, а эта хрень вообще в две строчки решается», но с каждым релизом надежда тает 🙁

  65. KriYes:

    «изящно» и «микрософт» рядом стоять не могут )

  66. JjrFcuk:

    ну, у меня нет таких предубеждений, MS выпускают много годных и часто изящных продуктов как, например, мобильная линейка ОС, или Word. У них работают очень хорошие специалисты. Но с интернет-решениями они не дружат исторически 🙁

  67. Aliwhite:

    Вот вам задача из разряда администрирования, не совсем webdev.
    Засиделся я как-то на М9, на 6 этаже. Поднимал один из серваков из груды обломков, поднял, запустил, смотрю на часы — время ~19:00. Припозднился. И понял вдруг, что крайне сильно хочу ссать. Настолько, что уже выбирал какую-нибудь стойку на входе, какую не жалко обоссать и сжечь. Саппорта на месте нет, будка закрыта. Шароёбятся где-то в другом месте, про меня забыли. А на телефоне бабло кончилось, как назло. Время и не только оно поджимает. Поднимать пожарную тревогу не вариант. Перед камерой махал руками — ноль реакции. Что делать?

  68. Kkebad:

    поссать в /dev/null

  69. KriYes:

    взять герметичный пакет из-под винта/видюхи/другой железки, которые всегда наличествуют

  70. Aliwhite:

    нихрена, там пара сотен стоек с телекоммуникационным оборудованием, серверами, климатическое оборудование, система пожаротушения и электричество. Пакетов нема.

  71. Exewhite:

    найти сервер побольше и вытащить из него сетевой кабель?
    Прибежавшему с пенделями руководства саппорту сказать «скажите спасибо что не обоссал»

  72. AmtEkb:

    ну вот кстати хороший вариант — вызвать ребят через консоль сервера. Набрать пару команд, или куда-нибудь зайти. В конце концов отправить бесплатную смску через консольный браузер.

  73. Aliwhite:

    зная время реакции саппорта на М9, даже если бы канал на зарубеж у датацентра перегрыз, они бы только минут через 40 приперлись.

  74. Aliwhite:

    во, попытался сейчас отправить смс через консоль:

    Otpravit’ SMS-soobschenie

    [+7 926______] _________

    150 simvolov ostalos’

    _____________________________
    _____________________________
    _____________________________
    _____________________________

    Primechanie: V Vashe soobschenie budet vklyuchena informaciya o novyh uslugah.
    [ ] Vklyuchit’ transliteraciyu [ ] Vybrat’ vremya dostavki
    [29]
    [Dekabrya__]
    [08] : [33] [2011]

    po moskovskomu vremeni
    ____________________
    * Obnovit’ izobrazhenie
    * Pomosch’

    IFRAME: //www.google.com/recaptcha/api/noscript? lang=ru&k=6Lc7XMUSAAAAAALuekCTAzdT5U0zei EUQbTRZIBu

    Vstav’te poluchennyj kod syuda:
    ________________________________________
    ________________________________________
    ________________________________________
    Otpravit’

    залип на капче.

  75. Exewhite:

    можно по циклу письма слать, авось саппорт уведомления получает.
    Ну или классически:
    net send «да вы там все поохреневали чтоле?» на всю рабочую группу (интересно, работает ли оно еще)

  76. Aliwhite:

    какой нетсенд?))
    Хотя, помню, когда был на одной подработке в эрстэндянге. Один мой друг послал net send по рабочей группе. Типа «С добрым утром».
    Нет сенд получили все российские офисы E&Y. Друга уволили сразу. И кто-то в IT отделе получил пиздюлей после этого.

  77. Exewhite:

    Еще свежак на тему.
    Ровно неделю мы имели вдумчивый секс со стандартным андроид браузером.
    Эта падла ни в какую не хотела ставить apk файлы, отдаваемые с подсайта, при этом на главном сайте все ок, в других браузерах тоже все ок.

    В процессе секса рутовали телефон, перехватывали трафик, курили вайршарк, конфигурили нгиникс, копались в кеше нгиникса, скурили километры логов, плакали и грызли кактус.

    Попутно выяснилось что стандартный браузер зачем-то делает два запроса к АПК файлу. Причем получает ответы разной длины. Похоже первый от браузера, второй от установщика софта.

    В общем, оказалось что в имени сабдомена кто-то очень умный поставил подчеркивание вместо дефиса — браузер это понимал нормально, а вот установщик сходил с ума.

  78. SkoLt:

    не уверен, насколько общественности знакома эта фича связки нгинкс+апач, но я как-то провел пару незабываемых часов в попытке выяснить почему header(«HTTP/1.0 404 Not Found») отрабатывает на ура, а header(«HTTP/1.1 404 Not Found») рисует какие-то цифры в hex’е на странице перед собственно содержимым страницы. в процессе этого секса выяснил, что эта цифра — суммарное количество строк в шаблонах smarty для этой страницы, но ответа на вопрос «что блять за хуйня происходит?» это не дало. в тот момент было решено оставить HTTP/1.0 и лишь пару недель назад я благодаря хабру получил-таки ответ на свой вопрос

  79. Xuagreen:

    так же на хабре ты должен был узнать, что номер протокола надо брать из $_SERVER (:

  80. Aliwhite:

    короче, все решилось почти просто. Мой мозг был не готов соображать в такой ситуации, поэтому я пошел к консоли своего сервера, чтобы запилить на один посещаемый сайт прямо на самый верх сообщение о том, что мне срочно нужны деньги — положить на телефон или позвонить. Дойдя, я обнаружил, что один из программистов сидит в шелле, и о, чудо, не idle! Через write написал ему просьбу срочно позвонить, объяснил ситуацию и уже через 10 минут журчал в одном из толчков этого сраного здания. Даа, не то чувство назвали оргазмом.
    Другую историю про то, как уделать тот же датацентр М9 кровью, создав на полу лужу из нее размером 2 на 2 метра я не буду рассказывать, так как особых проблем в этом не было. Решилось все обычной перекисью, обмороком какой-то девочки из саппорта, бинтами и двумя ровными и параллельными шрамами на руке.

  81. SkoLt:

    я же написал, что потерял пару часов время на «попытку понять почему 1.1 рисует цифры в hex’е», а не «какой же написать номер протокола»

  82. Exewhite:

    Новый день, новый факап.
    Внезапно при включении кеша нгиникса некоторые клиенты стали жаловаться, что получают вместо бинарников какую-то полову. Полова в немного меньше исходного файла. Долго долбались, пока пытались повторить.

    Оказалось, приходит пользователь с поддержкой gzip, делает запрос, бэкэнд отрабатывает и кеширует.
    Приходит другой, без gzip, делает запрос, получает битый файл.

    В рекордные сроки, часа за три. К сожалению откопал не я.

  83. Exewhite:

    Кстати только что столкнулся с этим же. Но, спасибо посту, быстро нашел откуда лежут эти 4 красивые цифры в хэксе. Всего 15 минут секса, что б узнать почему при первой генерации не показывается картинка (:

  84. CentOS6:

    скрипт рассылки висит на cron со срабатыванием каждые n минут. В начале скрипта определяется текущее время, от которого рассчитывается номер итерации N, ну и select * from users order by id limit X(N, Y), Y

Добавить комментарий