Найдите ошибку в программе

Обновлено: 06.07.2024

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

На обработку поступает положительное целое число, не превышающее 10 9 . Нужно написать программу, которая выводит на экран сумму цифр этого числа, меньших 7. Если в числе нет цифр, меньших 7, требуется на экран вывести 0. Программист написал программу неправильно. Ниже эта программа для Вашего удобства приведена на пяти языках программирования.

var N, digit, sum: longint;
begin
readln(N);
sum := 0;
while N > 0 do
begin
digit := N mod 10;
if digit < 7 then
sum := sum + 1;
N := N div 10;
end;
writeln(digit)
end.

Источник: демоверсия ФИПИ по информатике и ИКТ 2016-го года.

В решении задания есть видеоразбор

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

1. Что выведет программа при вводе числа 456.

readln(N);
sum := 0;
while N > 0 do
begin
digit := N mod 10;
if digit < 7 then
sum := sum + 1;
N := N div 10;
end;
writeln(digit)

Первая строка — N = 456

Вторая строка — sum = 0

  • digit := 456 mod 10 = 6
  • 6 < 7 — условие выполняется, следовательно sum := sum + 1 = 0 + 1 = 1
  • N := N div 10 = 456 div 10 = 45
  • digit := 45 mod 10 = 5
  • 5 < 7 — условие выполняется, следовательно sum := sum + 1 = 1 + 1 = 2
  • N := N div 10 = 45 div 10 = 4
  • digit := 4 mod 10 = 4
  • 4 < 7 — условие выполняется, следовательно sum := sum + 1 = 2 + 1 = 3
  • N := N div 10 = 4 div 10 = 0

writeln(digit) — digit в последней итерации равна 4, то есть выводится 4.

Ответ: 4

2. Приведите пример такого трёхзначного числа, при вводе которого программа выдаёт верный ответ.

Пожалуй, самая сложная часть задания. Сначала давайте определим, что вообще выводит неверно написанная программа. Как мы видим, выводится значение digit. В цикле операция digit := N mod 10; выполняется каждый повтор цикла, в последнем повторе переменная digit равна первому (старшему) разряду числа. Проще говоря, мы ввели 456 — программа вывела 4, введём 389 — программа выведет 3.

Требовалось написать программу, которая выводит сумму цифр числа, меньших 7, то есть мы должны подобрать такое трёхзначное число, чтобы старший разряд этого числа был равен сумме цифр числа, которые меньше 7. Примером может быть, к примеру, число 936 — сумма разрядов, меньших 7 равна 9-ти, на экран выводится старший разряд, то есть 9.

Ответ: 936

3. Найдите все ошибки в этой программе.

Ошибка 1. Каждый повтор цикла при выполнении условия к переменной sum прибавляется единица. Программа должна искать сумму разрядов, а не их количество, то есть к переменной sum должна прибавляться переменная digit. Значит строку

нужно заменить на

sum := sum + digit;

Ошибка 2. Программа выводит значение переменной digit, должна же выводить значение переменной sum. Заменим строку

Ответ: sum := sum + 1; -> sum := sum + digit; и writeln(digit) -> writeln(sum)

Для того, чтобы найти ошибку, нужно поставить в соответствие друг другу все части условного оператора if и else.

Помним, что часть else относится к ближайшему if. При этом наличие части else не обязательно.

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

Особого внимания требует инициализация переменных.

Формат книги не позволяет рассмотреть все основные типы задач 2 части, рассмотрим лишь те, которые встречались на проверочных и экзаменационных работах последних двух лет.

На об­ра­бот­ку по­сту­па­ет по­ло­жи­тель­ное целое число, не пре­вы­ша­ю­щее 10 9 . Нужно на­пи­сать про­грам­му, ко­то­рая вы­во­дит на экран сумму цифр этого числа, мень­ших 7. Если в числе нет цифр, мень­ших 7, тре­бу­ет­ся на экран вы­ве­сти 0. Про­грам­мист на­пи­сал про­грам­му не­пра­виль­но. Ниже эта про­грам­ма для Ва­ше­го удоб­ства при­ве­де­на на пяти язы­ках про­грам­ми­ро­ва­ния.

