Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: undefined reference to `_exit'
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > GNU/OpenSource средства разработки
ajkpro
Это уже былоhttp://electronix.ru/forum/index.php?showtopic=99348, но там я не "дошел".
Это мой первый опыт, поэтому задаю еще раз.
Вот есть проект https://github.com/h0rr0rrdrag0n/stm32vldis...-linux-template
Вот, автор с описанием этого проекта: http://h0rr0rr-drag0n.blogspot.ru/2011/08/...inux-linux.html

Вот, такая ошибка:
Цитата
rmv7-m/libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x16): undefined reference to `_exit'
collect2: error: ld returned 1 exit status
make: *** [ldall] Ошибка 1


Это я уже понял, что некий деструктор не подхватывается. Но почему у автора и некоторых последователей прошло. Там рекомендуют sys.c, но его нет по ссылке. И другой компилятор сам устраняет проблему.
Как все-таки победить?

Спасибо! Александр.
AHTOXA
Цитата(ajkpro @ Feb 10 2013, 23:19) *
Это я уже понял, что некий деструктор не подхватывается. Но почему у автора и некоторых последователей прошло.

Потому что автор и последователи убрали деструкторы.
Цитата(ajkpro @ Feb 10 2013, 23:19) *
Там рекомендуют sys.c, но его нет по ссылке.

Вот вам новая ссылка.
ajkpro
Цитата(AHTOXA @ Feb 10 2013, 22:48) *
Потому что автор и последователи убрали деструкторы.

А там некий траслятор это дело игнорирует - тут

Тем не менее...
Цитата(AHTOXA @ Feb 10 2013, 22:48) *

как его прикрутить? Пока фантазии не хватает...

Вот, то что подчеркнуто это я добавил:

cc: $(SRC)
$(CC) $(CFLAGS) $(SRC) ./sys.c
Естественно, ничего не вышло:
Цитата
/home/ajk/stm32/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3/../../../../arm-none-eabi/lib/armv7-m/libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x16): undefined reference to `_exit'
collect2: error: ld returned 1 exit status
make: *** [ldall] Ошибка 1


Но, с другой стороны в его коде и нет деструкторов: _exit

Ну, и весь make:
CODE
BIN=stm32vldiscovery-linux-template

TOOLS_PATH=/home/ajk/stm32/gcc-arm-none-eabi-4_7-2012q4
TOOLS_PREFIX=arm-none-eabi-
TOOLS_VERSION=4.7.3

CFLAGS=-c -mcpu=cortex-m3 -mthumb -Wall -O0 -mapcs-frame -D__thumb2__=1
CFLAGS+=-msoft-float -gdwarf-2 -mno-sched-prolog -fno-hosted -mtune=cortex-m3
CFLAGS+=-march=armv7-m -mfix-cortex-m3-ldrd -ffunction-sections -fdata-sections
CFLAGS+=-I./cmsis -I./stm32_lib -I.
ASFLAGS=-mcpu=cortex-m3 -I./cmsis -I./stm32_lib -gdwarf-2 -gdwarf-2
LDFLAGS=-static -mcpu=cortex-m3 -mthumb -mthumb-interwork -Wl,--start-group
LDFLAGS+=-L$(TOOLS_PATH)/lib/gcc/arm-none-eabi/$(TOOLS_VERSION)/thumb2
LDFLAGS+=-L$(TOOLS_PATH)/arm-none-eabi/lib/thumb2 -lc -lg -lstdc++ -lsupc++ -lgcc -lm
#LDFLAGS+=--section-start=.text=0x8000000
LDFLAGS+=-Wl,--end-group -Xlinker -Map -Xlinker $(BIN).map -Xlinker
LDFLAGS+=-T ./stm32_lib/device_support/gcc/stm32f100rb_flash.ld -o $(BIN).elf

CC=$(TOOLS_PATH)/bin/$(TOOLS_PREFIX)gcc-$(TOOLS_VERSION)
AS=$(TOOLS_PATH)/bin/$(TOOLS_PREFIX)as
SIZE=$(TOOLS_PATH)/bin/$(TOOLS_PREFIX)size

CMSISSRC=./cmsis/core_cm3.c
STM32_LIBSRC=./stm32_lib/system_stm32f10x.c ./stm32_lib/stm32f10x_it.c
STM32_LIBSRC+=./stm32_lib/stm32f10x_rcc.c ./stm32_lib/stm32f10x_gpio.c
SRC=main.c

OBJ=core_cm3.o system_stm32f10x.o stm32f10x_it.o startup_stm32f10x_md_vl.o
OBJ+=stm32f10x_rcc.o stm32f10x_gpio.o
OBJ+=main.o

all: ccmsis cstm32_lib cc ldall
$(SIZE) -B $(BIN).elf

ccmsis: $(CMSISSRC)
$(CC) $(CFLAGS) $(CMSISSRC)

cstm32_lib: $(STM32_LIBSRC)
$(CC) $(CFLAGS) $(STM32_LIBSRC)
$(AS) $(ASFLAGS) ./stm32_lib/device_support/gcc/startup_stm32f10x_md_vl.S -o startup_stm32f10x_md_vl.o

cc: $(SRC)
$(CC) $(CFLAGS) $(SRC) ./sys.c

ldall:
$(CC) $(OBJ) $(LDFLAGS)

.PHONY: clean load

clean:
rm -f $(OBJ) \
$(BIN).map \
$(BIN).elf
make clean -C ./stlink/build/

load: $(BIN).elf
./flashing_stm32vldiscovery.sh $(BIN).elf
AHTOXA
Цитата(ajkpro @ Feb 11 2013, 23:36) *
А там некий траслятор это дело игнорирует - тут

"Там" деструкторов сразу не было. Просто более старые версии компилятора подтягивали исключения не только при наличии деструкторов, но и просто при наличии чисто виртуальных функций. sys.c от этого помогал.
Но, может быть, у вас вообще другая проблема? Судя по makefile, у вас проект не на c++, а на c, а там нет деструкторов.
Может быть, вы просто добавили в main.c вызов функции printf()?
Или ещё проще - у вас нет в конце main() бесконечного цикла, и программа завершает работу? (как раз при этом вызывается функция exit() )
ajkpro
Цитата(AHTOXA @ Feb 12 2013, 00:05) *
Но, может быть, у вас вообще другая проблема? Судя по makefile, у вас проект не на c++, а на c, а там нет деструкторов.

По какому слову в makefile это видно?

Цитата(AHTOXA @ Feb 12 2013, 00:05) *
Может быть, вы просто добавили в main.c вызов функции printf()?
Или ещё проще - у вас нет в конце main() бесконечного цикла, и программа завершает работу? (как раз при этом вызывается функция exit() )

Я ещё ничего не добавлял, но в двух файлах есть функция printf()
~/stm32/stm32vldiscovery-linux-template/stlink/src/
stlink-hw.c
gdb-server.c

И цикл там есть.
Код
  while (1) {}


А может быть, что в другом новом компиляторе нужны другие ключи для компиляции?

Спасибо! Александр.
AHTOXA
Цитата(ajkpro @ Feb 12 2013, 09:25) *
По какому слову в makefile это видно?

Ну, там просто нет ни одного *.cpp файла. И компилятор вызывается gcc, а не g++.
Цитата(ajkpro @ Feb 12 2013, 09:25) *
Я ещё ничего не добавлял, но в двух файлах есть функция printf()
~/stm32/stm32vldiscovery-linux-template/stlink/src/
stlink-hw.c
gdb-server.c

Не, эти файлы не имеют отношения к вашей программе. Это исходники утилиты stlink, которая применяется для заливки прошивок и отладки.
Цитата(ajkpro @ Feb 12 2013, 09:25) *
И цикл там есть.
Код
  while (1) {}

Цикл должен быть в функции main() в файле main.c. Проверьте это.

alx2
Цитата(AHTOXA @ Feb 12 2013, 01:05) *
Может быть, вы просто добавили в main.c вызов функции printf()?
Или ещё проще - у вас нет в конце main() бесконечного цикла, и программа завершает работу? (как раз при этом вызывается функция exit() )

Цитата(ajkpro @ Feb 12 2013, 08:25) *
А может быть, что в другом новом компиляторе нужны другие ключи для компиляции?

Может быть лучше не гадать, а просто посмотреть в map-файл и узнать, кто вызвал exit()?..
ajkpro
Вот, main.c:
Код
#include "stm32f10x.h"

void RCC_init() {
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
}

int main(void) {
  GPIO_InitTypeDef GPIOC_init_params;

  RCC_init();

  GPIOC_init_params.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
  GPIOC_init_params.GPIO_Speed = GPIO_Speed_10MHz;
  GPIOC_init_params.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC, &GPIOC_init_params);

  GPIO_SetBits(GPIOC, GPIO_Pin_8);
  GPIO_SetBits(GPIOC, GPIO_Pin_9);

  while (1) {}
}

Т.е. цикл есть.

Цитата(alx2 @ Feb 12 2013, 09:54) *
Может быть лучше не гадать, а просто посмотреть в map-файл и узнать, кто вызвал exit()?..

Увы, я в нем ничего не понял... Но чистого exit() там нет.
ajkpro
Вот, map файл: http://yadi.sk/d/po6sankd2_2yQ

xemul
Код
void main(void) {
...
  while (1) {}
}

?
ajkpro
Цитата(xemul @ Feb 13 2013, 13:15) *
Код
void main(void) {
...
  while (1) {}
}

?

Ну, цикл-то есть. И им заканчивается программа. Там просто пример. Зажигаются по очереди по таймеру две лампочки.
xemul
Цитата(ajkpro @ Feb 13 2013, 20:39) *
Ну, цикл-то есть. И им заканчивается программа. Там просто пример. Зажигаются по очереди по таймеру две лампочки.

Может таки в .map заглянете? Там чёрным по-английски резервируется место под int, возвращаемый main(), и подтягивается функция, его возвращающая. Угадаете с трёх раз её имя?
ajkpro
Цитата(xemul @ Feb 13 2013, 21:54) *
Может таки в .map заглянете? Там чёрным по-английски резервируется место под int, возвращаемый main(), и подтягивается функция, его возвращающая. Угадаете с трёх раз её имя?


Да, я то не против. Только я первый раз смотрю. Нифига ни вижу.
А, допустим, увижу. Что дальше?
У автора так работает. Почему на этом компиляторе так не катит? И как sys. срабатывает?

Александр.
alx2
Цитата(ajkpro @ Feb 12 2013, 22:43) *
Увы, я в нем ничего не понял... Но чистого exit() там нет.

То есть линкер говорит: "In function `exit':", а в map-файле об этом самом exit ничего не пишет???
А это тогда что:
Код
/home/ajk/stm32/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3/../../../../arm-none-eabi/lib/armv7-m/libc.a(lib_a-exit.o)
                              /home/ajk/stm32/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3/../../../../arm-none-eabi/lib/armv7-m/crt0.o (exit)
