Какая самая жесткая ошибка, которую вы когда-либо нашли и фиксировали? [закрыто] -- debugging пол Связанный проблема

What's the toughest bug you ever found and fixed? [closed]


63
vote

проблема

русский
<в сторону CLASS = "S-NEWACTS S-WELTIVE__info JS-Post-New Imide MB16« Роль = «Статус»>
<Путь d = "M15 6.38A6.48 6.48 0 007.78. 04H-.02A6.49 6.49 0 002.05 5.6A6.31 6.31 0 002.39 5.75C.49.39.76.93.76 1.5V.24C0 1.07.89 1.9 1.92 1.92.75C1.04 0 1.92-.83 1.92-1.9v-. 2C0-.6.26-1.15.7-1.6.26-1.15.7-1.48A6.32 6.32 0 0015 6.37ZM4.03 5.85A4.49 4.49 0 018 2.02A4.48 4,48 0 015 4.36 4.3 4,3 0 01-1.72 3.44C-01-1.74-1.5 1.9- 1.5 3.08V.1H7.2V-.14C0-1.23-.6-2.34-1.3-1.32.32-1.53-3.07A4.32.32.32 0 01-1.64-3.94ZM10 18A1 1 0 000-2х7А1 1 0 100 2H3Z ">
Как оно в настоящее время стоит, этот вопрос не подходит для нашего Q и AMP; формат. Мы ожидаем, что ответы будут поддерживаться фактами, ссылками или опытом, но этот вопрос, скорее всего, запрашивает дебаты, аргументы, опрос или расширенное обсуждение. Если вы чувствуете, что этот вопрос может быть улучшен и, возможно, вновь открыт, Посетите справочный центр для руководства.
Закрыто 9 лет назад . <в сторону CLASS = "S-NEWACTS S-WELTIVE__info JS-Post-New Imide MB16« Роль = «Статус»>
заблокирован . Этот вопрос и его ответы находятся заблокированы потому что вопрос не входит в тему, но имеет историческое значение. В настоящее время он не принимает новые ответы или взаимодействия.

Что ему трудно найти? Как вы отслеживали его?

не достаточно близко, чтобы закрыть, но см. Также
https://stackoverflow.com/questions/175854/what- Самый смешной ошибок - вы когда-либо опытный

Английский оригинал

What made it hard to find? How did you track it down?

Not close enough to close but see also
https://stackoverflow.com/questions/175854/what-is-the-funniest-bug-youve-ever-experienced

</div
  
 
 

Список ответов

201
 
vote

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

100% воспроизводимой ошибки.

Я не ребенку ты не!

Вот почему:

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

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

Действительно классика.

 

A jpeg parser, running on a surveillance camera, which crashed every time the company's CEO came into the room.

100% reproducible error.

I kid you not!

This is why:

For you who doesn't know much about JPEG compression - the image is kind of broken down into a matrix of small blocks which then are encoded using magic etc.

The parser choked when the CEO came into the room, because he always had a shirt with a square pattern on it, which triggered some special case of contrast and block boundary algorithms.

Truly classic.

</div
 
 
       
       
115
 
vote

Это не случилось со мной, но друг рассказал мне об этом.

Он должен был отладить приложение, которое было бы очень редко потерпеть крах. Это только потерпит неудачу по средам - ​​в сентябре - после 9-го. Да, 362 дня года, это было хорошо, и три дня из года он сразу потерпел крах.

Это отформатировало бы дату «среда, 22 сентября 2008 года», но буфер был слишком коротким символом - так что это только вызвало бы проблему, когда у вас был 2-значный дом в день с самым длинным именем в месяц с самым длинным именем.

 

This didn't happen to me, but a friend told me about it.

He had to debug a app which would crash very rarely. It would only fail on Wednesdays -- in September -- after the 9th. Yes, 362 days of the year, it was fine, and three days out of the year it would crash immediately.

It would format a date as "Wednesday, September 22 2008", but the buffer was one character too short -- so it would only cause a problem when you had a 2 digit DOM on a day with the longest name in the month with the longest name.

</div
 
 
       
       
50
 
vote

Это было на Linux, но могло бы произойти практически на любой ОС. Теперь большинство из вас, вероятно, знакомы с API BSD Socket. Мы с радостью используем его год после года, и это работает.

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

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

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

Наконец (и, к счастью), я вспомнил, что массивное количество розетков может быть проблемой с выбором (), который ждет изменения состояния на сокетах (может прочитать / может написать / ошибку). Конечно, наше приложение начало уволить ущерб именно в тот момент, когда он достиг розетки с дескриптором 1025. Проблема в том, что выберите () работает с параметрами битового поля. Битовые поля заполнены MACROS FD_SET () и друзьями, которые не проверяют свои параметры для действительности.

Так что каждый раз, когда мы получили более 1024 дескрипторов (каждая ОС имеет свой собственный предел, ядра Vanilla Linux имеют 1024, фактическое значение определяется как fd_setsize), макрос fd_set с радостью перезаписывает его битовое поле и пишут мусор в следующую структуру в объем памяти.

Я заменил все выборы () вызовы с опросом (), который является хорошо спроектированной альтернативой выбору Arcane Select (), а большие нагрузки никогда не были проблемой Everafter. Нам повезло, потому что все обрабатывающие сокеты были в одном рамочном классе, где 15 минут работы могут решить проблему. Было бы очень хуже, если выбирать () звонки были посыпаны по всему коду.

Извлеченные уроки:

    .
  • Даже если функция API 25 лет, и все используют его, он может иметь темные углы, которые вы еще не знаете

  • Незаменяемая память пишет в API макросы зла

  • Инструмент отладки, как очистить, не может помочь со всеми ситуациями, особенно когда используется много памяти

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

  • Многие приложения используют выберите (), не думая о пределе разъема. Поэтому я уверен, что вы можете вызвать ошибки во многих популярном программном обеспечении, просто используя много много розетки. К счастью, большинство приложений никогда не будет иметь более 1024 розеток.

  • вместо того, чтобы иметь безопасную API, разработчики ОС хотели бы поставить вину на разработчик. Страница Man Linux Select () говорит

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

вводит в заблуждение. Linux может открыть более 1024 розеток. И поведение абсолютно хорошо определено: использование неожиданных значений разрушит приложение. Вместо того, чтобы сделать макросы устойчивыми к незаконным ценностям, разработчики просто перезаписывают Оте структуры. Fd_set реализован как встроенная сборка (!) В заголовках Linux и будет оценивать на одну ассемблею записи. Не малейшие границы, проверяющие происходящее где угодно.

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

thrsten79

 

This was on Linux but could have happened on virtually any OS. Now most of you are probably familiar with the BSD socket API. We happily use it year after year, and it works.

We were working on a massively parallel application that would have many sockets open. To test its operation we had a testing team that would open hundreds and sometimes over a thousand connections for data transfer. With the highest channel numbers our application would begin to show weird behavior. Sometimes it just crashed. The other time we got errors that simply could not be true (e.g. accept() returning the same file descriptor on subsequent calls which of course resulted in chaos.)

We could see in the log files that something went wrong, but it was insanely hard to pinpoint. Tests with Rational Purify said nothing was wrong. But something WAS wrong. We worked on this for days and got increasingly frustrated. It was a showblocker because the already negotiated test would cause havoc in the app.

As the error only occured in high load situations, I double-checked everything we did with sockets. We had never tested high load cases in Purify because it was not feasible in such a memory-intensive situation.

Finally (and luckily) I remembered that the massive number of sockets might be a problem with select() which waits for state changes on sockets (may read / may write / error). Sure enough our application began to wreak havoc exactly the moment it reached the socket with descriptor 1025. The problem is that select() works with bit field parameters. The bit fields are filled by macros FD_SET() and friends which DON'T CHECK THEIR PARAMETERS FOR VALIDITY.

