Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"
Ценой оставления отладочного кода в исполняемом файле изделия является увеличение размера программы. В зависимости от размещения отладочного кода он может быть также более медленным, поскольку каждый раз осуществляются проверки, которые все время оказываются ложными, пока не будет включен режим отладки. И, как упоминалось, кто-нибудь может изучить вашу программу, что может быть неприемлемым для вас. Или еще хуже, недоброжелательный пользователь может включить столько отладочных возможностей, что программа замедлится до невозможности работать с ней! (Это называется атакой отказа в обслуживании (denial of service attack).)
Преимуществом, которое может быть большим, является то, что вашу уже установленную программу можно запустить с включенным режимом отладки без необходимости сначала построить, а затем загрузить специальную версию на сайт заказчика. Когда программное обеспечение установлено в удаленных местах, в которых может не быть людей и все, что вы можете сделать, это получить удаленный доступ к системе через Интернет (или, еще хуже, через медленное модемное соединение!), такая возможность может оказаться спасительным средством.
Наконец, можно использовать смешанную методику: условно компилируемый отладочный код для детальной, точной отладки, а постоянно присутствующий код для более грубого вывода.
15.4.2.2. Используйте специальные переменные окружения
Другой полезной уловкой является проверка вашим приложением специальных переменных окружения (документированных или иных). Это может быть особенно полезным для тестирования. Вот другой пример из нашего опыта с
gawkgawkoptimal_bufsize()st_blksizestruct statoptimal_bufsize()BUFSIZ<stdio.h>posix/gawkmisc.c1 /* optimal_bufsize --- определяет оптимальный размер буфера */23 int4 optimal_bufsize(fd, stb) /* int optimal_bufsize(int fd, struct stat *stb); */5 int fd;6 struct stat *stb;7 {8 /* инициализировать все члены нулями на случай, если ОС не использует их все. */9 memset(stb, ' ', sizeof(struct stat));1011 /*12 * System V.n, n < 4, не имеет в структуре stat размера13 * системного блока файла. Поэтому нам нужно сделать разумную14 * догадку. Мы используем BUFSIZ, поскольку именно это имелось15 * в виду на первом месте.16 */17 #ifdef HAVE_ST_BLKSIZE18 #define DEFBLKSIZE (stb->st_blksize ? stb->st_blksize : BUFSIZ)19 #else20 #define DEFBLKSIZE BUFSIZ21 #endif2223 if (isatty(fd))24 return BUFSIZ;25 if (fstat(fd, stb) == -1)26 fatal("can't stat fd %d (%s)", fd, strerror(errno));27 if (lseek(fd, (off_t)0, 0) == -1) /* не обычный файл */28 return DEFBLKSIZE;29 if (stb->st_size > 0 && stb->st_size < DEFBLKSIZE) /* маленький файл */30 return stb->st_size;31 return DEFBLKSIZE;32 }Константа
DEFBLKSIZEstruct statBUFSIZlseek()BUFSIZDEFBLKSIZEBUFSIZУ нас была проблема, когда один из наших контрольных примеров отлично работал на нашей рабочей системе GNU/Linux и на любой другой системе Unix, к которой у нас был доступ. Однако, этот тест последовательно терпел неудачу на других определенных системах.
В течение длительного времени мы не могли получить непосредственный доступ к терпящей неудачу системе, чтобы запустить GDB. В конце концов, мы смогли, однако, ухитриться воспроизвести проблему. Она оказалась связана с размером буфера, который
gawkНам был нужен способ воспроизведения проблемы на своей машине разработки, система с неудачей находилась в стороне за девять часовых поясов, а интерактивный запуск GDB через Атлантический океан мучителен. Мы воспроизвели проблему, заставив
optimal_bufsize()AWKBUFSIZE"exact"optimal_bufsize()AWKBUFSIZEgawk$ <b>AWKBUFSIZE=42 make check</b>Это запускает тестовый набор
gawkoptimal_bufsize()