?

Эта запись означает, что линкер загрузил lib_a-exit.o из libc.a для того чтобы удовлетворить ссылку на символ exit, имеющуюся в crt0.o.

Цитата(ajkpro @ Feb 13 2013, 23:42) *
А, допустим, увижу. Что дальше?

А дальше Вы будете разбираться, почему в Вашем crt0.o есть ссылка на exit, которой, как Вы считаете, там быть не должно...
AHTOXA
Цитата(ajkpro @ Feb 13 2013, 09:49) *
Вот, map файл: http://yadi.sk/d/po6sankd2_2yQ

Короче, дело в следующем.
1. sys.c - забудьте про него, это совсем из другой оперы.
2. В вашем проекте почему-то вместо файла stm32_lib/device_support/gcc/startup_stm32f10x_md_vl.S используется файл начальной инициализации, предоставляемый компилятором по умолчанию. И он зачем-то вызывает _exit(). Это может быть действительно глюк компилятора.
3. Если вас это устраивает, просто добавьте в файл main.c функцию
Код
void _exit(int i)
{
    while (1);
}

А вообще, тот шаблон, который вы себе выбрали для старта - не очень удачный. Видите, сколько возни для того, чтобы просто скомпилировать его. Лучше возьмите другой шаблон, где всё сразу сделано нормально. Например, вот отсюда.
ajkpro
Йесс! Поехало, спасибо! В выходные буду разбираться, сейчас на работе облом. Там у меня немного другое.

