2009-11-05 2 views
3

Я обнаружил повреждение памяти в моей встроенной среде (моя программа работает на приставке с собственной ОС). но я не мог получить основную причину этого. повреждение памяти само по себе обнаруживается после стресс-теста запуска и выхода из приложения несколько раз. что я не мог установить точку прерывания памяти, потому что поврежденная переменная меняет свой адрес каждый раз, когда приложение запускается, есть ли какая-то идея уловить основную причину этого искажения?Как получить основную причину повреждения памяти во встроенной среде?

(Точка останова памяти точки останова запущен, когда окружающая среда изменить значение дает адрес памяти)

Отметим также, что все мое программное обеспечение разработано с использованием языка C.

Благодарим за помощь.

ответ

0

Вы обнаруживаете повреждение памяти. Не могли бы вы быть более конкретными? Например, это авария с дампом ядра?

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

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

Printfs в пользовательских функциях malloc/realloc/free proxy или даже пользовательский распределитель Electric Fence может помочь, если это так просто, как переполнение буфера.

+0

Фактически повреждение памяти обнаруживается в структуре. Так что я занимаюсь наблюдением за этой структурой, когда она создана и заполнена. На этом этапе все кажется хорошим. но когда другой процесс смотрит на эту структуру, он получает поврежденные данные, поэтому я пришел к выводу, что в этом месте есть другой процесс записи. Я также упоминаю, что приложение работает над интерпретатором, и даже если приложение вылетает, интерпретатор отлично справляется с этим. также обратите внимание, что проблема систематическая, поэтому я не думаю, что это шанс. – 2009-11-05 22:05:28

+1

C, интерпретируемая и разделяемая память? Я думаю, вам нужно добавить намного больше деталей к своему оригинальному вопросу! – Will

5

Это всегда трудные проблемы с встроенными системами, и нет простого ответа. Некоторые советы:

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

Удачи вам!

0

Использование средств отладки выделения памяти, таких как ElectricFence, dmalloc и т. Д. - они могут, как минимум, легко пропустить ошибки и наиболее умеренно сложные (перерасходы, недоработки, даже в некоторых случаях писать (или читать) после бесплатного) и т. Д. Мой личный фаворит - dmalloc.

2

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

Несколько идей:

  • делать регулярным code reviews (не быстро в отслеживании определенной ошибки, но ценен для ловли таких проблем в целом)
  • Если ваша архитектура позволяет легко отключить определенные процессы/задачи от запуска, в процессе устранения, возможно, вы можете сузить, какой процесс вызывает ошибку.
  • Если ваша ОС представляет собой совместную многозадачность, например, round robin (это было бы слишком сложно, я думаю, для превентивной многозадачности): добавьте код в конец задачи, которая «владеет» структурой, чтобы сохранить «проверку» структуры. Эта проверка может быть memcpy (если у вас есть время и пространство) или CRC. Затем после выполнения каждой другой задачи добавьте некоторый код для проверки структуры по сравнению с сохраненной проверкой. Это обнаружит любые изменения.
3

Где хранятся данные и как осуществляется доступ к этим двум процессам?

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

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

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

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

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

Чтобы проверить, вызвано ли повреждение другим процессом или обработчиком прерываний, добавьте крючки в каждый переключатель задачи и до и после вызова каждого ISR. Крючок должен проверить, было ли содержимое повреждено. Если они есть, вы сможете определить, какой процесс или ISR несет ответственность.

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

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

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

0

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

Библиотека C, которую вы используете, может включать в себя некоторые процедуры для обнаружения повреждения кучи (например, glibc). Включите их вместе со всеми имеющимися у вас средствами трассировки, чтобы вы могли видеть, что происходит, когда куча была повреждена.

0

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

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

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

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

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

Смежные вопросы