Бей­сик

Python

INPUT N

WHILE N > 0

DIGIT = N MOD 10

IF DIGIT < 7 THEN

END IF

WEND

Пас­каль

Ал­го­рит­ми­че­ский язык

begin

readln(N);

while N > 0 do

begin

digit := N mod 10;

if digit < 7 then

N := N div 10;

end;

writeln(digit)

нач

цел N, digit, sum

ввод N

нц пока N > 0

если digit < 7 то

все

кц

вывод digit

Си

int main()

int N, digit, sum;

while (N > 0)

if (digit < 7)

По­сле­до­ва­тель­но вы­пол­ни­те сле­ду­ю­щее.

1. На­пи­ши­те, что вы­ве­дет эта про­грам­ма при вводе числа 456.

2. При­ве­ди­те при­мер та­ко­го трёхзнач­но­го числа, при вводе ко­то­ро­го про­грам­ма выдаёт вер­ный ответ.

3. Най­ди­те все ошиб­ки в этой про­грам­ме (их может быть одна или не­сколь­ко). Из­вест­но, что каж­дая ошиб­ка за­тра­ги­ва­ет толь­ко одну стро­ку и может быть ис­прав­ле­на без из­ме­не­ния дру­гих строк. Для каж­дой ошиб­ки:

1) вы­пи­ши­те стро­ку, в ко­то­рой сде­ла­на ошиб­ка;

2) ука­жи­те, как ис­пра­вить ошиб­ку, т.е. при­ве­ди­те пра­виль­ный ва­ри­ант стро­ки.

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

Ре­ше­ние ис­поль­зу­ет за­пись про­грам­мы на Пас­ка­ле. До­пус­ка­ет­ся ис­поль­зо­ва­ние про­грам­мы на любом из четырёх дру­гих язы­ков.

1. Про­грам­ма вы­ве­дет число 4.

2. При­мер числа, при вводе ко­то­ро­го про­грам­ма выдаёт вер­ный ответ: 835.

Про­грам­ма ра­бо­та­ет не­пра­виль­но из-за не­вер­ной вы­во­ди­мой на экран пе­ре­мен­ной и не­вер­но­го уве­ли­че­ния суммы. Со­от­вет­ствен­но, про­грам­ма будет ра­бо­тать верно, если в числе стар­шая цифра (край­няя левая) равна сумме цифр, мень­ших 7.

3. В про­грам­ме есть две ошиб­ки.

Пер­вая ошиб­ка. Не­вер­ное уве­ли­че­ние суммы.

Стро­ка с ошиб­кой:

sum := sum + digit;

Вто­рая ошиб­ка. Не­вер­ный вывод от­ве­та на экран.

Стро­ка с ошиб­кой:

Для за­дан­но­го по­ло­жи­тель­но­го ве­ще­ствен­но­го числа A не­об­хо­ди­мо найти мак­си­маль­ное целое число K, при ко­то­ром вы­пол­ня­ет­ся не­ра­вен­ство

(при K = 0 сумма счи­та­ет­ся рав­ной 0).

Для ре­ше­ния этой за­да­чи уче­ник на­пи­сал такую про­грам­му.

Бей­сик

Python

DIM K AS INTEGER

INPUT A

WHILE S < A

WEND

PRINT K

Ал­го­рит­ми­че­ский язык

Пас­каль

нач

вещ a, s

цел k

ввод a

нц пока s<a

кц

вывод k

k: integer;

begin

read(a);

while s<a do begin

end;

write(k);

Си

int main()

double a, s;

int k;

while (s<a)

return 0;

По­сле­до­ва­тель­но вы­пол­ни­те сле­ду­ю­щее.

1. На­пи­ши­те, что вы­ве­дет эта про­грам­ма при вводе числа 1.2.

2. При­ве­ди­те при­мер числа, при вводе ко­то­ро­го про­грам­ма даст вер­ный ответ.