А может быть найдется ссылка на проект с stm32f4diskovery? Все-равно мне потом туда переползать.

А мар я распечатал, 13 листов. Обчитаешься!

Спасибо!
Александр.
AHTOXA
А какой вариант у вас "поехал"?
ajkpro
Цитата(AHTOXA @ Feb 14 2013, 21:45) *
А какой вариант у вас "поехал"?

Добавил:
Код
void _exit(int i)
{
    while (1);
}

Но теперь не понятно, почему ругается на _exit, добавил функцию _exit (естественно), но в map`е находим (exit),т.е. без подчерркивания?
Это что-то обозначает? Есть где-нибудь русские комментарии к map?
Александр.
p.s. По английски в следующем сезоне sm.gif
Цитата(alx2 @ Feb 14 2013, 09:44) *
А дальше Вы будете разбираться, почему в Вашем crt0.o есть ссылка на exit, которой, как Вы считаете, там быть не должно...

А нет у меня crt0, ни в проекте, ни в компилляторе. Точнее, нет такого файла. А в проекте даже это слово содержится только в map`е.
Но в компиляторе crt0 встречается в 120 файлах...
Или какие-то опции компиляции не корректно, или чего-то не понимаю.
Александр
_Pasha
Цитата(ajkpro @ Feb 15 2013, 06:47) *
А нет у меня crt0, ни в проекте, ни в компилляторе. Точнее, нет такого файла. А в проекте даже это слово содержится только в map`е.

Опция линкера
Код
-Wl,-nostartfiles

имеется?
AHTOXA
Цитата(_Pasha @ Feb 15 2013, 10:02) *
Опция линкера
Код
-Wl,-nostartfiles

имеется?

Вроде бы -Wl, - не нужно, просто -nostartfiles.
ajkpro
Цитата(AHTOXA @ Feb 15 2013, 08:25) *
Вроде бы -Wl, - не нужно, просто -nostartfiles.

-Wl, - имеется, а -nostartfiles добавил и избавился от void _exit(int i) .
И, заодно, минус 4+kb. map тоже укоротился, раза в полтора.
alx2
Цитата(ajkpro @ Feb 15 2013, 08:47) *
Но теперь не понятно, почему ругается на _exit,
Кто на него ругается и как именно?
Если Вы имеете в виду сообщение об ошибке, процитированное в первом посте темы, то оно возникает из-за того что в функции exit() есть ссылка на символ _exit (проще говоря, exit() вызывает _exit()), которого линкер не смог найти. Подробности ищите в документации на используемую Вами библиотеку - там наверняка сказано, что если программист использует exit(), то он должен предоставить функцию _exit().

Цитата(ajkpro @ Feb 15 2013, 08:47) *
добавил функцию _exit (естественно), но в map`е находим (exit),т.е. без подчерркивания?
Это что-то обозначает? Есть где-нибудь русские комментарии к map?
Это означает, что в Вашей программе используется функция exit(). Вызывается она, как я Вам уже говорил, в crt0.o. Какие еще комментарии Вы хотите услышать? Задайте конкретные вопросы, я постараюсь (в меру своего понимания) ответить...

Цитата(ajkpro @ Feb 15 2013, 08:47) *
А нет у меня crt0, ни в проекте, ни в компилляторе. Точнее, нет такого файла.
Как это нет? Покажите вывод команды ls -l /home/ajk/stm32/gcc-arm-none-eabi-4_7-2012q4/arm-none-eabi/lib/armv7-m/crt0.o

Цитата(ajkpro @ Feb 15 2013, 08:47) *
Но в компиляторе crt0 встречается в 120 файлах...
Или какие-то опции компиляции не корректно, или чего-то не понимаю.

Вы чего-то не понимаете. Судя по названию, это Ваш стартап-модуль. Иными словами, это модуль, содержащий код, выполняющийся при старте контроллера (после RESET), и, как правило, содержащий инициализацию среды (инициализацию указателя(ей) стека, секции .data, очистку .bss, выполнение конструкторов глобальных объектов и т.п.), и после этого вызывает main(). А после вызова main() у Вас там, видимо, и вызывается exit(). Если Вы знаете, что main() никогда не вернет управление, просто уберите весь код после вызова main(), так как он все равно не будет выполняться.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.