Как найти файл по коду ошибки

Представляем перевод статьи «How to fix bugs, step by step», опубликованный сайтом tproger.ru.

ошибки в коде

Искать ошибки в программах — непростая задача. Здесь нет никаких готовых методик или рецептов успеха. Можно даже сказать, что это — искусство. Тем не менее есть общие советы, которые помогут вам при поиске. В статье описаны основные шаги, которые стоит предпринять, если ваша программа работает некорректно.

Шаг 1: Занесите ошибку в трекер

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

  1. Вы забыли какую-то важную деталь об ошибке, например, в чем она заключалась.
  2. Вы могли делегировать ее кому-то более опытному.

Трекер поможет вам не потерять нить размышлений и о текущей проблеме, и о той, которую вы временно отложили. А если вы работаете в команде, это поможет делегировать исправление коллеге и держать все обсуждение в одном месте.

Вы должны записать в трекер следующую информацию:

  1. Что делал пользователь.
  2. Что он ожидал увидеть.
  3. Что случилось на самом деле.

Это должно подсказать, как воспроизвести ошибку. Если вы не сможете воспроизвести ее в любое время, ваши шансы исправить ошибку стремятся к нулю.

Шаг 2: Поищите сообщение об ошибке в сети

Если у вас есть сообщение об ошибке, то вам повезло. Или оно будет достаточно информативным, чтобы вы поняли, где и в чем заключается ошибка, или у вас будет готовый запрос для поиска в сети. Не повезло? Тогда переходите к следующему шагу.

Шаг 3: Найдите строку, в которой проявляется ошибка

Если ошибка вызывает падение программы, попробуйте запустить её в IDE под отладчиком и посмотрите, на какой строчке кода она остановится. Совершенно необязательно, что ошибка будет именно в этой строке (см. следующий шаг), но, по крайней мере, это может дать вам информацию о природе бага.

Шаг 4: Найдите точную строку, в которой появилась ошибка

Как только вы найдете строку, в которой проявляется ошибка, вы можете пройти назад по коду, чтобы найти, где она содержится. Иногда это может быть одна и та же строка. Но чаще всего вы обнаружите, что строка, на которой упала программа, ни при чем, а причина ошибки — в неправильных данных, которые появились ранее.

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

Шаг 5: Выясните природу ошибки

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

  1. Ошибка на единицу
    Вы начали цикл for с единицы вместо нуля или наоборот. Или, например, подумали, что метод .count() или .length() вернул индекс последнего элемента. Проверьте документацию к языку, чтобы убедиться, что нумерация массивов начинается с нуля или с единицы. Эта ошибка иногда проявляется в виде исключения Index out of range.
  2. Состояние гонки
    Ваш процесс или поток пытается использовать результат выполнения дочернего до того, как тот завершил свою работу. Ищите использование sleep() в коде. Возможно, на мощной машине дочерний поток выполняется за миллисекунду, а на менее производительной системе происходят задержки. Используйте правильные способы синхронизации многопоточного кода: мьютексы, семафоры, события и т. д.
  3. Неправильные настройки или константы
    Проверьте ваши конфигурационные файлы и константы. Я однажды потратил ужасные 16 часов, пытаясь понять, почему корзина на сайте с покупками виснет на стадии отправки заказа. Причина оказалась в неправильном значении в /etc/hosts, которое не позволяло приложению найти ip-адрес почтового сервера, что вызывало бесконечный цикл в попытке отправить счет заказчику.
  4. Неожиданный null
    Бьюсь об заклад, вы не раз получали ошибку с неинициализированной переменной. Убедитесь, что вы проверяете ссылки на null, особенно при обращении к свойствам по цепочке. Также проверьте случаи, когда возвращаемое из базы данных значение NULL представлено особым типом.
  5. Некорректные входные данные
    Вы проверяете вводимые данные? Вы точно не пытаетесь провести арифметические операции с введенными пользователем строками?
  6. Присваивание вместо сравнения
    Убедитесь, что вы не написали = вместо ==, особенно в C-подобных языках.
  7. Ошибка округления
    Это случается, когда вы используете целое вместо Decimal, или float для денежных сумм, или слишком короткое целое (например, пытаетесь записать число большее, чем 2147483647, в 32-битное целое). Кроме того, может случиться так, что ошибка округления проявляется не сразу, а накапливается со временем (т. н. Эффект бабочки).
  8. Переполнение буфера и выход за пределы массива
    Проблема номер один в компьютерной безопасности. Вы выделяете память меньшего объема, чем записываемые туда данные. Или пытаетесь обратиться к элементу за пределами массива.
  9. Программисты не умеют считать
    Вы используете некорректную формулу. Проверьте, что вы не используете целочисленное деление вместо взятия остатка, или знаете, как перевести рациональную дробь в десятичную и т. д.
  10. Конкатенация строки и числа
    Вы ожидаете конкатенации двух строк, но одно из значений — число, и компилятор пытается произвести арифметические вычисления. Попробуйте явно приводить каждое значение к строке.
  11. 33 символа в varchar(32)
    Проверяйте данные, передаваемые в INSERT, на совпадение типов. Некоторые БД выбрасывают исключения (как и должны делать), некоторые просто обрезают строку (как MySQL). Недавно я столкнулся с такой ошибкой: программист забыл убрать кавычки из строки перед вставкой в базу данных, и длина строки превысила допустимую как раз на два символа. На поиск бага ушло много времени, потому что заметить две маленькие кавычки было сложно.
  12. Некорректное состояние
    Вы пытаетесь выполнить запрос при закрытом соединении или пытаетесь вставить запись в таблицу прежде, чем обновили таблицы, от которых она зависит.
  13. Особенности вашей системы, которых нет у пользователя
    Например: в тестовой БД между ID заказа и адресом отношение 1:1, и вы программировали, исходя из этого предположения. Но в работе выясняется, что заказы могут отправляться на один и тот же адрес, и, таким образом, у вас отношение 1:многим.

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