So everytime we got over 1024 descriptors (each OS has its own limit, Linux vanilla kernels have 1024, the actual value is defined as FD_SETSIZE), the FD_SET macro would happily overwrite its bit field and write garbage into the next structure in memory.

I replaced all select() calls with poll() which is a well-designed alternative to the arcane select() call, and high load situations have never been a problem everafter. We were lucky because all socket handling was in one framework class where 15 minutes of work could solve the problem. It would have been a lot worse if select() calls had been sprinkled all over of the code.

Lessons learned:

  • even if an API function is 25 years old and everybody uses it, it can have dark corners you don't know yet

  • unchecked memory writes in API macros are EVIL

  • a debugging tool like Purify can't help with all situations, especially when a lot of memory is used

  • Always have a framework for your application if possible. Using it not only increases portability but also helps in case of API bugs

  • many applications use select() without thinking about the socket limit. So I'm pretty sure you can cause bugs in a LOT of popular software by simply using many many sockets. Thankfully, most applications will never have more than 1024 sockets.

  • Instead of having a secure API, OS developers like to put the blame on the developer. The Linux select() man page says

"The behavior of these macros is undefined if a descriptor value is less than zero or greater than or equal to FD_SETSIZE, which is normally at least equal to the maximum number of descriptors supported by the system."

That's misleading. Linux can open more than 1024 sockets. And the behavior is absolutely well defined: Using unexpected values will ruin the application running. Instead of making the macros resilient to illegal values, the developers simply overwrite other structures. FD_SET is implemented as inline assembly(!) in the linux headers and will evaluate to a single assembler write instruction. Not the slightest bounds checking happening anywhere.

To test your own application, you can artificially inflate the number of descriptors used by programmatically opening FD_SETSIZE files or sockets directly after main() and then running your application.

Thorsten79

</div
 
 
   
   
43
 
vote

Мой была аппаратная проблема ...

В тот день я использовал DEC VAXSTATION с большим 21-дюймовым монитором CRT. Мы переехали в лабораторию в нашем новом здании и установили два викса в противоположных углах комнаты. После включения мой монитор мерцал Как дискотека (да, это было 80-е годы), но другой монитор не сделал.

Хорошо, поменяйте мониторам. Другой монитор (в настоящее время подключен к моему виксаку) мерцал, и мой бывший монитор (перемещается через комнату) не.

Я вспомнил, что мониторы на основе ЭЛТ были восприимчивы к магнитным полям. Фактически, они были - восприимчивы до 60 Гц чередующихся магнитных полей. Я сразу же подозревал, что что-то в моей рабочей зоне генерировал магнитное поле с изменением 60 Гц.

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

Чтобы проверить эту теорию, мы преобразовали VAXSTATION и его 85 фунт монитора в портативную систему. Мы разместили всю систему на роликовую тележку и подключили его к 100 футовым оранжевым удлинителем. План состоял в том, чтобы использовать эту настройку в качестве портативного измерителя прочности поля, чтобы найти оскорбительный кусок оборудования.

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

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

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

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

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

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

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

Мораль этой истории: горячие и нейтральные линии в вашей электропроводке переменного тока находятся рядом друг с другом для веской причины.

Теперь, все, что мне нужно было сделать, это было т Объясните управлению, почему им пришлось перевесить часть своего нового здания ...

 

Mine was a hardware problem...

Back in the day, I used a DEC VaxStation with a big 21" CRT monitor. We moved to a lab in our new building, and installed two VaxStations in opposite corners of the room. Upon power-up,my monitor flickered like a disco (yeah, it was the 80's), but the other monitor didn't.

Okay, swap the monitors. The other monitor (now connected to my VaxStation) flickered, and my former monitor (moved across the room) didn't.

I remembered that CRT-based monitors were susceptable to magnetic fields. In fact, they were -very- susceptable to 60 Hz alternating magnetic fields. I immediately suspected that something in my work area was generating a 60 Hz alterating magnetic field.

At first, I suspected something in my work area. Unfortunately, the monitor still flickered, even when all other equipment was turned off and unplugged. At that point, I began to suspect something in the building.

To test this theory, we converted the VaxStation and its 85 lb monitor into a portable system. We placed the entire system on a rollaround cart, and connected it to a 100 foot orange construction extension cord. The plan was to use this setup as a portable field strength meter,in order to locate the offending piece of equipment.

Rolling the monitor around confused us totally. The monitor flickered in exactly one half of the room, but not the other side. The room was in the shape of a square, with doors in opposite corners, and the monitor flickered on one side of a diagnal line connecting the doors, but not on the other side. The room was surrounded on all four sides by hallways. We pushed the monitor out into the hallways, and the flickering stopped. In fact, we discovered that the flicker only occurred in one triangular-shaped half of the room, and nowhere else.

After a period of total confusion, I remembered that the room had a two-way ceiling lighting system, with light switches at each door. At that moment, I realized what was wrong.

I moved the monitor into the half of the room with the problem, and turned the ceiling lights off. The flicker stopped. When I turned the lights on, the flicker resumed. Turning the lights on or off from either light switch, turned the flicker on or off within half of the room.

The problem was caused by somebody cutting corners when they wired the ceiling lights. When wiring up a two-way switch on a lighting circuit, you run a pair of wires between the SPDT switch contacts, and a single wire from the common on one switch, through the lights, and over to the common on the other switch.

Normally, these wires are bundeled together. They leave as a group from one switchbox, run to the overhead ceiling fixture, and on to the other box. The key idea, is that all of the current-carrying wires are bundeled together.

When the building was wired, the single wire between the switches and the light was routed through the ceiling, but the wires travelling between the switches were routed through the walls.

If all of the wires ran close and parallel to each other, then the magnetic field generated by the current in one wire was cancelled out by the magnetic field generated by the equal and opposite current in a nearby wire. Unfortunately, the way that the lights were actually wired meant that one half of the room was basically inside a large, single-turn transformer primary. When the lights were on, the current flowed in a loop, and the poor monitor was basically sitting inside of a large electromagnet.

Moral of the story: The hot and neutral lines in your AC power wiring are next to each other for a good reason.

Now, all I had to do was to explain to management why they had to rewire part of their new building...

</div
 
 
 
 
60
 
vote

Это требует узнать немного ассемблера Z-8000, которое я объясню, как мы идем.

Я работал над встроенной системой (в ассемблере Z-8000). Различное подразделение компании создала другую систему на одной платформе, и написала библиотеку функций, которые я также использовал в моем проекте. Ошибка заключалась в том, что каждый раз, когда я позвонил одной функции, программа разбилась. Я проверил все мои входы; Они были в порядке. Это должно было быть ошибкой в ​​библиотеке - за исключением того, что библиотека была использована (и работала нормально) в тысячах POS-сайтов по всей стране.

Теперь процессоры Z-8000 имеют 16 16-битных регистров, R0, R0, R1, R2 ... R15, которые также могут быть адресованы как 8 32-разрядными регистрами, названные RR0, RR2, RR4..RR14 и т. Д. Библиотека была написана с нуля, рефакторируя кучу старых библиотек. Это было очень чисто и последовало строгие стандарты программирования. В начале каждой функции каждый регистр, который будет использоваться в функции, был нажат на стек, чтобы сохранить его значение. Все было аккуратно; аккуратно - они были идеальны.

Тем не менее, я изучал ассемблер, перечисленный для библиотеки, и я заметил что-то странное о том, что функция - - в начале функции, у нее был нажимается rr0 / push rr2 и в конце, чтобы иметь POP RR2 / POP R0 Отказ Теперь, если вы не следили за этим, он нажал 4 значения в стеке в начале, но только удаляют 3 из них в конце. Это рецепт стихийных бедствий. Там неизвестное значение в верхней части стека, где требуется обратный адрес. Функция не может работать.

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

