Atmel Studio: Как точно срабатывают точки останова данных?
ОК, ребята. Я установил точку останова данных в студии Atmel (с помощью отладчика ICEmk2-JTag), и она не будет получена, хотя значение по адресу будет изменено. (Я проверил это со следующими точками останова) Почему это?
Вся цель точек останова данных состоит в том, чтобы обнаружить изменение значения по адресу, или я что-то неправильно понимаю?
Чтобы быть более конкретным: у меня есть указатель A, который указывает на значение. Но указатель A изменяется (а не на значение, на которое он указывает!) Из-за ошибки, которую я пытаюсь найти. Итак, я создал указатель B, который указывает на адрес, где хранится указатель A, и установил точку останова данных на указателе B. Вот инициализация:
#define lastCMDRingBufferSIZE 255
volatile uint8_t lastCMDRingbuffer[lastCMDRingBufferSIZE]; //
volatile uint8_t*lastCMDRingstartPtr = lastCMDRingbuffer; // This is PtrA
volatile uint32_t*ptrToPtr = &lastCMDRingstartPtr; // PtrB
Или другой способ выразить это; Точка данных запускается, если:
- содержимое адреса написано переполнением массива?
- содержимое адреса интерпретируется как часть большей структуры данных, которая каким-то образом написана мошенническим указателем? (expl: 64-битный указатель разыменовывается и записывается, в результате 32-битное целое число перезаписывается)
Ваши подозрения и советы высоко ценятся:)
2 ответа
Используемое мной оборудование для отладки, поддерживающее прерывание доступа к данным, не реализовано так, как я думаю, большинство людей ожидают от них. Аппаратное обеспечение не контролирует память по адресу и выдает точку останова, если она изменяется, оно контролирует шину чтения / записи ЦП и прерывает работу, если происходит доступ по данному адресу (или диапазону адресов) и правильной ширины.,
Конечным результатом является то, что некоторые действия могут быть недоступны для оборудования. DMA, обращающийся к памяти, является большим, который вы просто не можете поймать (если ваш интерфейс SRAM/DRAM не имеет возможности выдавать такую ошибку). Кроме того, если вы обращаетесь к адресу в режиме, для которого аппаратное обеспечение отладки не настроено (например, выполняется запись байтов при поиске записи слов - что может быть возможно, если у вас очень наивный memset / memcpy, который делает доступ к байту)
Я предполагаю, что вы делаете некоторые байтовые обращения к массиву, объявленному перед указателем, и растоптываете указатель, переполняя массив. Даже если вы указали аппаратную точку останова доступа к словам на указателе, она не перехватывается, потому что вы выполняете байтовый доступ.
Вы не обращаетесь (каламбур не предназначен) это правильно. Если указатель A
поврежден, необходимо установить точку останова данных &A
непосредственно; создание вторичного указателя не принесет ничего полезного, если вы не можете установить условную точку останова A != B
,
Точка данных запускается, если:
- содержимое адреса написано переполнением массива? содержимое адреса интерпретируется как часть большей структуры данных, которая
- как-то написано мошенническим указателем? (expl: 64-битный указатель разыменовывается и записывается, в результате 32-битное целое число перезаписывается)
Он запускается, когда значение по адресу точки останова изменяется - просто так; аппаратное обеспечение отладки не имеет понятия языковых конструкций; адрес, который вы должны смотреть, поэтому &A
не A
или же B
,
В контексте вашего фактического кода, если lastCMDRingstartPtr
модифицируется, ptrToPtr
также не изменится. Просто введите &lastCMDRingstartPtr
как адрес; тогда вы получите перерыв, когда значение lastCMDRingstartPtr
изменения.