Шаг 6: Метод исключения

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

Попробуйте отключать компоненты системы один за другим, пока не найдете минимальную конфигурацию, которая будет работать. Затем подключайте их обратно по одному, пока ошибка не вернется. Таким образом вы вернетесь на шаг 3.

Шаг 7: Логгируйте все подряд и анализируйте журнал

Пройдитесь по каждому модулю или компоненту и добавьте больше сообщений. Начинайте постепенно, по одному модулю. Анализируйте лог до тех пор, пока не проявится неисправность. Если этого не случилось, добавьте еще сообщений.

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

Шаг 8: Исключите влияние железа или платформы

Замените оперативную память, жесткие диски, поменяйте сервер или рабочую станцию. Установите обновления, удалите обновления. Если ошибка пропадет, то причиной было железо, ОС или среда. Вы можете по желанию попробовать этот шаг раньше, так как неполадки в железе часто маскируют ошибки в ПО.

Если ваша программа работает по сети, проверьте свитч, замените кабель или запустите программу в другой сети.

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

Если у вас возникает одна и та же ошибка вне зависимости от среды, то она в вашем коде.

Шаг 9: Обратите внимание на совпадения

  1. Ошибка появляется всегда в одно и то же время? Проверьте задачи, выполняющиеся по расписанию.
  2. Ошибка всегда проявляется вместе с чем-то еще, насколько абсурдной ни была бы эта связь? Обращайте внимание на каждую деталь. На каждую. Например, проявляется ли ошибка, когда включен кондиционер? Возможно, из-за этого падает напряжение в сети, что вызывает странные эффекты в железе.
  3. Есть ли что-то общее у пользователей программы, даже не связанное с ПО? Например, географическое положение (так был найден легендарный баг с письмом за 500 миль).
  4. Ошибка проявляется, когда другой процесс забирает достаточно большое количество памяти или ресурсов процессора? (Я однажды нашел в этом причину раздражающей проблемы «no trusted connection» с SQL-сервером).

Шаг 10: Обратитесь в техподдержку

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

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

Полезные советы (когда ничего не помогает)

  1. Позовите кого-нибудь еще.
    Попросите коллегу поискать ошибку вместе с вами. Возможно, он заметит что-то, что вы упустили. Это можно сделать на любом этапе.
  2. Внимательно просмотрите код.
    Я часто нахожу ошибку, просто спокойно просматривая код с начала и прокручивая его в голове.
  3. Рассмотрите случаи, когда код работает, и сравните их с неработающими.
    Недавно я обнаружил ошибку, заключавшуюся в том, что когда вводимые данные в XML-формате содержали строку xsi:type='xs:string', все ломалось, но если этой строки не было, все работало корректно. Оказалось, что дополнительный атрибут ломал механизм десериализации.
  4. Идите спать.
    Не бойтесь идти домой до того, как исправите ошибку. Ваши способности обратно пропорциональны вашей усталости. Вы просто потратите время и измотаете себя.
  5. Сделайте творческий перерыв.
    Творческий перерыв — это когда вы отвлекаетесь от задачи и переключаете внимание на другие вещи. Вы, возможно, замечали, что лучшие идеи приходят в голову в душе или по пути домой. Смена контекста иногда помогает. Сходите пообедать, посмотрите фильм, полистайте интернет или займитесь другой проблемой.
  6. Закройте глаза на некоторые симптомы и сообщения и попробуйте сначала.
    Некоторые баги могут влиять друг на друга. Драйвер для dial-up соединения в Windows 95 мог сообщать, что канал занят, при том что вы могли отчетливо слышать звук соединяющегося модема. Если вам приходится держать в голове слишком много симптомов, попробуйте сконцентрироваться только на одном. Исправьте или найдите его причину и переходите к следующему.
  7. Поиграйте в доктора Хауса (только без Викодина).
    Соберите всех коллег, ходите по кабинету с тростью, пишите симптомы на доске и бросайте язвительные комментарии. Раз это работает в сериалах, почему бы не попробовать?