После некоторого времени отладки (который не был легким в ассемблере в встроенной системе с инструментами середины 1980-х годов), он всегда будет сбиваться на возвращении, потому что плохое значение отправляет его в случайном порядке. Очевидно, я должен был отладить рабочее приложение, чтобы выяснить, почему он не потерпел неудачу.

Ну, помните, что библиотека была очень хороша о сохранении значений в регистров, поэтому, как только вы поместите значение в реестр, он остался там. R1 был 0000 в нем. У нее всегда было 0000, когда была вызвана эта функция. Поэтому ошибка осталась 0000 в стеке. Поэтому, когда функция вернулась, она перешла бы к адресу 0000, что просто так случилось, что будет RET, что высказало бы следующее значение (правильный адрес возврата) от стека, и перейти к этому. Данные идеально замаскировали ошибку.

Конечно, в моем приложении у меня было другое значение R1, поэтому он просто разбился ....

 

This requires knowing a bit of Z-8000 assembler, which I'll explain as we go.

I was working on an embedded system (in Z-8000 assembler). A different division of the company was building a different system on the same platform, and had written a library of functions, which I was also using on my project. The bug was that every time I called one function, the program crashed. I checked all my inputs; they were fine. It had to be a bug in the library -- except that the library had been used (and was working fine) in thousands of POS sites across the country.

Now, Z-8000 CPUs have 16 16-bit registers, R0, R1, R2 ...R15, which can also be addressed as 8 32-bit registers, named RR0, RR2, RR4..RR14 etc. The library was written from scratch, refactoring a bunch of older libraries. It was very clean and followed strict programming standards. At the start of each function, every register that would be used in the function was pushed onto the stack to preserve its value. Everything was neat & tidy -- they were perfect.

Nevertheless, I studied the assembler listing for the library, and I noticed something odd about that function --- At the start of the function, it had PUSH RR0 / PUSH RR2 and at the end to had POP RR2 / POP R0. Now, if you didn't follow that, it pushed 4 values on the stack at the start, but only removed 3 of them at the end. That's a recipe for disaster. There an unknown value on the top of the stack where return address needed to be. The function couldn't possibly work.

Except, may I remind you, that it WAS working. It was being called thousands of times a day on thousands of machines. It couldn't possibly NOT work.

After some time debugging (which wasn't easy in assembler on an embedded system with the tools of the mid-1980s), it would always crash on the return, because the bad value was sending it to a random address. Evidently I had to debug the working app, to figure out why it didn't fail.

Well, remember that the library was very good about preserving the values in the registers, so once you put a value into the register, it stayed there. R1 had 0000 in it. It would always have 0000 in it when that function was called. The bug therefore left 0000 on the stack. So when the function returned it would jump to address 0000, which just so happened to be a RET, which would pop the next value (the correct return address) off the stack, and jump to that. The data perfectly masked the bug.

Of course, in my app, I had a different value in R1, so it just crashed....

</div
 
 
     
     
34
 
vote

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

 

A bug where you come across some code, and after studying it you conclude, "There's no way this could have ever worked!" and suddenly it stops working though it always did work before.

</div
 
 
         
         
28
 
vote

Один из продуктов, которые я помог построить на моей работе, работал на сайте клиента в течение нескольких месяцев, собирая и счастливо записывая каждое событие, которое он получил в базу данных SQL Server. Он очень хорошо провел около 6 месяцев, собирая около 35 миллионов записей или около того.

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

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

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

При работе на сервере однажды работаю на сервере, все еще собирая информацию отладки от приложений, когда они разбились, пытаясь выяснить, что происходит, сервер BSOD на меня. Когда сервер вернулся в Интернете, я открыл MiniDump в WINDBG, чтобы выяснить, что был оскорбительным водителем. Я получил имя файла и проследил его обратно в фактический файл. После изучения информации о версии в файле я понял, что она была частью антивирусного пакета McAfee, установленного на компьютере.

Мы отключили антивирус и не имели ни одной проблемы с момента !!

 

One of the products I helped build at my work was running on a customer site for several months, collecting and happily recording each event it received to a SQL Server database. It ran very well for about 6 months, collecting about 35 million records or so.

Then one day our customer asked us why the database hadn't updated for almost two weeks. Upon further investigation we found that the database connection that was doing the inserts had failed to return from the ODBC call. Thankfully the thread that does the recording was separated from the rest of the threads, allowing everything but the recording thread to continue functioning correctly for almost two weeks!

We tried for several weeks on end to reproduce the problem on any machine other than this one. We never could reproduce the problem. Unfortunately, several of our other products then began to fail in about the same manner, none of which have their database threads separated from the rest of their functionality, causing the entire application to hang, which then had to be restarted by hand each time they crashed.

Weeks of investigation turned into several months and we still had the same symptoms: full ODBC deadlocks in any application that we used a database. By this time our products are riddled with debugging information and ways to determine what went wrong and where, even to the point that some of the products will detect the deadlock, collect information, email us the results, and then restart itself.

While working on the server one day, still collecting debugging information from the applications as they crashed, trying to figure out what was going on, the server BSoD on me. When the server came back online, I opened the minidump in WinDbg to figure out what the offending driver was. I got the file name and traced it back to the actual file. After examining the version information in the file, I figured out it was part of the McAfee anti-virus suite installed on the computer.

We disabled the anti-virus and haven't had a single problem since!!

</div
 
 
     
     
26
 
vote

Я просто хочу указать довольно распространенную и неприятную ошибку, которая может происходить в этом времени Google:
Код вставки и печально известное минус

Это когда вы Copy вставьте какой-то код с помощью минус в Вместо того, вместо обычного персонажа ASCII гипген-минус ('-') .

ALT TEXT
Плюс, минус (U + 2212), дефис-минус (U + 002D)

Теперь, хотя минус предположительно отображается дольше, чем дольше, чем дефис-минус, на определенных редакторах (или на Windows DOS Shell), в зависимости от используемой афиши, он фактически визуализируется как обычный «-» дефис минус знак.

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

может быть не самая жесткая ошибка, но достаточно расстраивает;)

(Спасибо Шреевасар для обнаружения инверсии в моем оригинальном посте - см. Комментарии)

 

I just want to point out a quite common and nasty bug that can happens in this google-area time:
code pasting and the infamous minus

That is when you copy paste some code with an minus in it, instead of a regular ASCII character hyphen-minus ('-').

alt text
Plus, minus(U+2212), Hyphen-Minus(U+002D)

Now, even though the minus is supposedly rendered as longer than the hyphen-minus, on certain editors (or on a DOS shell windows), depending on the charset used, it is actually rendered as a regular '-' hyphen-minus sign.

And... you can spend hours trying to figure why this code does not compile, removing each line one by one, until you find the actual cause!

May be not the toughest bug out there, but frustrating enough ;)

(Thank you ShreevatsaR for spotting the inversion in my original post - see comments)

</div
 
 
         
         
19
 
vote

Первый был, что наш выпущенный продукт проявил ошибку, но когда я пытался отладить проблему, она не произошла. Я думал, что это был «выпуск против отладки» на первом месте - но даже когда я составлял код в режиме выпуска, я не мог воспроизвести проблему. Я пошел посмотреть, может ли какой-нибудь другой разработчик воспроизвести проблему. Неа. После большого расследования (создание смешанного кодового кода / C кода Code) вывода программы и выхода через код сборки выпущенного продукта (YUCK!) Я нашел оскорбительную линию. Но линия выглядела только хорошо для меня! Затем мне пришлось посмотреть, что сделала инструкции по сборке - и, конечно, недостаточно неправильной инструкции по сборке было в исполняемом исполняемости. Затем я проверил исполняемый файл, что создается моя среда сборки - она ​​имела правильную инструкцию сборки. Оказалось, что сборная машина как-то была повреждена и произвела плохой код сборки только для одной инструкции для этого приложения. Все остальное (в том числе предыдущие версии нашего продукта), создали идентичный код для других машин разработчиков. После того, как я продемонстрировал свое исследование менеджеру программного обеспечения, мы быстро повторно построили нашу сборку.

 

