#gcc #embedded
#gcc #встроенный
Вопрос:
Я работаю над некоторым старым исходным кодом для встроенной системы с целью m68k, и иногда я вижу массивные запросы на выделение памяти при вызове gcvtf
для форматирования числа с плавающей запятой для отображения. Вероятно, я могу обойти это, написав свою собственную процедуру замены, но природа ошибки вызывает у меня большое любопытство, потому что она возникает только тогда, когда куча начинается с определенного адреса или выше, и она исчезает, если я взломаю .скрипт компоновщика ld или удалите любой набор глобальных переменных (которые помещаются перед кучей в моей карте памяти), которые составляют достаточный размер байта, чтобы куча начиналась ниже таинственного критического адреса.
Итак, я подумал, что посмотрю в исходном коде gcc версию компилятора, которую я использую (m68k-elf-gcc 3.3.2). Я загрузил то, что кажется исходным кодом для этой версии по адресу http://gcc.petsads.us/releases/gcc-3.3.2 /, но я нигде не могу найти определение для gcvt или gcvtf. Когда я ищу его, grep находит только некоторую документацию и ссылки .h, но не определение:
$ find | xargs grep gcvt
./gcc/doc/gcc.info: C library functions `ecvt', `fcvt' and `gcvt'. Given va
lid
./gcc/doc/trouble.texi:library functions @code{ecvt}, @code{fcvt} and @code{gcvt
}. Given valid
./gcc/sys-protos.h:extern char * gcvt(double, int, char *);
Итак, где эта функция фактически определена в исходном коде? Или я загрузил совершенно неправильную вещь?
Я не хочу менять этот проект, чтобы использовать самый последний gcc, из-за соображений стабильности проекта и тестирования, и, как я уже сказал, я могу обойти это, написав свою собственную процедуру форматирования, но такое поведение меня очень смущает, и оно будет терзать мой мозг, если я не найдувыясните, почему это так странно.
Ответ №1:
Уоллик прав, что это определено в библиотеке C, а не в компиляторе. Однако библиотека GNU C (почти всегда) используется только с компиляторами и дистрибутивами Linux. Ваш компилятор, будучи компилятором с «голым металлом», почти наверняка использует вместо этого библиотеку C Newlib.
Основной веб-сайт для Newlib находится здесь: http://sourceware.org/newlib /, и эта конкретная функция определена в newlib/libc/stdlib/efgcvt.c
файле. Исходные коды были довольно стабильными в течение длительного времени, поэтому (если это не результат ошибки) довольно велики шансы, что текущие исходные коды не слишком отличаются от того, что использует ваш компилятор.
Как и в случае с исходным кодом GNU C, я не вижу там ничего, что, очевидно, вызвало бы эту странность, которую вы видите, но в конечном итоге все это куча оболочек вокруг базовых sprintf
подпрограмм.
Комментарии:
1. Спасибо! Я нашел исходный код для версии newlib, которую я использовал (1.11.0), и что gcvt фактически вызывает функцию _dtoa_r , которая вызывает некоторые функции распределения. Я почти уверен, что странное поведение есть.
Ответ №2:
Он находится в библиотеке GNU C как glibc/misc/efgcvt.c
. Чтобы избавить вас от некоторых проблем, код для функции:
char *
__APPEND (FUNC_PREFIX, gcvt) (value, ndigit, buf)
FLOAT_TYPE value;
int ndigit;
char *buf;
{
sprintf (buf, "%.*" FLOAT_FMT_FLAG "g", MIN (ndigit, NDIGIT_MAX), value);
return buf;
}
Инструкции по получению glibc приведены здесь.
Комментарии:
1. Спасибо! Естественно, это не содержит ничего, что могло бы объяснить странность распределения кучи. Ну что ж, я пока отложу свое любопытство на задний план и изучу его подробнее после завершения проекта.
2. Как я отметил в своем ответе, GNU C был бы правильным ответом для компилятора Linux, но, похоже, это простой компилятор (согласно «-elf-» в цели) и, следовательно, будет использовать Newlib.