Что вам точно не поможет

  1. Паника
    Не надо сразу палить из пушки по воробьям. Некоторые менеджеры начинают паниковать и сразу откатываться, перезагружать сервера и т. п. в надежде, что что-нибудь из этого исправит проблему. Это никогда не работает. Кроме того, это создает еще больше хаоса и увеличивает время, необходимое для поиска ошибки. Делайте только один шаг за раз. Изучите результат. Обдумайте его, а затем переходите к следующей гипотезе.
  2. «Хелп, плиииз!»
    Когда вы обращаетесь на форум за советом, вы как минимум должны уже выполнить шаг 3. Никто не захочет или не сможет вам помочь, если вы не предоставите подробное описание проблемы, включая информацию об ОС, железе и участок проблемного кода. Создавайте тему только тогда, когда можете все подробно описать, и придумайте информативное название для нее.
  3. Переход на личности
    Если вы думаете, что в ошибке виноват кто-то другой, постарайтесь по крайней мере говорить с ним вежливо. Оскорбления, крики и паника не помогут человеку решить проблему. Даже если у вас в команде не в почете демократия, крики и применение грубой силы не заставят исправления магическим образом появиться.

Ошибка, которую я недавно исправил

Это была загадочная проблема с дублирующимися именами генерируемых файлов. Дальнейшая проверка показала, что у файлов различное содержание. Это было странно, поскольку имена файлов включали дату и время создания в формате yyMMddhhmmssШаг 9, совпадения: первый файл был создан в полпятого утра, дубликат генерировался в полпятого вечера того же дня. Совпадение? Нет, поскольку hh в строке формата — это 12-часовой формат времени. Вот оно что! Поменял формат на yyMMddHHmmss, и ошибка исчезла.

Сами по себе коды ошибок Windows не предоставляют никакой практической информации, которая могла бы пригодиться в деле их устранения, запомнить же все коды просто невозможно, разве что вам постоянно приходится иметь с ними дело. Тем, кто является системным администратором или увлекается темой системного администрирования, в таких случаях может пригодиться тулза Error Lookup, буквально «Поиск ошибок».

Эта небольшая программка является, по сути, справочником по кодам ошибок в Windows 10.

Запустив утилиту, введите код ошибки или выберите его в выпадающем списке. При этом в поле модули станет выводиться свой список — список модулей, под которыми следует понимать сценарии, в которых появляется ошибка.

Error Lookup

Такая классификация необходима, поскольку один и тот же код ошибки в разных сценариях будет иметь разные значения. Например, ошибка с кодом 0x00000003 в сценарии Windows (User Mode) станет указывать на невозможность системы найти указанный путь, а в сценарии BSOD — на попытку установить несовместимое оборудование.

Доступны модули с кодами ошибок DirectX, NTSTATUS, модули сетевых ошибок и так далее. Жаль вот только, что не для всех кодов Error Lookup выводит подробное описание, часто она ограничивается лишь названием ошибки, что тоже мало о чём говорит.

Стоп-ошибка 0x00000003 имеет имя INVALID_AFFINITY_SET, но что такое INVALID_AFFINITY_SET не указывается. Пришлось выяснять это в интернете. Но, поскольку Error Lookup активно развивается, есть надежда, что разработчик добавит подробные описания ошибок или даже общие рекомендации по их устранению.

Error Lookup

Инструмент доступен на сайте разработчика github.com/henrypp/errorlookup, имеется портативная версия. Утилитой поддерживается русский язык, в настройках можно отключить часть модулей (всего их 109), которые по умолчанию все включены.

Загрузка…

Искать ошибки в программах — непростая задача. Здесь нет никаких готовых методик или рецептов успеха. Можно даже сказать, что это — искусство. Тем не менее есть общие советы, которые помогут вам при поиске. В статье описаны основные шаги, которые стоит предпринять, если ваша программа работает некорректно.

Шаг 1: Занесите ошибку в трекер

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

  1. Вы забыли какую-то важную деталь об ошибке, например, в чем она заключалась.
  2. Вы могли делегировать ее кому-то более опытному.

Трекер поможет вам не потерять нить размышлений и о текущей проблеме, и о той, которую вы временно отложили. А если вы работаете в команде, это поможет делегировать исправление коллеге и держать все обсуждение в одном месте.

Вы должны записать в трекер следующую информацию:

  1. Что делал пользователь.
  2. Что он ожидал увидеть.
  3. Что случилось на самом деле.

Это должно подсказать, как воспроизвести ошибку. Если вы не сможете воспроизвести ее в любое время, ваши шансы исправить ошибку стремятся к нулю.

Шаг 2: Поищите сообщение об ошибке в сети

Если у вас есть сообщение об ошибке, то вам повезло. Или оно будет достаточно информативным, чтобы вы поняли, где и в чем заключается ошибка, или у вас будет готовый запрос для поиска в сети. Не повезло? Тогда переходите к следующему шагу.

Шаг 3: Найдите строку, в которой проявляется ошибка

Если ошибка вызывает падение программы, попробуйте запустить её в IDE под отладчиком и посмотрите, на какой строчке кода она остановится. Совершенно необязательно, что ошибка будет именно в этой строке (см. следующий шаг), но, по крайней мере, это может дать вам информацию о природе бага.

Шаг 4: Найдите точную строку, в которой появилась ошибка

Как только вы найдете строку, в которой проявляется ошибка, вы можете пройти назад по коду, чтобы найти, где она содержится. Иногда это может быть одна и та же строка. Но чаще всего вы обнаружите, что строка, на которой упала программа, ни при чем, а причина ошибки — в неправильных данных, которые появились ранее.

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