The first was that our released product exhibited a bug, but when I tried to debug the problem, it didn't occur. I thought this was a "release vs. debug" thing at first -- but even when I compiled the code in release mode, I couldn't reproduce the problem. I went to see if any other developer could reproduce the problem. Nope. After much investigation (producing a mixed assembly code / C code listing) of the program output and stepping through the assembly code of the released product (yuck!), I found the offending line. But the line looked just fine to me! I then had to lookup what the assembly instructions did -- and sure enough the wrong assembly instruction was in the released executable. Then I checked the executable that my build environment produced -- it had the correct assembly instruction. It turned out that the build machine somehow got corrupt and produced bad assembly code for only one instruction for this application. Everything else (including previous versions of our product) produced identical code to other developers machines. After I showed my research to the software manager, we quickly re-built our build machine.

</div
 
 
     
     
16
 
vote

где-то глубоко в кишечнике сетевого приложения была линия (упрощенная):

 <код> if (socket = accept() == 0)     return false;  //code using the socket()   

Что случилось, когда звонок преуспел? <Код> socket был установлен 1. Что делает <код> send() , когда дано 1? (например, в:

 <код> send(socket, "mystring", 7);   

Это печатает <код> stdout ... это я нашел через 4 часа удивления, почему со всем моим printf() printf() Вместо отправки данных по сети.

 

Somewhere deep in the bowels of a networked application was the line (simplified):

if (socket = accept() == 0)     return false;  //code using the socket() 

What happened when the call succeeded? socket was set to 1. What does send() do when given a 1? (such as in:

send(socket, "mystring", 7); 

It prints to stdout... this I found after 4 hours of wondering why, with all my printf()s taken out, my app was printing to the terminal window instead of sending the data over the network.

</div
 
 
   
   
15
 
vote

С Fortran на общий момент данных Minicomputer в 80-х годах у нас имел случай, когда компилятор вызывал константу 1 (один), который будет рассматриваться как 0 (ноль). Это произошло, потому что какой-то старый код передавал постоянную значение 1 к функции, которая объявила переменную в качестве параметра Fortran, что означало, что он (должен быть) неизменно. Из-за дефекта в коде мы выполнили задание переменной параметры, и компилятор радостно изменил данные в месте памяти, который он использовал для постоянной 1 к 0.

Многие несвязанные функции позже у нас был код, который сравнил с буквальной стоимостью 1, и тест потерпит неудачу. Я помню, как уставился на этот код в течение более длинного времени в отладчике. Я бы распечатал значение переменной, это было бы 1, но тест «если (Foo .eq. 1)» не удастся. Мне потребовалось много времени, прежде чем я подумал попросить отладчик распечатать то, что он думал, что значение 1 было. Затем он взял на себя много волос, чтобы отслеживать, обратно через код, чтобы найти, когда постоянная 1 стала 0.

 

With FORTRAN on a Data General minicomputer in the 80's we had a case where the compiler caused a constant 1 (one) to be treated as 0 (zero). It happened because some old code was passing a constant of value 1 to a function which declared the variable as a FORTRAN parameter, which meant it was (supposed to be) immutable. Due to a defect in the code we did an assignment to the parameter variable and the compiler gleefully changed the data in the memory location it used for a constant 1 to 0.

Many unrelated functions later we had code that did a compare against the literal value 1 and the test would fail. I remember staring at that code for the longest time in the debugger. I would print out the value of the variable, it would be 1 yet the test 'if (foo .EQ. 1)' would fail. It took me a long time before I thought to ask the debugger to print out what it thought the value of 1 was. It then took a lot of hair pulling to trace back through the code to find when the constant 1 became 0.

</div
 
 
 
 
13
 
vote

Не очень жесткий, но я много смеялся, когда он был раскрыт.

Когда я поддерживал систему обработки заказа 24/7 для интернет-магазина, клиент пожаловался, что его заказ был «усечен». Он утверждал, что, в то время как порядок он настроен на фактически содержащиеся позиции, система приняла гораздо меньше позиций без какого-либо предупреждения.

После того, как мы проследили порядок поток через систему, были обнаружены следующие факты. Там была сохраненная процедура, ответственная за хранение элементов заказа в базе данных. Принято список элементов заказа в виде строки, который закодировал список (product-id, quantity, price) Trimles, как это:

"" & lt; 12345, 3, 19.99 & gt; 56452, 1, 8,99 и GT; & lt; 26586, 2, 12.99 & gt; "

Теперь автор хранимой процедуры был слишком умным, чтобы прибегнуть к чему-либо, как обычное разборы и циклирование. Таким образом, он напрямую преобразовал строку в SQL Multi-INSERT, заменив <код> "<" с <код> "insert into ... values (" и <код> ">" с <код> ");" . Что было все хорошо и денди, если только он не хранит полученную строку в варечане (8000) переменной!

Что случилось, это то, что его <код> "insert ...; insert ...;" был усечен при 8000-м символах и для этого конкретного порядка был достаточно «счастливый», чтобы произойти прямо между insert S, так что < EM> Усеченный SQL остался синтаксически правильным .

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

 

Not very tough, but I laughed a lot when it was uncovered.

When I was maintaining a 24/7 order processing system for an online shop, a customer complained that his order was "truncated". He claimed that while the order he placed actually contained N positions, the system accepted much less positions without any warning whatsoever.

After we traced order flow through the system, the following facts were revealed. There was a stored procedure responsible for storing order items in database. It accepted a list of order items as string, which encoded list of (product-id, quantity, price) triples like this:

"<12345, 3, 19.99><56452, 1, 8.99><26586, 2, 12.99>"

Now, the author of stored procedure was too smart to resort to anything like ordinary parsing and looping. So he directly transformed the string into SQL multi-insert statement by replacing "<" with "insert into ... values (" and ">" with ");". Which was all fine and dandy, if only he didn't store resulting string in a varchar(8000) variable!

What happened is that his "insert ...; insert ...;" was truncated at 8000th character and for that particular order the cut was "lucky" enough to happen right between inserts, so that truncated SQL remained syntactically correct.

Later I found out the author of sp was my boss.

</div
 
 
12
 
vote

У меня была ошибка в консоли, которая произошла только после того, как вы боролись и выиграли длинный босс-битва, а затем только около 1 раз в 5. Когда это вызвало, он оставил бы оборудование на 100% и не мог говорить на внешний мир вообще.

Это была стейка, которую я когда-либо сталкивался; Изменение, автоматизация, инструментируя или отладка боевой битвы будут скрывать ошибку (и, конечно, мне придется сделать 10-20 пробежек, чтобы определить, что ошибка скрыта).

В конце я нашел проблему (гонка кэш / DMA / прерывании), читая код в течение 2-3 дней.

 

I had a bug in a console game that occurred only after you fought and won a lengthy boss-battle, and then only around 1 time in 5. When it triggered, it would leave the hardware 100% wedged and unable to talk to outside world at all.

It was the shyest bug I've ever encountered; modifying, automating, instrumenting or debugging the boss-battle would hide the bug (and of course I'd have to do 10-20 runs to determine that the bug had hidden).

In the end I found the problem (a cache/DMA/interrupt race thing) by reading the code over and over for 2-3 days.

</div
 
 
 
 
12
 
vote

Это обратно, когда я думал, что C ++ и цифровые часы были довольно аккуратно ...

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

В этом случае они были объектами COM. В ядре системы была компонент, который раздал множество литых маленьких объектов COM, которые все выглядят более или менее одинаковыми. Каждый был раздавлен многими различными клиентами, каждый из которых был ответственен за выполнение <код> AddRef() и Release() одинаковое количество раз.

Не было никакого способа автоматически рассчитать, который назвал каждый <код> AddRef , а имел ли они <код> "<"0 d.

Я провел несколько дней в отладчике, пишущий шестигранные адреса на маленьких кусках бумаги. Мой офис был покрыт им. Наконец я нашел виновник. Команда, которая спросила меня о помощи, была очень благодарна.

На следующий день я переключился на язык GC'D. *

(* не на самом деле правда, но было бы хорошим окончанием истории.)

 

This is back when I thought that C++ and digital watches were pretty neat...

I got a reputation for being able to solve difficult memory leaks. Another team had a leak they couldn't track down. They asked me to investigate.

In this case, they were COM objects. In the core of the system was a component that gave out many twisty little COM objects that all looked more or less the same. Each one was handed out to many different clients, each of which was responsible for doing AddRef() and Release() the same number of times.

There wasn't a way to automatically calculate who had called each AddRef, and whether they had Released.

I spent a few days in the debugger, writing down hex addresses on little pieces of paper. My office was covered with them. Finally I found the culprit. The team that asked me for help was very grateful.

The next day I switched to a GC'd language.*

(*Not actually true, but would be a good ending to the story.)

</div
 
 
 
 
12
 
vote

Брайан Cantrill от Sun Microsystems дал отличную технологию Google Tech по ошибке, который он отслеживал, используя инструмент, который он помог развить под названием DTRace.

Tech Talk , отвратительный, информативный и очень впечатляющий (и <сильный> длинный , около 78 минут).

Я не буду давать никаких спойлеров здесь, на то, что была ошибка, но он начинает раскрывать виновника около 53:00.

 

Bryan Cantrill of Sun Microsystems gave an excellent Google Tech Talk on a bug he tracked down using a tool he helped develop called dtrace.

The The Tech Talk is funny, geeky, informative, and very impressive (and long, about 78 minutes).

I won't give any spoilers here on what the bug was but he starts revealing the culprit at around 53:00.

</div
 
 
12
 
vote

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

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

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

Это хороший пример типа ошибки, известный как A SchroEdinbug . Хотя большинство из нас слышали об этих своеобразных организациях, это жуткое чувство, когда вы на самом деле столкнулись с одним в дикой природе.

 

While testing some new functionality that I had recently added to a trading application, I happened to notice that the code to display the results of a certain type of trade would never work properly. After looking at the source control system, it was obvious that this bug had existed for at least a year, and I was amazed that none of the traders had ever spotted it.

After puzzling for a while and checking with a colleague, I fixed the bug and went on testing my new functionality. About 3 minutes later, my phone rang. On the other end of the line was an irate trader who complained that one of his trades wasn’t showing correctly.

Upon further investigation, I realized that the trader had been hit with the exact same bug I had noticed in the code 3 minutes earlier. This bug had been lying around for a year, just waiting for a developer to come along and spot it so that it could strike for real.

This is a good example of a type of bug known as a Schroedinbug. While most of us have heard about these peculiar entities, it is an eerie feeling when you actually encounter one in the wild.

</div
 
 
9
 
vote

Две самые жесткие ошибки, которые приходят к уму, были как в одном типе программного обеспечения, только один был в веб-версии, а одна в версии Windows.

Этот продукт представляет собой просмотрщик / редактор пола. Веб-версия имеет фронт вспышки, которая загружает данные как SVG. Теперь это работает нормально, только иногда браузер повесил. Только на нескольких рисунках, и только тогда, когда вы немного явились на мышь на рисунок. Я сузил проблему до одного нанесенного слоя, содержащего 1,5 МБ данных SVG. Если бы я взял только подраздел данных, любой подраздел, повешение не произошло. В конце концов он осел на меня, что проблема, вероятно, была, что в файле было несколько разных разделов, что в комбинации вызывала ошибку. Конечно, достаточно, после случайного удаления участков слоя и тестирования для ошибки, я обнаружил, что оскорбительный комбинация выступлений чертежей. Я написал обходной путь в генераторе SVG, и ошибка была исправлена ​​без изменения строки ActionScript.

В том же продукте на стороне Windows, написанный в Delphi, у нас была сопоставимая проблема. Здесь продукт принимает файлы AutoCAD DXF, импортирует их в внутренний формат чертежа и отображает их в пользовательском чертеже. Эта процедура импорта не особенно эффективна (она использует много подстрочных копирований), но он выполняет работу. Только в этом случае это было не так. Файл 5 мегабайта, как правило, импортирует через 20 секунд, но в одном файле потребовалось 20 минут, потому что след памяти надувной для гигабайта или более. Сначала это казалось типичной утечкой памяти, но инструменты утечки памяти сообщали о его чистоте, и инспекция ручной кода либо ничего не появилась. Проблема оказалась ошибками в распределении памяти Delphi 5. В некоторых условиях, которые этот конкретный файл был надлежащим образом воссоздан, он был бы склонен к серьезной фрагментации памяти. Система будет продолжать пытаться выделить большие струны и найти нигде, чтобы поставить их, кроме как выше на самых высоких выделенных блоке памяти. Интеграция новой библиотеки распределения памяти исправлена ​​ошибка, не изменив строку кода импорта.

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

 

The two toughest bugs that come to mind were both in the same type of software, only one was in the web-based version, and one in the windows version.

This product is a floorplan viewer/editor. The web-based version has a flash front-end that loads the data as SVG. Now, this was working fine, only sometimes the browser would hang. Only on a few drawings, and only when you wiggled the mouse over the drawing for a bit. I narrowed the problem down to a single drawing layer, containing 1.5 MB of SVG data. If I took only a subsection of the data, any subsection, the hang didn't occur. Eventually it dawned on me that the problem probably was that there were several different sections in the file that in combination caused the bug. Sure enough, after randomly deleting sections of the layer and testing for the bug, I found the offending combination of drawing statements. I wrote a workaround in the SVG generator, and the bug was fixed without changing a line of actionscript.

In the same product on the windows side, written in Delphi, we had a comparable problem. Here the product takes autocad DXF files, imports them to an internal drawing format, and renders them in a custom drawing engine. This import routine isn't particularly efficient (it uses a lot of substring copying), but it gets the job done. Only in this case it wasn't. A 5 megabyte file generally imports in 20 seconds, but on one file it took 20 minutes, because the memory footprint ballooned to a gigabyte or more. At first it seemed like a typical memory leak, but memory leak tools reported it clean, and manual code inspection turned up nothing either. The problem turned out to be a bug in Delphi 5's memory allocator. In some conditions, which this particular file was duly recreating, it would be prone to severe memory fragmentation. The system would keep trying to allocate large strings, and find nowhere to put them except above the highest allocated memory block. Integrating a new memory allocation library fixed the bug, without changing a line of import code.

Thinking back, the toughest bugs seem to be the ones whose fix involves changing a different part of the system than the one where the problem occurs.

</div
 
 
 
 
9
 
vote

Когда Pet Bunny Bunny Bunny Bunny Grawed Partway по кабелю Ethernet. да. Это было плохо.

 

When the client's pet bunny rabbit gnawed partway through the ethernet cable. Yes. It was bad.

</div
 
 
 
 
8
 
vote
У

была ошибка на платформе с очень плохой на устройстве отладчик. Мы получили бы CRANCE на устройстве , если мы добавили printf к коду. Затем он столкнулся бы на другом месте, чем расположение печати. Если мы переместили printf, Crash авария будет двигаться или исчезнуть . На самом деле, если мы изменили этот код путем переупорядочения некоторых простых утверждений, авария произойдет некоторые, где не связаны с кодом, который мы сделали изменились.

Оказывается, в Relocator для нашей платформы был ошибка BUG. ReloCator не был нулем инициализирует раздел Zi, а скорее, используя таблицу перемещения для инициализации значений. Поэтому в любое время таблица переселения изменена в двоичной ошибке, будет двигаться. Так что просто добавить Printf изменит таблицу перемещения там для ошибки.

 

Had a bug on a platform with a very bad on device debugger. We would get a crash on the device if we added a printf to the code. It then would crash at a different spot than the location of the printf. If we moved the printf, the crash would ether move or disappear. In fact, if we changed that code by reordering some simple statements, the crash would happen some where unrelated to the code we did change.

It turns out there was a bug in the relocator for our platform. the relocator was not zero initializing the ZI section but rather using the relocation table to initialze the values. So any time the relocation table changed in the binary the bug would move. So simply added a printf would change the relocation table an there for the bug.

</div
 
 
   
   
8
 
vote

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

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

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

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

 

This happened to me on the time I worked on a computer store.

One customer came one day into shop and tell us that his brand new computer worked fine on evenings and night, but it does not work at all on midday or late morning. The trouble was that mouse pointer does not move at that times.

The first thing we did was changing his mouse by a new one, but the trouble were not fixed. Of course, both mouses worked on store with no fault.

After several tries, we found the trouble was with that particular brand and model of mouse. Customer workstation was close to a very big window, and at midday the mouse was under direct sunlight. Its plastic was so thin that under that circumstances, it became translucent and sunlight prevented optomechanical wheel for working :|

</div
 
 
7
 
vote

Моя команда унаследовала CGI, на основе CGI, многопоточное веб-приложение C ++. Основная платформа была окна; Дальнейшая вторичная платформа была Solaris с потоками POSIX. Стабильность на Solaris была катастрофой по какой-то причине. У нас были различные люди, которые смотрели на проблему более года, выключенные и на (в основном), в то время как наш продавец успешно подтолкнул версию Windows.

Симптом был жалкая стабильность: широкий спектр системы сбоит с небольшим рифмом или причиной. Приложение использовало как CORBA, так и домой протокол. Один разработчик пошел до сих пор, чтобы удалить всю подсистему CORBA как отчаянную меру: не повезло.

Наконец, старший, оригинальный разработчик удивился вслух о идее. Мы смотрели в него и в конечном итоге нашли проблему: на Solaris, на параметра параметра совокупности времени (или время выполнения) для настройки размера стека для исполняемого. Он был установлен неправильно: слишком маленький. Итак, приложение заканчивается из стека и печатания стека следов, которые были полными красными фруктами.

Это был настоящий кошмар.

Извлеченные уроки:

    .
  • Мозговой штурм, мозговой штурм, мозговой штурм
  • Если что-то шел гайки на другой, заброшенной платформы, это, вероятно, является атрибутом платформы окружающей среды
  • Остерегайтесь проблем, которые передаются от разработчиков, которые покидают команду. Если возможно, свяжитесь с предыдущими людьми на личной основе для Garner Info и Background. Просить, умолять, составить сделку. Потеря опыта должна быть минимизирована на всех расходах.
 

My team inherited a CGI-based, multi-threaded C++ web app. The main platform was Windows; a distant, secondary platform was Solaris with Posix threads. Stability on Solaris was a disaster, for some reason. We had various people who looked at the problem for over a year, off and on (mostly off), while our sales staff successfully pushed the Windows version.

The symptom was pathetic stability: a wide range of system crashes with little rhyme or reason. The app used both Corba and a home-grown protocol. One developer went so far as to remove the entire Corba subsystem as a desperate measure: no luck.

Finally, a senior, original developer wondered aloud about an idea. We looked into it and eventually found the problem: on Solaris, there was a compile-time (or run-time?) parameter to adjust the stack size for the executable. It was set incorrectly: far too small. So, the app was running out of stack and printing stack traces that were total red herrings.

It was a true nightmare.

Lessons learned:

  • Brainstorm, brainstorm, brainstorm
  • If something is going nuts on a different, neglected platform, it is probably an attribute of the environment platform
  • Beware of problems that are transferred from developers who leave the team. If possible, contact the previous people on personal basis to garner info and background. Beg, plead, make a deal. The loss of experience must be minimized at all costs.
</div
 
 
7
 
vote

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

Представительское резюме приложения на случай, если вы еще не видели сообщение ADAM-сообщению: программное обеспечение для автоматизации продаж ... на ноутбуках ... конец дня, которые они набрали ... чтобы синхронизировать с базой данных для матери. < / P >.

Один пользователь жаловался, что каждый раз, когда он пытался набрать, приложение будет сбой. Люди поддержки клиентов проходили все их обычно по телефону диагностики, и они ничего не нашли. Итак, им пришлось переоценить Ultimate: у пользователя FedEx ноутбук на наши офисы. (Это было очень большое дело, так как локальная база данных каждого ноутбука была настроена для пользователя, поэтому должен был быть подготовлен новый ноутбук, отправлен пользователю для него, чтобы он использовал, пока мы работали на его оригинале, тогда нам пришлось отменить У него наконец-то синхронизируйте данные на первом оригинальном ноутбуке).

Так, когда прибыл ноутбук, мне дали мне возможность выяснить проблему. Теперь синхронизация включала в себя подключение телефонной линии к внутреннему модему, переходя на страницу «Связь» нашего приложения и выбрав номер телефона из раскрывающегося списка (с последним числом, используемым предварительно выбранным). Числа в DDL были частью настройки, и были в основном, количество офиса, количество офиса, префиксированного «+1», количество офиса, префиксированного с «9 ,,», если они были Вызов из отеля и т. Д.

Итак, я нажимаю значок «Comm» и нажал возврат. Он набрал набранный, он подключен к модему - а затем немедленно разбился. Я устал пару раз. 100% повторяемость.

Итак, подключен объем данных между ноутбуком и AMP; Телефонная линия и посмотрела на данные, проходящие через строку. Это выглядело довольно странно ... Самая странная часть была то, что я могу прочитать его!

Пользователь, по-видимому, хотел использовать свой ноутбук, чтобы набрать в локальную систему BBS, и поэтому измените конфигурацию приложения для использования номера телефона BBS вместо компании. Наше приложение ожидало, что наш запатентованный бинарный протокол - не длинные потоки текста ASCII. Буферы переполнены - Kaboom!

Тот факт, что проблемный набор в начале сразу после того, как он изменил номер телефона, может дать среднему пользователю подсказку, что это было причина проблемы, но этот парень никогда не упоминал это. < / P >.

Я зафиксировал номер телефона и отправил его обратно в службу поддержки, с примечанием, избранным парням «Undhead пользователь недели». (*)


(*) Okokok ... Вероятно, очень хороший шанс, что на самом деле произошло в том, что ребенок парень, увидев его отца набрать каждую ночь, подумал, что именно вы набираете в BBS и изменили номер телефона когда он когда-нибудь был дома один с ноутбуком. Когда это разбилось, он не хотел признать, что коснулся ноутбука, не говоря уже о нарушении; Поэтому он просто отложил его и никому не говорил.

 

Adam Liss's message above talking about the project we both worked on, reminded me of a fun bug I had to deal with. Actually, it wasn't a bug, but we'll get to that in a minute.

Executive summary of the app in case you haven't seen Adam message yet: sales-force automation software...on laptops...end of the day they dialed up ...to synchronize with the Mother database.

One user complained that every time he tried to dial in, the application would crash. The customer support folks went through all their usually over-the-phone diagnostic tricks, and they found nothing. So, they had to relent to the ultimate: have the user FedEx the laptop to our offices. (This was a very big deal, as each laptop's local database was customized to the user, so a new laptop had to be prepared, shipped to the user for him to use while we worked on his original, then we had to swap back and have him finally sync the data on first original laptop).

So, when the laptop arrived, it was given to me to figure out the problem. Now, syncing involved hooking up the phone line to the internal modem, going to the "Communication" page of our app, and selecting a phone number from a Drop-down list (with last number used pre-selected). The numbers in the DDL were part of the customization, and were basically, the number of the office, the number of the office prefixed with "+1", the number of the office prefixed with "9,,," in case they were calling from an hotel etc.

So, I click the "COMM" icon, and pressed return. It dialed in, it connected to a modem -- and then immediately crashed. I tired a couple more times. 100% repeatability.

So, a hooked a data scope between the laptop & the phone line, and looked at the data going across the line. It looked rather odd... The oddest part was that I could read it!

The user had apparently wanted to use his laptop to dial into a local BBS system, and so, change the configuration of the app to use the BBS's phone number instead of the company's. Our app was expecting our proprietary binary protocol -- not long streams of ASCII text. Buffers overflowed -- KaBoom!

The fact that a problem dialing in started immediately after he changed the phone number, might give the average user a clue that it was the cause of the problem, but this guy never mentioned it.

I fixed the phone number, and sent it back to the support team, with a note electing the guy the "Bonehead user of the week". (*)


(*) OkOkOk... There's probably a very good chance what actually happened in that the guy's kid, seeing his father dial in every night, figured that's how you dial into BBS's also, and changed the phone number sometime when he was home alone with the laptop. When it crashed, he didn't want to admit he touched the laptop, let alone broke it; so he just put it away, and didn't tell anyone.

</div
 
 
6
 
vote

Это было во время моего дипломаского тезиса. Я писал программу для моделирования эффекта высокой интенсивности лазера на атом гелия, используя Fortran.

Один тестовый прогон работал так:

    .
  • Рассчитать Intial Quantum State, используя программу 1, около 2 часов.
  • Запустите основное моделирование на данных с первого шага, для самых простых случаев примерно от 20 до 50 часов.
  • проанализировать вывод с третьей программой, чтобы получить значимые значения, такие как энергия, Tork, импульс

Они должны быть постоянными в общей сложности, но они не были. Они сделали все виды странных вещей.

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

Таким образом, я узнал, что я написал через конец массива, который изменил постоянную !

Друг сказал, что он когда-то изменил литерал 2 с такой ошибкой.

 

It was during my diploma thesis. I was writing a program to simulate the effect of high intensity laser on a helium atom using FORTRAN.

One test run worked like this:

  • Calculate the intial quantum state using program 1, about 2 hours.
  • run the main simulation on the data from the first step, for the most simple cases about 20 to 50 hours.
  • then analyse the output with a third program in order to get meaningful values like energy, tork, momentum

These should be constant in total, but they weren't. They did all kinds of weird things.

After debugging for two weeks I went berserk on the logging and logged every variable in every step of the simulation including the constants.

That way I found out that I wrote over an end of an array, which changed a constant!

A friend said he once changed the literal 2 with such a mistake.

</div
 
 
5
 
vote

тупик в моей первой многопоточной программе!

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

 

A deadlock in my first multi-threaded program!

It was very tough to find it because it happened in a thread pool. Occasionally a thread in the pool would deadlock but the others would still work. Since the size of the pool was much greater than needed it took a week or two to notice the first symptom: application completely hung.

</div
 
 
5
 
vote

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

Некоторые различные примеры:

  1. ffmpeg имеет эту неприятную привычку создавать предупреждение о «обрезке Brainfart» (обращаясь к случаю, когда значения обрезки в потоке являются и GT; = 16), когда значения урожая в потоке были фактически совершенно действительными. Я исправил его, добавив три символа: «H- & GT;». ".

  2. x264 имел ошибку, где в чрезвычайно редких случаях (один в миллионах кадров) с определенными вариантами, он позволил бы сделать случайным блоком совершенно не тот цвет. Я исправил ошибку, добавив букву «O» в два места в коде. Оказалось, что я провел имя #define в предыдущем фиксации.

 

I have spent hours to days debugging a number of things that ended up being fixable with literally just a couple characters.

Some various examples:

  1. ffmpeg has this nasty habit of producing a warning about "brainfart cropping" (referring to a case where in-stream cropping values are >= 16) when the crop values in the stream were actually perfectly valid. I fixed it by adding three characters: "h->".

  2. x264 had a bug where in extremely rare cases (one in a million frames) with certain options it would produce a random block of completely the wrong color. I fixed the bug by adding the letter "O" in two places in the code. Turned out I had mispelled the name of a #define in an earlier commit.

</div
 
 
5
 
vote

Моя первая «реальная» работа была для компании, которая написала программное обеспечение автоматизации продаж клиент-сервера. Наши клиенты управляли клиентским приложением в своих (15-фунтовых) ноутбуках и в конце дня они набрали наши серверы Unix для синхронизации с базой данных матери. После серии жалоб, мы обнаружили, что астрономическое количество вызовов падали в самом начале, во время аутентификации.

После недель отладки, мы обнаружили, что аутентификация всегда может не удалось, если входящий вызов ответил на Getty Process на сервере, идентификатор процесса которого содержал четное число, за которым следует сразу на 9. Аутентификация была схемой на дому, которая зависела от 8-символьного строкового представления PID; Ошибка вызвала оскорбительную PID схватить Getty, которая отвечала с новой PID. Второй или третий вызов обычно нашел приемлемый PID, и автоматический повторный повторный повторный повторный повторный повторный повторный затрагивал для клиентов вмешиваться, поэтому его не считали значительной проблемой до тех пор, пока законопроекты по телефону не пришли к концу месяца.

«Исправление» (AHEM) состояла в том, чтобы преобразовать PID в строку, представляющую его значение в othal otal , а не десятичным, что делает невозможным содержать 9 и ненужную для решения основной проблемы. < / P >.

 

My first "real" job was for a company that wrote client-server sales-force automation software. Our customers ran the client app on their (15-pound) laptops, and at the end of the day they dialed up to our unix servers to synchronize with the Mother database. After a series of complaints, we found that an astronomical number of calls were dropping at the very beginning, during authentication.

After weeks of debugging, we discovered that the authentication always failed if the incoming call was answered by a getty process on the server whose Process ID contained an even number followed immediately by a 9. Turns out the authentication was a homebrew scheme that depended on an 8-character string representation of the PID; a bug caused an offending PID to crash the getty, which respawned with a new PID. The second or third call usually found an acceptable PID, and automatic redial made it unnecessary for the customers to intervene, so it wasn't considered a significant problem until the phone bills arrived at the end of the month.

The "fix" (ahem) was to convert the PID to a string representing its value in octal rather than decimal, making it impossible to contain a 9 and unnecessary to address the underlying problem.

</div
 
 
     
     
5
 
vote

в основном, все, что связано с нитями.

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

 

Basically, anything involving threads.

I held a position at a company once in which I had the dubious distinction of being one of the only people comfortable enough with threading to debug nasty issues. The horror. You should have to get some kind of certification before you're allowed to write threaded code.

</div
 
 
5
 
vote

Я слышал о классической ошибке обратно в среднюю школу; Терминал, который вы можете входить в систему, если вы сидели в кресле перед ним. (Это отклонило бы ваш пароль, если вы стояли.)

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

В конце концов оказалось, что какой-то придурок поменял пару соседних клавиш на клавиатуре, E / R и C / V IIRC, а когда вы сели, вы набрали и вошли, но когда вы стояли, вы имели Чтобы охотиться на клевете, так что вы посмотрели на неверные этикетки и не удалось.

 

I heard about a classic bug back in high school; a terminal that you could only log into if you sat in the chair in front of it. (It would reject your password if you were standing.)

It reproduced pretty reliably for most people; you could sit in the chair, log in, log out... but if you stand up, you're denied, every time.

Eventually it turned out some jerk had swapped a couple of adjacent keys on the keyboard, E/R and C/V IIRC, and when you sat down, you touch-typed and got in, but when you stood, you had to hunt 'n peck, so you looked at the incorrent labels and failed.

</div
 
 
4
 
vote

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

 

While I don't recall a specific instance, the toughest category are those bugs which only manifest after the system has been running for hours or days, and when it goes down, leaves little or no trace of what caused the crash. What makes them particularly bad is that no matter how well you think you've reasoned out the cause, and applied the appropriate fix to remedy it, you'll have to wait for another few hours or days to get any confidence at all that you've really nailed it.

</div
 
 
   
   
4
 
vote

Наш сетевой интерфейс, ATM-карта с поддержкой DMA, очень иногда бывает поврежденные данные в полученных пакетах. CRC AAL5 проверил как правильно, когда пакет сошел с провода, но данные DMAD к памяти будут неверными. Контрольная сумма TCP, как правило, поймает его, но обратно в заправочные дни ATM Cure Thours были врезаны по поводу бега нативных приложений непосредственно на AAL5, доминируя с TCP / IP. В конце концов мы заметили, что коррупция произошла только на некоторых моделях рабочей станции продавцов (кто останется безымянным), а не другим.

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

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

 

Our network interface, a DMA-capable ATM card, would very occasionally deliver corrupted data in received packets. The AAL5 CRC had checked out as correct when the packet came in off the wire, yet the data DMAd to memory would be incorrect. The TCP checksum would generally catch it, but back in the heady days of ATM people were enthused about running native applications directly on AAL5, dispensing with TCP/IP altogether. We eventually noticed that the corruption only occurred on some models of the vendor's workstation (who shall remain nameless), not others.

By calculating the CRC in the driver software we were able to detect the corrupted packets, at the cost of a huge performance hit. While trying to debug we noticed that if we just stored the packet for a while and went back to look at it later, the data corruption would magically heal itself. The packet contents would be fine, and if the driver calculated the CRC a second time it would check out ok.

We'd found a bug in the data cache of a shipping CPU. The cache in this processor was not coherent with DMA, requiring the software to explicitly flush it at the proper times. The bug was that sometimes the cache didn't actually flush its contents when told to do so.

</div
 
 
   
   

Связанный проблема

1  WINDBG, как установить точку останова метода на конкретный процесс  ( Windbg how to set method breakpoint on specific process ) 
У меня есть виртуальная машина с <Код> VirtualKD Драйверы, установленные и прикрепленные к WINGBG, работающим на хост-машина. До сих пор мне удалось устано...

2  ADB над USB-устройством вне форума - LG Nexus 4 + Kubuntu 13  ( Adb over usb device offline lg nexus 4 kubuntu 13 ) 
lg nexus 4 Android 4.3 (USB отладки активный) ADB 1.0.31 На Кубунту 13 Мои /etc/udev/rules.d/51-Android.Rules взяты из здесь https://code.google.com/p...

0  Как я могу отладить деталь удаплителя (с настройкой) проекта установщика в Visual Studio 2008  ( How can i debug the uninstaller part with customaction of an installer project ) 
Я унаследовал этот раствор C #, который включает в себя проект установщика IX (куча файлов .wxs и некоторые файлы C #.). Ударверщик генерирует сообщение об ...

0  Совет отладки: не может видеть надувную макет в эмуляторе  ( Debugging advice cannot see inflated layout in emulator ) 
У меня довольно общий вопрос, но я новичок в разработке Android, так что все, что я спрашиваю, это для того, чтобы кто-то, надеюсь, укажет меня в правильном н...

2  Отладчик asp.net vs2010 mstest не останавливается на точках останова  ( Asp net vs2010 mstest debugger not stopping at breakpoints ) 
только создал новый веб-сайт ASP.NET с использованием VS2010 (ничего не изменил) щелкнул на элементе меню Test , используемый мастер тестирования для ген...

1  Отладка Ironpython-код в SharpDevelop 4.2  ( Debugging ironpython code in sharpdevelop 4 2 ) 
Я практикую Ironpython Coding в SharpDevelop 4.2, но у меня проблемы с отладкой. В окне местных жителей я не могу найти свои переменные. В простом скрипте, ка...

2  Eclipse LoadProperties, как в задаче  ( Eclipse loadproperties like in ant task ) 
Есть ли что-то вроде нагрузки на Anttask в Eclipse, чтобы я мог загрузить файл свойств, когда я хочу отладить в Eclipse. Спасибо! ...

5  Констанция номера линии в Actionscript 3.0?  ( Line number constant in actionscript 3 0 ) 
Есть ли постоянная константа строки или способ динамически проследить номер строки в ActionScript? делает ActionScript эквивалент <код> __LINE__ в php...

6  Как вы можете установить блок PHP + XDEBUG + (X) + Eclipse для работы с точками останова в модульных тестах?  ( How can you set up php xdebug xunit eclipse to work with breakpoints in ) 
Пробовали на некоторое время, чтобы правильно работать, но не повезло. В принципе, у меня есть Eclipse (3.3) с помощью инструментов разработки PHP (PDT) и пла...

4  Kindle Fire HD Разработчик Варианты  ( Kindle fire hd developer options ) 
Я пытаюсь разобраться, как включить «Параметры разработчика» (Использование GPU, границы макета, местоположение указателя и т. Д.) Для HOLDLE FIRE HD. Похоже,...

0  Как узнать, был ли SessionToken был реализован правильно?  ( How to know if sessiontoken was implemented properly ) 
Так что я пытаюсь реализовать простое местоположение AutoComlection с API Google API. Я использую услугу автозаполнения для этого (см.: https: //developers.g...

-2  Ошибка печати в файле PHP на ПК  ( Print error in file php on pc ) 
Я новый в PHP. Я запускаю file.php на моем компьютере с Firefox, но я не знаю, как посмотреть ошибку. Что я могу добавить, чтобы увидеть это, возможно, если у...

5  Delphi - пытаясь получить Stacktrace для исключения  ( Delphi trying to get stacktrace for an exception ) 
У меня есть регистратор исключения, который регистрирует все исключения в файл журнала: <код> class function TLogger.LogException (ACaller: String; E: Excep...

26  Легкий .NET отладчик?  ( Lightweight net debugger ) 
Я часто нужно отлаживать двоичные файлы .NET на тестовых машинах (по тестированию, я имею в виду, что машина не имеет на нем Visual Studio, она часто переигра...

16  Загрузка файла Некоторые байты были заменены символом замены Unicode во время загрузки файла  ( File load some bytes have been replaced with the unicode substitution character ) 
Я отладки в исходном коде .NET Framework внезапно, когда я вошел в файл их, Visual Studio 2010 поднял эту ошибку: Файл Загрузка: Некоторые байты были з...

Связанный проблема

1  WINDBG, как установить точку останова метода на конкретный процесс 
2  ADB над USB-устройством вне форума - LG Nexus 4 + Kubuntu 13 
0  Как я могу отладить деталь удаплителя (с настройкой) проекта установщика в Visual Studio 2008 
0  Совет отладки: не может видеть надувную макет в эмуляторе 
2  Отладчик asp.net vs2010 mstest не останавливается на точках останова 
1  Отладка Ironpython-код в SharpDevelop 4.2 
2  Eclipse LoadProperties, как в задаче 
5  Констанция номера линии в Actionscript 3.0? 
6  Как вы можете установить блок PHP + XDEBUG + (X) + Eclipse для работы с точками останова в модульных тестах? 
4  Kindle Fire HD Разработчик Варианты 
0  Как узнать, был ли SessionToken был реализован правильно? 
-2  Ошибка печати в файле PHP на ПК 
5  Delphi - пытаясь получить Stacktrace для исключения 
26  Легкий .NET отладчик? 
16  Загрузка файла Некоторые байты были заменены символом замены Unicode во время загрузки файла