Как я могу проверить список STL в отладчике CodeWarrior? - PullRequest
1 голос
/ 29 апреля 2009

Есть ли простой способ просмотра данных в STL std::list<T> в отладчике Metrowerks CodeWarrior? Я могу просматривать данные в начале или в конце списка, просматривая выражения, такие как

instances->__list_imp.__list_deleter.end_.compressed_pair_imp.second_.prev_->data_

Я могу развернуть маленькие знаки «+» рядом с членами структуры, чтобы просмотреть список элементов за раз, но это утомительно, и после примерно 20-30 элементов дерево становится слишком широким для окна отладчика. Список, который я изучаю, содержит более 2000 элементов.

Отладчик CodeWarrior не поддерживает вызов функций в выражениях, поэтому я не могу проверить значение (++(++instances.begin())) или что-то подобное. Я могу только смотреть на членов структуры, которые имеют очень длинные и неудобные имена.

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

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

Ответы [ 3 ]

1 голос
/ 29 апреля 2009

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

С помощью std :: list у вас обычно есть реализация, которая выглядит примерно так в памяти (обратитесь к за подробностями при необходимости):

struct List
{
  Node * next;
  Node * prev;
  size_t size;
}

template 
struct Node
{
  Node * next;  // last node will point to list rather than another node
  Node * prev;  // first node will point to list rather than another node
  T payload; // e.g. in a std::list this would be a Foo * payload
}

Обратите внимание, что next и prev могут быть в обратном порядке в вашей реализации.

& myList в большинстве случаев эквивалентен "end ()".

Если вы используете вид памяти, вы можете осматриваться рядом с & myList. Это позволит вам найти значение указателя myList.prev или myList.next, а затем изменить представление памяти, чтобы посмотреть на это. Затем вы попали на последний или первый узел в вашем списке соответственно.

Как только вы доберетесь до узла, вы можете посмотреть на prev, next или payload, а затем перейти к prev или next; вспенить, промыть, повторить. Если вы снова окажетесь в & myList, вы узнаете, что прошли через все это.

Больно и скучно? Возможно. Но вы хорошо знакомы с вашей реализацией stl, в некоторых случаях вы легко «видите» возможные помехи, и это полезный навык, когда все другие возможности вылетают из окна.

(Ведите записи о том, где вы были, запутаться очень легко.)

0 голосов
/ 02 мая 2009

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

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

********************((Metrowerks::node_base**********************)instances->__list_imp.__list_deleter.end_.compressed_pair_imp.second_)

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

0 голосов
/ 01 мая 2009

Отладчики могут быть гораздо более дружественными к STL. Я не знаком с CodeWarrior конкретно, но разве вы вообще не можете вызывать какие-либо функции из окна отладки? Или это больше похоже на другие отладчики, которые я использовал, когда вы (1) не можете вызывать функции, если программа уже завершена (ABORT, segfault, ...), и (2) не могут вызывать функции, которые включают в себя расширения шаблонов (что может потребовать добавления кода к изображению), но (3) может вызывать статически связанные функции, если код остановлен на точке останова?

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

...