Шаг 5: Выясните природу ошибки

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

  1. Ошибка на единицу
    Вы начали цикл for с единицы вместо нуля или наоборот. Или, например, подумали, что метод .count() или .length() вернул индекс последнего элемента. Проверьте документацию к языку, чтобы убедиться, что нумерация массивов начинается с нуля или с единицы. Эта ошибка иногда проявляется в виде исключения Index out of range.
  2. Состояние гонки
    Ваш процесс или поток пытается использовать результат выполнения дочернего до того, как тот завершил свою работу. Ищите использование sleep() в коде. Возможно, на мощной машине дочерний поток выполняется за миллисекунду, а на менее производительной системе происходят задержки. Используйте правильные способы синхронизации многопоточного кода: мьютексы, семафоры, события и т. д.
  3. Неправильные настройки или константы
    Проверьте ваши конфигурационные файлы и константы. Я однажды потратил ужасные 16 часов, пытаясь понять, почему корзина на сайте с покупками виснет на стадии отправки заказа. Причина оказалась в неправильном значении в /etc/hosts, которое не позволяло приложению найти ip-адрес почтового сервера, что вызывало бесконечный цикл в попытке отправить счет заказчику.
  4. Неожиданный null
    Бьюсь об заклад, вы не раз получали ошибку с неинициализированной переменной. Убедитесь, что вы проверяете ссылки на null, особенно при обращении к свойствам по цепочке. Также проверьте случаи, когда возвращаемое из базы данных значение NULL представлено особым типом.
  5. Некорректные входные данные
    Вы проверяете вводимые данные? Вы точно не пытаетесь провести арифметические операции с введенными пользователем строками?
  6. Присваивание вместо сравнения
    Убедитесь, что вы не написали = вместо ==, особенно в C-подобных языках.
  7. Ошибка округления
    Это случается, когда вы используете целое вместо Decimal, или float для денежных сумм, или слишком короткое целое (например, пытаетесь записать число большее, чем 2147483647, в 32-битное целое). Кроме того, может случиться так, что ошибка округления проявляется не сразу, а накапливается со временем (т. н. Эффект бабочки).
  8. Переполнение буфера и выход за пределы массива
    Проблема номер один в компьютерной безопасности. Вы выделяете память меньшего объема, чем записываемые туда данные. Или пытаетесь обратиться к элементу за пределами массива.
  9. Программисты не умеют считать
    Вы используете некорректную формулу. Проверьте, что вы не используете целочисленное деление вместо взятия остатка, или знаете, как перевести рациональную дробь в десятичную и т. д.
  10. Конкатенация строки и числа
    Вы ожидаете конкатенации двух строк, но одно из значений — число, и компилятор пытается произвести арифметические вычисления. Попробуйте явно приводить каждое значение к строке.
  11. 33 символа в varchar(32)
    Проверяйте данные, передаваемые в INSERT, на совпадение типов. Некоторые БД выбрасывают исключения (как и должны делать), некоторые просто обрезают строку (как MySQL). Недавно я столкнулся с такой ошибкой: программист забыл убрать кавычки из строки перед вставкой в базу данных, и длина строки превысила допустимую как раз на два символа. На поиск бага ушло много времени, потому что заметить две маленькие кавычки было сложно.
  12. Некорректное состояние
    Вы пытаетесь выполнить запрос при закрытом соединении или пытаетесь вставить запись в таблицу прежде, чем обновили таблицы, от которых она зависит.
  13. Особенности вашей системы, которых нет у пользователя
    Например: в тестовой БД между ID заказа и адресом отношение 1:1, и вы программировали, исходя из этого предположения. Но в работе выясняется, что заказы могут отправляться на один и тот же адрес, и, таким образом, у вас отношение 1:многим.

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

Шаг 6: Метод исключения

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

Попробуйте отключать компоненты системы один за другим, пока не найдете минимальную конфигурацию, которая будет работать. Затем подключайте их обратно по одному, пока ошибка не вернется. Таким образом вы вернетесь на шаг 3.

Шаг 7: Логгируйте все подряд и анализируйте журнал

Пройдитесь по каждому модулю или компоненту и добавьте больше сообщений. Начинайте постепенно, по одному модулю. Анализируйте лог до тех пор, пока не проявится неисправность. Если этого не случилось, добавьте еще сообщений.

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

Шаг 8: Исключите влияние железа или платформы

Замените оперативную память, жесткие диски, поменяйте сервер или рабочую станцию. Установите обновления, удалите обновления. Если ошибка пропадет, то причиной было железо, ОС или среда. Вы можете по желанию попробовать этот шаг раньше, так как неполадки в железе часто маскируют ошибки в ПО.

Если ваша программа работает по сети, проверьте свитч, замените кабель или запустите программу в другой сети.

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

Если у вас возникает одна и та же ошибка вне зависимости от среды, то она в вашем коде.

Шаг 9: Обратите внимание на совпадения

  1. Ошибка появляется всегда в одно и то же время? Проверьте задачи, выполняющиеся по расписанию.
  2. Ошибка всегда проявляется вместе с чем-то еще, насколько абсурдной ни была бы эта связь? Обращайте внимание на каждую деталь. На каждую. Например, проявляется ли ошибка, когда включен кондиционер? Возможно, из-за этого падает напряжение в сети, что вызывает странные эффекты в железе.
  3. Есть ли что-то общее у пользователей программы, даже не связанное с ПО? Например, географическое положение (так был найден легендарный баг с письмом за 500 миль).
  4. Ошибка проявляется, когда другой процесс забирает достаточно большое количество памяти или ресурсов процессора? (Я однажды нашел в этом причину раздражающей проблемы «no trusted connection» с SQL-сервером).