3. Най­ди­те в про­грам­ме все ошиб­ки (их может быть одна или не­сколь­ко).

Для каж­дой ошиб­ки вы­пи­ши­те стро­ку, в ко­то­рой она до­пу­ще­на, и при­ве­ди­те эту же стро­ку в ис­прав­лен­ном виде.

Об­ра­ти­те вни­ма­ние: вам нужно ис­пра­вить при­ведённую про­грам­му, а не на­пи­сать свою. Вы мо­же­те толь­ко ис­прав­лять оши­боч­ные стро­ки; уда­лять стро­ки или до­бав­лять новые стро­ки нель­зя. По­ста­рай­тесь также не вне­сти новые ошиб­ки – за это оцен­ка сни­жа­ет­ся.

Ре­ше­ние ис­поль­зу­ет за­пись про­грам­мы на Пас­ка­ле. До­пус­ка­ет­ся ис­поль­зо­ва­ние про­грам­мы на дру­гих язы­ках.

1. При вводе числа 1.2 про­грам­ма вы­ве­дет число 2.

2. При­ме­ры чисел, при вводе ко­то­рых про­грам­ма вы­во­дит вер­ный ответ: 1.6, 2.05.

Про­грам­ма со­дер­жит две ошиб­ки, одна из ко­то­рых при­во­дит к уве­ли­че­нию от­ве­та, дру­гая – к умень­ше­нию.

В не­ко­то­рых слу­ча­ях эти ошиб­ки ком­пен­си­ру­ют друг друга, и ответ ока­зы­ва­ет­ся пра­виль­ным. Это про­ис­хо­дит, если зна­че­ние A по­па­да­ет в один из сле­ду­ю­щих диа­па­зо­нов: 1.5 < A < 1.83, 2 < A < 2.08.

3. Про­грам­ма со­дер­жит две ошиб­ки.

1) Не­вер­ная ини­ци­а­ли­за­ция. На­чаль­ное зна­че­ние S долж­но быть равно нулю.

В при­ведённом ва­ри­ан­те вы­чис­лен­ная сумма ока­зы­ва­ет­ся на 1 боль­ше пра­виль­но­го зна­че­ния.

Стро­ка с ошиб­кой:

2) Не­вер­ное опре­де­ле­ние от­ве­та. При­ведённая про­грам­ма на­хо­дит не мак­си­маль­ное K, при ко­то­ром вы­пол­ня­ет­ся не­ра­вен­ство, а ми­ни­маль­ное, при ко­то­ром оно не вы­пол­ня­ет­ся, то есть уве­ли­чи­ва­ет вер­ное зна­че­ние на 1.

Кроме того, ис­поль­зо­ван­ный по­ря­док дей­ствий в цикле (уве­ли­че­ние K после уве­ли­че­ния S) при­во­дит к уве­ли­че­нию ещё на 1. Это можно было бы ис­пра­вить, из­ме­нив по­ря­док дей­ствий в цикле и умень­шив K после за­вер­ше­ния цикла, но эти дей­ствия не раз­ре­ше­ны по усло­вию за­да­чи.

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

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

Сведения о системе и ошибке

С компьютера на ПЛК подаются уставки (времена, флаги режимов) и команды на устройство.
Из ПЛК на компьютер выдаются сигналы статуса устройства и времени до конца команды на это устройство. Сигналы пакуются в слова, для минимизации объемов приема и передачи.
Из ПЛК на устройство выдаются команды.
Устройство выдает на ПЛК свои статусы.

image

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

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

Поиск

Цифрами в круглых скобках показаны места проверок, соответствующие цифрам на схеме ниже.

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

Было установлено, что ошибка присутствует не только в SCADA (1) (там, где она собственно была обнаружена), но и в OPC сервере (2).

Дальнейший разбор показал, что ошибка присутствует и в ПЛК, как минимум в слове, формируемом для компьютера (3).

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

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

