Чтение онлайн

на главную

Жанры

Linux программирование в примерах
Шрифт:

 hd = 0x0, av = 0x0, r_ent =0), x = {extra = 0x0, xl = 0,

 param_list = 0x0}, name = 0x0, number = 1, reflags = 0},

 val = { fltnum = 6.6614606209589101e-316, sp = 0x0,

 slen = 0, sref = 1, idx = 0),

 hash = {next = 0x8095598, name = 0x0, length = 0,

 value = 0x0, ref = 1}}, type = Node_K_print, flags = 1}

Это куча вязкой массы. Однако, GDB все же несколько упрощает ее обработку. Вы можете использовать выражения вроде '

($1).sub.val.slen
', чтобы пройти через дерево и перечислить структуры данных.

Есть другие причины

для избегания объединений. Прежде всего, объединения не проверяются. Ничто, кроме внимания программиста, не гарантирует, что когда вы получаете доступ к одной части объединения, вы получаете доступ к той части, которая была сохранена последней. Мы видели это в
ch15-union.c
, в котором доступ к обоим «элементам» объединения осуществлялся одновременно.

Вторая причина, связанная с первой, заключается в осторожности с перекрытиями вложенных комбинаций

struct
/
union
. Например, в предыдущей версии
gawk
[173] был такой код.

173

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

/* n->lnode перекрывает размер массива, не вызывайте unref, если это массив */

if (n->type != Node_var_array && n->type != Node_array_ref)

unref(n->lnode);

Первоначально

if
не было, был только вызов
unref
, которая освобождает
NODE
, на которую указывает
n->lnode
. Однако, в этот момент
gawk
могла создать аварийную ситуацию. Можете себе представить, сколько времени потребовало отслеживание в отладчике того факта, что то, что рассматривалось как указатель, на самом деле было размером массива!

В качестве отступления, объединения значительно менее полезны в С++. Наследование и объектно-ориентированные возможности создают при управлении структурами данных совсем другую ситуацию, которая значительно безопаснее.

Рекомендация: по возможности избегайте объединений (

union
). Если это невозможно, тщательно проектируйте и программируйте их!

15.4.2. Отлаживаемый код времени исполнения

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

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

15.4.2.1. Добавляйте отладочные опции и переменные

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

стороны, не документирование ее кажется довольно подлым. Если вы пишете для Open Source или Free Software, лучше документировать опцию.)

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

struct option options[] = {

 ...

 { "debug", required_argument, NULL, 'D' },

 ...

};

int main(int argc, char **argv) {

 int c;

 while ((c = getopt_long(argc, argv, "...D:")) != -1) {

switch (c) {

...

case 'D':

parse_debug(optarg);

break;

...

}

 }

 ...

}

Функция

parse_debug
считывает строку аргументов. Например, это может быть строка разделенных запятыми или пробелами подсистем, вроде "
file,memory,ipc
". Для каждого действительного имени подсистемы функция устанавливает бит в отладочной переменной:

extern int debugging;

void parse_debug(const char *subsystems) {

 char *sp;

 for (sp = subsystems; *sp != '\0';) {

if (strncmp(sp, "file", 4) == 0) {

debugging |= DEBUG_FILE;

sp += 4;

} else if (strncmp(sp, "memory", 6) == 0) {

debugging |= DEBUG_MEM;

sp += 6;

} else if (strncmp(sp, "ipc", 3) == 0) {

debugging |= DEBUG_IPC;

sp += 3;

...

}

while (*sp == ' ' || *sp == ',') sp++;

 }

}

В конечном счете код приложения может затем проверить флаги:

if ((debugging & DEBUG_FILE) != 0) ...

 /* В части программы для ввода/вывода */

if ((debugging & DEBUG_MEM) != 0) ... /* В менеджере памяти */

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

enum
), зависит от вас.

Ценой оставления отладочного кода в исполняемом файле изделия является увеличение размера программы. В зависимости от размещения отладочного кода он может быть также более медленным, поскольку каждый раз осуществляются проверки, которые все время оказываются ложными, пока не будет включен режим отладки. И, как упоминалось, кто-нибудь может изучить вашу программу, что может быть неприемлемым для вас. Или еще хуже, недоброжелательный пользователь может включить столько отладочных возможностей, что программа замедлится до невозможности работать с ней! (Это называется атакой отказа в обслуживании (denial of service attack).)

Поделиться:
Популярные книги

Последняя Арена 7

Греков Сергей
7. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 7

Пенсия для морского дьявола 4

Чиркунов Игорь
4. Первый в касте бездны
Фантастика:
попаданцы
5.40
рейтинг книги
Пенсия для морского дьявола 4

#Бояръ-Аниме. Газлайтер. Том 11

Володин Григорий Григорьевич
11. История Телепата
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
#Бояръ-Аниме. Газлайтер. Том 11

Сумеречный Стрелок 2

Карелин Сергей Витальевич
2. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный Стрелок 2

Совершенный: пробуждение

Vector
1. Совершенный
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Совершенный: пробуждение

Новая мама в семье драконов

Смертная Елена
2. В доме драконов
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Новая мама в семье драконов

Возвышение Меркурия. Книга 5

Кронос Александр
5. Меркурий
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 5

Бастард Императора. Том 4

Орлов Андрей Юрьевич
4. Бастард Императора
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Бастард Императора. Том 4

Господин следователь. Книга 2

Шалашов Евгений Васильевич
2. Господин следователь
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Господин следователь. Книга 2

Провинциал. Книга 4

Лопарев Игорь Викторович
4. Провинциал
Фантастика:
космическая фантастика
рпг
аниме
5.00
рейтинг книги
Провинциал. Книга 4

Сбой Системы Мимик! Академия

Северный Лис
2. Сбой Системы!
Фантастика:
боевая фантастика
юмористическая фантастика
5.71
рейтинг книги
Сбой Системы Мимик! Академия

Кодекс Охотника. Книга ХХ

Винокуров Юрий
20. Кодекс Охотника
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга ХХ

Хозяйка дома в «Гиблых Пределах»

Нова Юлия
Любовные романы:
любовно-фантастические романы
5.75
рейтинг книги
Хозяйка дома в «Гиблых Пределах»

Вторая жизнь майора. Цикл

Сухинин Владимир Александрович
Вторая жизнь майора
Фантастика:
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Вторая жизнь майора. Цикл