Шаг 10: Обратитесь в техподдержку

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

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

Полезные советы (когда ничего не помогает)

  1. Позовите кого-нибудь еще.
    Попросите коллегу поискать ошибку вместе с вами. Возможно, он заметит что-то, что вы упустили. Это можно сделать на любом этапе.
  2. Внимательно просмотрите код.
    Я часто нахожу ошибку, просто спокойно просматривая код с начала и прокручивая его в голове.
  3. Рассмотрите случаи, когда код работает, и сравните их с неработающими.
    Недавно я обнаружил ошибку, заключавшуюся в том, что когда вводимые данные в XML-формате содержали строку xsi:type='xs:string', все ломалось, но если этой строки не было, все работало корректно. Оказалось, что дополнительный атрибут ломал механизм десериализации.
  4. Идите спать.
    Не бойтесь идти домой до того, как исправите ошибку. Ваши способности обратно пропорциональны вашей усталости. Вы просто потратите время и измотаете себя.
  5. Сделайте творческий перерыв.
    Творческий перерыв — это когда вы отвлекаетесь от задачи и переключаете внимание на другие вещи. Вы, возможно, замечали, что лучшие идеи приходят в голову в душе или по пути домой. Смена контекста иногда помогает. Сходите пообедать, посмотрите фильм, полистайте интернет или займитесь другой проблемой.
  6. Закройте глаза на некоторые симптомы и сообщения и попробуйте сначала.
    Некоторые баги могут влиять друг на друга. Драйвер для dial-up соединения в Windows 95 мог сообщать, что канал занят, при том что вы могли отчетливо слышать звук соединяющегося модема. Если вам приходится держать в голове слишком много симптомов, попробуйте сконцентрироваться только на одном. Исправьте или найдите его причину и переходите к следующему.
  7. Поиграйте в доктора Хауса (только без Викодина).
    Соберите всех коллег, ходите по кабинету с тростью, пишите симптомы на доске и бросайте язвительные комментарии. Раз это работает в сериалах, почему бы не попробовать?

Что вам точно не поможет

  1. Паника
    Не надо сразу палить из пушки по воробьям. Некоторые менеджеры начинают паниковать и сразу откатываться, перезагружать сервера и т. п. в надежде, что что-нибудь из этого исправит проблему. Это никогда не работает. Кроме того, это создает еще больше хаоса и увеличивает время, необходимое для поиска ошибки. Делайте только один шаг за раз. Изучите результат. Обдумайте его, а затем переходите к следующей гипотезе.
  2. «Хелп, плиииз!»
    Когда вы обращаетесь на форум за советом, вы как минимум должны уже выполнить шаг 3. Никто не захочет или не сможет вам помочь, если вы не предоставите подробное описание проблемы, включая информацию об ОС, железе и участок проблемного кода. Создавайте тему только тогда, когда можете все подробно описать, и придумайте информативное название для нее.
  3. Переход на личности
    Если вы думаете, что в ошибке виноват кто-то другой, постарайтесь по крайней мере говорить с ним вежливо. Оскорбления, крики и паника не помогут человеку решить проблему. Даже если у вас в команде не в почете демократия, крики и применение грубой силы не заставят исправления магическим образом появиться.

Ошибка, которую я недавно исправил

Это была загадочная проблема с дублирующимися именами генерируемых файлов. Дальнейшая проверка показала, что у файлов различное содержание. Это было странно, поскольку имена файлов включали дату и время создания в формате yyMMddhhmmss. Шаг 9, совпадения: первый файл был создан в полпятого утра, дубликат генерировался в полпятого вечера того же дня. Совпадение? Нет, поскольку hh в строке формата — это 12-часовой формат времени. Вот оно что! Поменял формат на yyMMddHHmmss, и ошибка исчезла.

Перевод статьи «How to fix bugs, step by step»

К написанию статьи меня побудило желание внести свои пять копеек в обсуждение одного из последних выпусков (на данный момент) самой популярной среди пользователей операционной системы Windows. А также состояние растерянности и недоумения, если окажется, что описываемый мною ниже баг в системе поиска действительно является «архитектурной особенностью продукта», как мне ответили специалисты поддержки Microsoft. Изложенный ниже материал представлен на основе моих экспериментов с поиском в операционной системе Windows-8-Pro-64bit (установлена самостоятельно на «чистый» ноутбук, лицензионная, активированная). Подобные опыты проводил и ранее на ноутбуке с предустановленной системой Windows-7-HomeBasic-64bit. В обоих случаях результат был одинаков.
По моему мнению, в поисковом модуле указанных выше операционных систем (подозреваю и не в них одних) серьезный баг механизма поиска. Хотя, как я уже упомянул выше, специалисты Microsoft считают, что это не баг, а фича.

Вот кратко суть:

1. Поиск только по именам файлов работает некорректно, а именно – файл будет найден, только если выполняется одно из условий:
a) искомая последовательность символов является началом слова;
b) искомая последовательность символов расположена после некоторых символов типа дефиса, точки, подчеркивания и возможно других.