Сравнение с кодами других объектов, на которых этой ошибки нет – различий не выдает. Полная идентичность. Вероятность ошибки в программе ПЛК уменьшается (5).

Отключается компьютер, как возможный источник ошибки, записывающий что-то в данную область памяти. Ошибка сохраняется. Вероятность ошибки из-за компьютера стремится к нулю. Соответственно, не смотря ни на что, проблема все-таки в ПЛК (6).

Ремарка: Также можно было, отключив ПЛК, руками менять статусы в OPC. Но такой вариант был сложнее технически, а в целом эти две проверки практически равнозначны.

Перенесение слова статуса, передаваемого из ПЛК на компьютер, в другую область памяти ПЛК ничего не дает. Ошибка сохраняется.

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

  1. Подача команды (без нее не понятно как проверять).
  2. Таймер, с которого берется время до сброса команды.
  3. Формирование слова на компьютере из статуса и времени до сброса команды.

image

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

Взамен вставляется новый таймер. Тщательно осматривается на предмет нелепостей. Таймер самый заурядный, ничего необычного. Таких в программе еще штук 200. Но ошибка появляется (8)

  1. Запись статусов устройства в младший байт слова.
  2. Замена старшего и младшего байт местами командой SWAP_WORD (статусы переносятся в старший байт)
  3. По AND запись времени в младший байт слова

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

  1. Запись времени устройства в младший байт слова.
  2. В промежуточной переменной статусы умножаются на 256, сдвигаясь в старший байт слова.
  3. По OR производится запись статусов в старший байт слова.

image

После разбора — ситуация становится окончательно понятной.

Причина ошибки:

Операторы увеличили стандартное время таймаута с 1,5 до 10 минут.
И если 1,5 минуты это 90 секунд, то 10 минут это 600 секунд.
600 секунд не влезали в младший байт (максимум 256), и часть времени писалась в старший.

Суть последней проверки:

При записи сначала времени, и лишь затем статуса – статус забивал биты переполнения, приходившие от значения времени. А при обратной последовательности команд, время наоборот забивало своими битами статус.

Решение:

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

И они работали они долго и счастливо, и сломались в один день.

Выводы

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

По сути не очень важно, где именно ищется ошибка — в электронике, в ПЛК, на компьютере или где-то еще. Общие принципы всегда примерно одинаковы:

  1. По максимуму собрать информацию о проблеме — где и как она проявляется. Осциллографы, снифферы, утилиты от Русиновича, логи, градусники, в общем всё, что можно использовать в данном случае. Не зависит ли она от времени года, прихода уборщицы, или барометрического давления.
  2. Вывести из-под подозрения как можно большую часть. Перерезая дорожки на печатных платах, отключая теги, выводя из системы отдельные компьютеры. Хуже, если есть какие-нибудь обратные связи и прочие хендшейки. Тогда можно попытаться либо организовать проверку приняв во внимание отсутствие части системы, либо пробовать проэмулировать часть, например искусственно подавая сигнал на вход обратной связи. В общем думать.
  3. По возможности доводить каждую проверку до конца, даже если вдруг появилась «мысль!». Потому-что «мысль!» может и не сработать (и до обидного часто не срабатывает), а результатов проверки лишаешься.
  4. В оставшемся куске — менять всё, что вызывает подозрения. Если это ПО — попробовать переустановить или заменить на аналогичное. В принципе есть вариант начать с этого пункта. Лично видел инженера, при ремонте платы на 40-50 микросхем К155 серии, выкусившего их все и впаявшего новые. Но это на мой взгляд скорее пример того, как не надо делать. Потому-что даже если все заработает, конкретики не получишь. Тем более, что в описанном случае этот вариант не прошел и неисправность сохранилась. В общем — я этого не говорил.

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

Извиняюсь за вероятную сложность чтения.
Тема не очень художественная, плюс к этому попытался сократить, пропуская не очень существенные моменты, вроде вынужденного отказа от BreakPoint'ов, из-за цикличности выполнения программы в ПЛК и наличия таймера.

Читайте также: