Перейти к содержанию
    

Почему функция sscanf требует около 50кБ памяти?

Здравствуйте, уважаемые форумчане!

 

Возникла проблема с linking gcc в среде Xilinx SDK (Eclipse).

 

Почему из-за функции sscanf сегмент .text увеличивается в размере на 50 кБайт (а может и больше)? Не потому ли, что вместе с sscanf в .text попадает целиком вся библиотека ввода/вывода.

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

 

Или я что-то в корне не понимаю. Заранее благодарен за любые комментарии.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Или я что-то в корне не понимаю.
Создайте .map (ключ для gcc -Wl.-Map=имя_файла). Рассмотрите его внимательно. В для каждой притянутой из библиотеки функции написано, какая функция ее вызвала. Не знаю про Xilinx, но обычно gcc-реализация (s)scanf тянет за собой менеджер памяти и кучу прочих вещей. Как раз где-то на 50К.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кстати, как-то раз взял из тырнета чей-то sprintf() - получилось около 4К байт кода и никаких malloc(). С тех пор повсеместно использую. Есть ли что-то подобное для sscanf? Поиск в гугле навскидку результата не дал.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кстати, как-то раз взял из тырнета чей-то sprintf() - получилось около 4К байт кода и никаких malloc()

 

да я вообще полагал, что sprintf sscanf должны работать только на стеке. И вроде так и есть в IAR. Или нет ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И вроде так и есть в IAR. Или нет ?
В ИАРе может и так. А в комплекте gcc в качестве стандартной библиотеки идет newlib, которая изначально заточена под большие компы, многопоточность и буферизованный вывод. Только недавно в нех появилась возможность собирать "нано"-версию. Возможно это чем-то поможет автору ветки. Я код newlib внимательно не изучал, видел лишь имена функций, которые подтягивает sscanf и ssprintf. Вроде как printf использует динамическую память при первом вызове для создания структур потокового ввода-вывода и их буферов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Создайте .map (ключ для gcc -Wl.-Map=имя_файла). Рассмотрите его внимательно. В для каждой притянутой из библиотеки функции написано, какая функция ее вызвала. Не знаю про Xilinx, но обычно gcc-реализация (s)scanf тянет за собой менеджер памяти и кучу прочих вещей. Как раз где-то на 50К.

 

Я сгенерировал map-файл, но сильно закапываться в него не стал. Как я понял, в .text попадает целиком не вся библиотека ввода/вывода, а только нужные функции. Верно?

 

Кстати, как-то раз взял из тырнета чей-то sprintf() - получилось около 4К байт кода и никаких malloc(). С тех пор повсеместно использую. Есть ли что-то подобное для sscanf? Поиск в гугле навскидку результата не дал.

 

Для microBlaze специально сделан так называемый xil_printf, который не поддерживает плавающую точку. Он отъедает около 3-х килобайт.

Однако для sscanf такой халявы нет.

 

Мне в общем-то не нужен парсинг строк с вещественными числами с фиксированной точкой, а также с тестовыми подстроками.

Нет ли у кого? Не хотелось бы самому это писать.

 

да я вообще полагал, что sprintf sscanf должны работать только на стеке. И вроде так и есть в IAR. Или нет ?

 

В GNU GCC не на стеке.

 

В ИАРе может и так. А в комплекте gcc в качестве стандартной библиотеки идет newlib, которая изначально заточена под большие компы, многопоточность и буферизованный вывод. Только недавно в нех появилась возможность собирать "нано"-версию. Возможно это чем-то поможет автору ветки. Я код newlib внимательно не изучал, видел лишь имена функций, которые подтягивает sscanf и ssprintf. Вроде как printf использует динамическую память при первом вызове для создания структур потокового ввода-вывода и их буферов.

 

В Xilinx SDK newlib, к сожалению, не поставляется.

 

Всем большое спасибо за ответы.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я сгенерировал map-файл, но сильно закапываться в него не стал.
там самыми первыми строками должно идти что-то вроде

Archive member included because of file (symbol)

/opt/arm-gcc/linaro/20130313/bin/../lib/gcc/arm-none-eabi/4.7.3/armv7-m/libgcc.a(_arm_addsubdf3.o)
                              ./release/obj/floatp10.o (__aeabi_dadd)
/opt/arm-gcc/linaro/20130313/bin/../lib/gcc/arm-none-eabi/4.7.3/armv7-m/libgcc.a(_arm_muldivdf3.o)
                              ./release/obj/floatp10.o (__aeabi_dmul)
/opt/arm-gcc/linaro/20130313/bin/../lib/gcc/arm-none-eabi/4.7.3/armv7-m/libgcc.a(_arm_cmpdf2.o)
                              ./release/obj/floatp10.o (__aeabi_dcmpeq)

Как я понял, в .text попадает целиком не вся библиотека ввода/вывода, а только нужные функции. Верно?
Для библиотеки - да. Из нее тянется только то, что нужно. Кому нужно - см. начало .map.

Из исходников по умолчанию линкуется все. Чтобы этого не происходило, надо компилировать с ключами -ffunction-sections, -fdata-sections и линковать с ключем -Wl,--gc-sections. Тогда компилятор поместит каждую функцию и каждую переменную в свою секцию, а линкер выкинет те секции, на которые нет ссылок. Без этого все функции попадают в один глобальный сегмент .text, а данные - в .data и .bss. С этими ключами - функции попадают в .text.<имя_функции>, данные - аналогично и линкер может легко отделить мух от котлет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

там самыми первыми строками должно идти что-то вроде

 

У меня аналогично:

Archive member included because of file (symbol)

../../standalone_bsp_1/microblaze_1/lib\libxil.a(xil_printf.o)
                              ./src/helloworld.o (xil_printf)
../../standalone_bsp_1/microblaze_1/lib\libxil.a(_exception_handler.o)
                              c:/xilinx/14.7/ise_ds/edk/gnu/microblaze/nt/bin/../lib/gcc/microblaze-xilinx-elf/4.6.4/../../../../microblaze-xilinx-elf/lib/m/mh/le/crt0.o (_exception_handler)
../../standalone_bsp_1/microblaze_1/lib\libxil.a(_program_clean.o)
                              c:/xilinx/14.7/ise_ds/edk/gnu/microblaze/nt/bin/../lib/gcc/microblaze-xilinx-elf/4.6.4/../../../../microblaze-xilinx-elf/lib/m/mh/le/crtinit.o (_program_clean)

 

 

надо компилировать с ключами -ffunction-sections, -fdata-sections и линковать с ключем -Wl,--gc-sections. Тогда компилятор поместит каждую функцию и каждую переменную в свою секцию, а линкер выкинет те секции, на которые нет ссылок. Без этого все функции попадают в один глобальный сегмент .text, а данные - в .data и .bss. С этими ключами - функции попадают в .text.<имя_функции>, данные - аналогично и линкер может легко отделить мух от котлет.

 

Похоже, этих премудростей мой GCC не знает...

make all 
'Building file: ../src/helloworld.c'
'Invoking: MicroBlaze gcc compiler'
mb-gcc -Wall -O0 -g3 -c -fmessage-length=0 -Wno-implicit-function-declaration  -fno-builtin-strlen -fno-builtin-memcpy -ffunction-sections, -fdata-sections -I../../standalone_bsp_1/microblaze_1/include -mlittle-endian -mxl-pattern-compare -mno-xl-soft-div -mcpu=v8.50.c -mno-xl-soft-mul -mxl-multiply-high -mhard-float -mxl-float-convert -mxl-float-sqrt -Wl,--no-relax -ffunction-sections -fdata-sections -MMD -MP -MF"src/helloworld.d" -MT"src/helloworld.d" -o "src/helloworld.o" "../src/helloworld.c"
cc1.exe: error: unrecognized command line option '-ffunction-sections,'
make: *** [src/helloworld.o] Ошибка 1

 

-------------

SORRY.

 

Не работало из-за лишней запятой в командной строке. С этими опциями все собирается, правда эффекта никакого. Видимо, из программы нечего выкидывать.

Спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С этими опциями все собирается, правда эффекта никакого. Видимо, из программы нечего выкидывать.

А вы не забыли об опциях линкера -Wl,--gc-sections ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А вы не забыли об опциях линкера -Wl,--gc-sections ?

 

Точно не забыл. Программа маленькая, еще не успел лишнего понаписать :) . А вот sscanf 50% памяти сожрал.

 

Кроме этого на http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gc...ze-Options.html

написано: Only use these options when there are significant benefits from doing so. When you specify these options, the assembler and linker will create larger object and executable files and will also be slower.

Поэтому решил эти опции не указывать.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я и раньше натыкался на Nuttx. Там в комплекте идёт своя стандартная библиотека. Вроде бы sscanf выглядит вменяемо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Создайте .map (ключ для gcc -Wl.-Map=имя_файла).
Подскажите, пожалуйста, новичку, куда это вписывать? Я попробовал сюда:

 

post-13271-1418894933_thumb.png

 

Не помогло, после сборки не нашёл такого файла.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я не использую этот плугин, поэтому конкретное место не подскажу. Но видите на вашей картинке чуть ниже обведенного есть поле All options. Вот вам надо добиться, чтобы оно появилось в этом поле. Поищите в подразделах General, Mascellaneous или в других. Возможно вы найдете галочку вроде "генерить .map-файл" и она добавит эту опцию сама.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Там галочки можно поставить только в General:

 

post-13271-1418899702_thumb.png

 

В остальных разделах нет галочек, только вводить можно текстовые поля.

 

Короче я в консоли смотрю результат запуска линкера, вот так печатает:

'Invoking: MicroBlaze gcc linker'
mb-gcc -Wl.-Map=../src/test_paul.map -L../../fft_sp605_bsp/microblaze_0/lib -Wl,-T -Wl,../src/lscript.ld -L../../fft_sp605_bsp/microblaze_0/lib -mlittle-endian -mxl-barrel-shift -mxl-pattern-compare -mcpu=v8.50.c -mno-xl-soft-mul -Wl,--no-relax -Wl,--gc-sections -o "fft_sp605.elf"  ./src/main.o ./src/platform.o   -Wl,--start-group,-lxil,-lgcc,-lc,--end-group

 

Т.е. в принципе эта опция туда пролазит по синтаксису нормально, и он на синтаксис вызова не ругается. Другое дело, что и файла не создаёт )))

Либо ещё как вариант: может он файл создаёт, а потом стирает как ненужный мусор?

Путь к файлу пробовал указывать вообще без пути, пробвал по аналогии с остальными путями ставить не ../src, а ./src - результат тот же...

 

Добавление:

Решилась проблема, надо было запятую поставить, а не точку )))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...