2. Поиск по именам файлов и содержимому файлов работает некорректно, а именно – файл с нужным нам содержимым будет найден, только если выполняются два условия:
a) тип файла включен в перечень типов, для которых операционная система выполняет текстовый поиск;
b) искомая последовательность символов либо является началом слова, либо расположена после некоторых символов типа дефиса, точки, подчеркивания и возможно других.

Кого это заинтересовало, могут ознакомиться с техническими подробностями моих опытов в изложенном ниже материале.
Небольшое примечание: так как для открытия описываемых мною окон элементов и настроек существует более чем один способ, я избрал как точку отсчета панель управления Windows. Ее можно открыть, нажав сочетание клавиш Win+X и выбрав в появившемся списке пункт «панель управления».

2. Описание системы поиска

Начну с того, что система поиска является компонентом операционной системы. Откроем настройку компонентов Windows: панель управления → программы и компоненты → включение или отключение компонентов Windows. Называется наш компонент – Windows Search. Если его отключить (убрать галочку из соответствующего квадратика), то после перезагрузки родной поиск Windows перестает работать, а из окна проводника исчезает поле для ввода поисковых запросов в правом верхнем углу окна.

По умолчанию компонент, естественно, включен. И при вводе первого же символа в поле поиска, система приступает к поиску, не дожидаясь ввода полного запроса. Это так называемый «живой» поиск, сейчас так модно. Вспомним, что в Windows XP для начала процесса поиска было необходимо дать команду – нажать кнопку «Найти».

Составляющей частью системы поиска, служащей для ускорения процесса поиска, является служба индексирования содержимого с аналогичным названием Windows Search, тип запуска – автоматический, отложенный. (На рисунке ниже данная служба отключена).

Для настройки служб открываем: панель управления → администрирование → службы. Свойства выделенной службы можно посмотреть, открыв контекстное меню – клик правой кнопкой мышки. Как я понимаю, данная служба индексирует определенное содержимое (названия, свойства, содержание файлов) в указанных ей расположениях и заносит эту информацию в свою базу данных. И в последующем поиск происходит уже по этой базе, которая хранится в «C:ProgramDataMicrosoftSearch», тем самым сокращается время поиска.

3. Настройки системы поиска

Настройки поиска сосредоточены аж в трех местах, видимо для удобства. При этом некоторые из них встречаются более чем в одном из этих трех мест, некоторые только в одном. Записываем минус на счет Microsoft. (Некоторые настройки остались для меня загадкой). Вот места расположения этих настроек:
3.1. Панель управления → параметры индексирования;
3.2. Панель управления → параметры папок (вкладка поиск);
3.3. Окно проводника Windows → активируем строку поиска (ставим в нее курсор) → в главном меню окна появляется вкладка «поиск», кликаем ее, если не раскрыта.

Пройдемся по этим местам и кратко рассмотрим параметры поиска.

3.1. Панель управления → параметры индексирования.

В параметрах индексирования нам предоставляется возможность указать, что и где будет индексироваться. Пока плюс в копилку Microsoft. Справка Microsoft не рекомендует выбирать много индексируемых мест, например папки Windows, Program Files, так как, по ее мнению, пользователям там искать нечего. Кроме того индексирование (перестройка индекса) процесс длительный.

Как видно из рисунка каждому типу файла сопоставляется нужный фильтр, а индексировать можно или только свойства файла или и свойства и содержимое. А это значит (о чудо!), что мы, например, можем набрать в строке поиска проводника имя нашего музыкального божества, и он будет найден по музыкальным тэгам. Правда не учитывается состояние/наличие тех самых музыкальных тэгов в наших любимых, часто безликих mp3-файлах. Ведь не редкость и имена типа track_01.mp3.
Кстати путь (расположение) файла – это еще и свойство файла, так что надо быть готовым увидеть в результатах поиска все файлы в пути которых есть слово, набранное в поисковом запросе. По мне, так это уже лишнее.
В итоге мы имеем замудреный поиск. А, как говорит, философия языка Python – простое лучше, чем сложное. Поэтому служба индексирования у меня остановлена.

3.2. Панель управления → параметры папок (вкладка поиск).

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

Параметры раздела «Как искать» применяются и к индексируемым и к неиндексируемым расположениям. Нужный и понятный всем параметр «Искать частичные совпадения» в комментариях не нуждается. Значение параметра «Не использовать индекс при поиске системных файлов в папках» для меня осталось загадкой. Ведь в параметрах индексирования уже указано, что и как индексировать.

Из названия следует, что параметры раздела «Поиск в неиндексированных расположениях» применяются только к неиндексированным местам.
Значения параметров понятны. В наличии возможность искать в архивах – еще плюс. Следующий важный параметр «Искать по именам файлов и содержимому». Что сказать? Порадовали, и честно предупредили – не все сразу и сейчас.

3.3. Окно проводника Windows → при активированной строке поиска в главном меню окна появляется вкладка «поиск».

Ну и третье место для настройки параметров поиска любое окно проводника Windows, стоит активировать поле поискового запроса и в главном меню окна появляется вкладка «поиск»:

Здесь много полезных фишек, в том числе только здесь и настраиваемых. Например, поиск только в текущей папке, либо и во всех вложенных тоже. Можно ограничить круг поиска по дате изменения файла, типу, размеру и другим свойствам. Ими я не пользуюсь, дабы потом не терзали сомнения. Фишка повторения поиска в интернетах (однако!), журнал поисковых запросов, а также дополнительные параметры (это как раз те, что мы уже обсудили выше).

4. Устранение неполадок и собственно баг

Начну с того, что в операционную систему встроены модули для поиска и устранения различных проблем. Думаю, фишка нужная, но сразу скажу – меня не спасла.
Итак открываем: панель управления → устранение неполадок → просмотр всех категорий → поиск и индексирование. Почему бы не показать сразу все категории? Не так уж их и много, на мой 14 дюймовый экран помещаются. Запускаем устранение неполадок поиска, в открывшемся окне кликаем «Дополнительно», кликаем «Запуск с правами администратора», кнопка «Далее». Опять новое окно с выбором проблемы, ставим галочку «Файлы не отображаются в результатах поиска» – дошли наконец до моего горя! Жмем «Далее» и получаем вот такой результат работы диагностики:

Как видим это касается службы индексирования (которая в тот момент была включена и работала). Разрешения для каталогов службы индексирования я не трогал, да и не знал о существовании этих каталогов, пока не увидел это окно с результатами диагностики. Напомню, где эти каталоги: «C:ProgramDataMicrosoftSearch».
Способ исправления этой ошибки я не нашел, и думаю уже незачем (служба индексирования у меня ведь отключена теперь). Да и по смыслу следует, что это касается только индексируемых расположений. А моя проблема актуальна для всех расположений.
Настало время детально разъяснить мою проблему. Сразу поясню, что состояние службы индексирования («работает» или «отключена») значения не имеет.

4.1. Поиск по имени файла.

Итак, в первой части эксперимента в глобальных параметрах поиска (относящихся к любым размещениям, индексированным и нет) активируем параметр «Искать частичные совпадения». Далее для неиндексированных расположений (в моем случае – для всех) снимаем галочку «Искать по именам файлов и содержимому», чтобы поиск выполнялся только по именам файлов. Приступаем к опытам. В исследуемой папке размещены несколько файлов различных типов:

Набираем в строке поиска fa и видим:

Казалось бы, Windows Search с задачей справился, даже результаты подсвечены желтым цветом. О чем еще мечтать? Но где же файл SearchFalse. vsd? Разве fa не часть имени SearchFalse. vsd? Может дело в регистре? Но в примере выше найдены имена, где f и в верхнем и в нижнем регистре. Для успокоения введем Fa и увидим, что результат не изменился. Хотя бы с регистром проблем не имеем!

Попробуем ввести cm, получим:

Как будто-бы все в норме.

Вводим ro:

«Нет элементов, удовлетворяющих условиям поиска» – как же так, братья и сестры? Три файла удовлетворяют условиям поиска (Error. cmd, Error_critical. txt, Wrong. txt), но они не найдены. Все пропало?
Вот что мы пока имеем: в поле поиска вводится последовательность символов, которая заведомо есть в названии файлов. Но в результатах поиска содержатся только файлы, у которых заданная последовательность является началом имени, или началом расширения, или расположена после дефиса.
Но это противоречит, уверен не только моему, представлению о принципе работы поиска!

Попробуем хитрость, введем первым символом запроса «звездочку» *ro:

Свершилось, файлы найдены! Но уже без чудной желтой подсветки. В справке про такие хитрости нет упоминаний. Развитие событий в целом настораживает.

4.2. Поиск по имени и содержимому файла.

Орешек знаний тверд, но мы не привыкли отступать… Включаем настройку «Искать по именам файлов и содержимому», чтобы теперь искать и по содержанию файла. В уже знакомой нам папке в пяти файлах (Error. cmd, Fail. xlsx, Foul. jpg, Mistake. bat, Wrong. txt) есть одинаковое содержимое:

Get off My Cloud
As Tears Go By
Paint_It_Black
Mother’s Little Helper
Lady-Jane

Файл Foul. jpg – это текстовый файл с измененным расширением.

Набираем в поле поиска tea, (чтобы соответствовало началу слова Tears):

Усложним задание, набираем в поле поиска bla, (чтобы символы шли после знака подчеркивания):

Файлы найдены, но говорить об удаче еще рано. Вводим jan, получаем тот же результат. Что ожидаемо.

Пробуем еще более усложнить задание, набираем запрос ear:

Те четыре файла, которые должны быть найдены, отсутствуют. Снова неудача, но к которой мы должны быть готовы. У нас есть ответный ход! Вводим *ear:
Ex-*ear

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

4.3. Выводы.

На основании всего изложенного выше можно сделать вывод, что механизм поиска одинаков и для поиска по именам файлов и для поиска по именам и содержимому. Ошибка, на мой взгляд, одна и весьма критическая, так как приводит к неполным результатам поиска. Кроме того вводит в заблуждение человека логичного в своем мышлении и вынуждает строить хитрые догадки.
Результат – жирный минус Microsoft. Радует только то, что баг лечится хотя бы для поиска по именам файлов.

5. Диагноз

Можно подвести неутешительные итоги:

1. Поиск только по именам файлов (с выключенным параметром «искать по именам файлов и содержимому») работает некорректно. А именно – файл будет найден, только если выполняется одно из условий:
a) искомая последовательность символов является началом слова;
b) искомая последовательность символов расположена после некоторых символов типа дефиса, точки, подчеркивания и возможно других, определять перечень которых считаю бесполезной тратой времени.

Этот баг лечится использованием в начале искомой последовательности спасительного символа * «звездочка».

2. Поиск по именам файлов и содержимому файлов (с включенным параметром «Искать по именам файлов и содержимому») работает некорректно. А именно – файл с нужным нам содержимым (нас интересует именно содержание файла) будет найден, только если выполняются два условия:
a) тип файла включен в перечень типов, для которых операционная система выполняет текстовый поиск;
b) искомая последовательность символов либо является началом слова, либо расположена после некоторых символов типа дефиса, точки, подчеркивания и возможно других, определять перечень которых считаю бесполезной тратой времени.

Лекарство от этого бага пока мною не найдено.

Коды ошибок Windows 7

Ошибка Синий экран смерти

Синий экран смерти — сокращённо BSoD, по английский BlueScreenofDeath, это сообщение о фатальной ошибке, после которой компьютер не может нормально функционировать и перезагружается. Обычно, сообщение синего экрана начинается со слова «STOP», после чего показывается код.

Причины возникновения BSoD

Причины ошибок можно разделить на 2 категории:

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

Системные сбои

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

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

Программные ошибки

Если причиной сбоя является файл конкретного приложения, то устранить проблему можно попросту удалив программу. Для этого лучше использовать специальные деинсталляторы, которые полностью чистят систему от оставшихся файлов и записей в системном реестре. О том как удалять неудаляемые файлы читайте здесь

Отсутствие свободного места

Иногда сбой происходит из-за банальной нехватки места на диске. Зачастую это случается с разделом C. Чтобы узнать сведения о свободной памяти потребуется:

Ошибка после обновления Windows

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

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

Неисправность жесткого диска

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

Если ошибка программная, то данный способ сможет её исправить.

Драйверы устройств

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

Сбои оперативной памяти

Иногда проблема кроется в неисправной оперативной памяти. Провести её диагностику можно при помощи программы Memtest86+.

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

Источники:

https://habr. com/ru/post/167039/

https://cheerss. ru/kody-oshibok-windows-7/.html

Насколько я понял

3856B — номер записи в MFT (соответствует полю FILE record number структуры File Reference)

$I30 — указывает на индекс файлов в каталоге (один из типов индексов)

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


Для того, чтобы узнать имя файла по его номеру записи в MFT, в Windows существует команда fsutil file queryfilenamebyid. Проблема в том, что эта команда требует полный ID файла вида 0x7500000000CFCD (состоящий из номера записи и дополнительного однобайтового значения SequenceNumber, которое показывает, сколько раз данная запись была повторно использована), в то время как журнал программы проверки диска возвращает только частичный идентификатор вида 0x00000000CFCD (только номер записи). Теоретически, для идентификации файла достаточно только номера записи, т.к. он представляет собой индекс массива. Дополнительный байт, как я понял, нужен для контроля правильности действий при обращении к повторно используемым записям, поэтому все «высокоуровневные» средства Windows, например WMI, используют полный идентификатор.

Тем не менее, есть способ найти файл и по частичному идентификатору. Для этого понадобится утилита nfi.exe из пакета Windows 2000 OEM Support Tools. К сожалению, сей антиквариат более не доступен с официального сайта, однако на свой страх и риск его можно скачать здесь: Oem3sr2s.zip. Данная консольная утилита позволяет сделать дамп MFT указанного тома.
Использование:

nfi.exe (БукваДиска):>filename.txt

Затем в полученном файле надо искать переведенное в десятичную систему значение номера записи из chkdsk. В результате будет найдено что-то такое (для каталога):

File 53197

foobarcatalog

    $STANDARD_INFORMATION (resident)

    $FILE_NAME (resident)

    $FILE_NAME (resident)

    $INDEX_ROOT $I30 (resident)

Примечания

  1. Можно найти файл подбором, вызывайте в цикле команду, пока не получите %ERRORLEVEL% равный 0:

    fsutil file queryfilenamebyid (БукваДиска): 0xXX00000012CFCA
    

    где XX изменяется в диапазоне от 00 до FF

    При наличии node.js это можно сделать следующим образом:

    const spawn = require("child_process").spawnSync;
    
    for (var q=0; q<256; ++q) {
      var id = "0x" + (0+q.toString(16)).slice(-2) + "00000003856B";
      var args = ["file", "queryfilenamebyid", "h:\", id];
    
      if(!spawn("fsutil", args).status) {
        console.log(id);
        /* 866-я кодировка не считывается нормально, поэтому перезапускаем */
        spawn("fsutil", args, {stdio:'inherit'});
      }
    }
    
  2. Аналогом nfi.exe в Linux является утилита ntfsls, запущенная с ключом -i

Понравилась статья? Поделить с друзьями:
  • Как найти концентрацию свободных электронов в проводнике
  • Как найти расположение программы по ярлыку
  • Установлено одно новое приложение как найти
  • Как выполнить задание найти третий артефакт
  • Как составить заявление от руки