标签: newlib

如何获得调用堆栈回溯?(深入嵌入,没有库支持)

我希望我的异常处理程序和调试函数能够打印调用堆栈回溯,基本上就像glibc中的backtrace()库函数一样.不幸的是,我的C库(Newlib)没有提供这样的调用.

我有这样的事情:

#include <unwind.h> // GCC's internal unwinder, part of libgcc
_Unwind_Reason_Code trace_fcn(_Unwind_Context *ctx, void *d)
{
    int *depth = (int*)d;
    printf("\t#%d: program counter at %08x\n", *depth, _Unwind_GetIP(ctx));
    (*depth)++;
    return _URC_NO_REASON;
}

void print_backtrace_here()
{
    int depth = 0;
    _Unwind_Backtrace(&trace_fcn, &depth);
}
Run Code Online (Sandbox Code Playgroud)

这基本上有效,但结果痕迹并不总是完整的.例如,如果我这样做

int func3() { print_backtrace_here(); return 0; }
int func2() { return func3(); }
int func1() { return func2(); }
int main()  { return func1(); }
Run Code Online (Sandbox Code Playgroud)

backtrace只显示func3()和main().(这是一个玩具示例,但我已经检查了反汇编并确认这些功能全部都在这里,并没有优化或内联.)

更新:我在旧的ARM7系统上尝试了这个回溯代码但是使用相同(或至少,尽可能等同)的编译器选项和链接描述文件,它打印出正确的完整回溯(即func1和func2不会丢失)和实际上它甚至会将过去的主要内容转移到启动初始化代码中.所以可能问题不在于链接器脚本或编译器选项.(另外,通过反汇编确认在此ARM7测试中也没有使用帧指针).

代码使用-fomit-frame-pointer编译,但我的平台(裸机ARM Cortex M3)定义了一个不使用帧指针的ABI.(该系统的先前版本在ARM7上使用旧的APCS ABI,具有强制堆栈帧和帧指针,以及类似于此处的回溯,它完美地工作).

整个系统使用-fexception进行编译,这确保了_Unwind使用的必要元数据包含在ELF文件中.(_Unwind是为我认为的异常处理而设计的).

所以,我的问题是: 在使用GCC的嵌入式系统中,是否存在"标准",可接受的可靠回溯方式? …

c c++ gcc arm newlib

20
推荐指数
3
解决办法
1万
查看次数

在ARM Cortex-M3中使用newlib的malloc

我正在为ARM Cortex-M3(NXP的LCP17xx)创建代码.到目前为止我一直在使用静态内存,一切运行良好.我试图添加动态内存支持,但是一旦我调用malloc,系统就会卡住.

我正在用gcc编译arm裸机,并使用newlib.版本:gcc-arm-none-eabi-4_6-2012q1

为了添加malloc支持,我实现了一个简单的_sbrk函数并修改了我的链接器脚本以为堆创建一些空间(我已经阅读了很多关于这个部分的不同教程,但没有一个涵盖我接下来遇到的问题).

在一些LED的帮助下,我可以确定代码运行到它调用的那一点malloc,然后它就不会继续.它甚至没有达到我的_sbrk功能.此外,sizeof如果我malloc稍后在代码中包含一个调用,它将陷入调用状态.

那么,当调用malloc代码时,如果没有达到_sbrk或返回代码,我会做错什么呢?

在对malloc包含调用时生成的内存映射进行了很长一段时间后,当它不是时,我怀疑它与使用的结构有关malloc.

这是定义ram内存的ld脚本的一部分:

.bss :
{
    _start_bss = .;
    *(.bss)
    *(COMMON)
    _ebss = .;
    . = ALIGN (8);
    _end = .;
} >sram
. = ALIGN(4);
_end_bss = .;
. = ALIGN(256);
_start_heap = .;
PROVIDE( __cs3_heap_start = _start_heap)

_end_stack = 0x10008000;
Run Code Online (Sandbox Code Playgroud)

然后在中断向量表中设置_end_stack.

现在比较不同的地图.不在代码中使用malloc:

 *(COMMON)
            0x1000000c                _ebss = .
            0x10000010                . = ALIGN (0x8)
 *fill*     0x1000000c        0x4 00
            0x10000010 …
Run Code Online (Sandbox Code Playgroud)

arm cortex-m3 newlib

16
推荐指数
1
解决办法
1万
查看次数

未定义的引用"只有一些math.h"函数

我有一个奇怪的问题.

数学库已添加到我的makefile中.

# include standard C library
LDFLAGS += -lc
# include standard math library
LDFLAGS += -lm
Run Code Online (Sandbox Code Playgroud)

在输出文件(.map)中,我可以看到所有内容都已正确链接:

LOAD c:/gnu/powerpc-eabi/3pp.ronetix.powerpc-eabi/bin/../lib/gcc/powerpc-eabi/4.3.3/nof\libgcc.a
LOAD c:/gnu/powerpc-eabi/3pp.ronetix.powerpc-eabi/bin/../lib/gcc/powerpc-eabi/4.3.3/../../../../powerpc-eabi/lib/nof\libc.a
LOAD c:/gnu/powerpc-eabi/3pp.ronetix.powerpc-eabi/bin/../lib/gcc/powerpc-eabi/4.3.3/../../../../powerpc-eabi/lib/nof\libm.a
Run Code Online (Sandbox Code Playgroud)

当我做

z = pow((double) 2, (double) 3);
Run Code Online (Sandbox Code Playgroud)

它工作正常.但是,如果我测试另一个函数,如:

double result = asin(x);
Run Code Online (Sandbox Code Playgroud)

我去拿:

undefined reference to `asin'
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

怎么会这样?在math.h中都有powasin,见下文:

/* Non reentrant ANSI C functions.  */

#ifndef _REENT_ONLY
#ifndef __math_6881
extern double acos _PARAMS((double));
extern double asin _PARAMS((double));
extern double atan2 _PARAMS((double, double));
extern …
Run Code Online (Sandbox Code Playgroud)

c embedded math gcc newlib

11
推荐指数
3
解决办法
3万
查看次数

理解__libc_init_array

我从http://newlib.sourcearchive.com/documentation/1.18.0/init_8c-source.html查看了__libc_init_array的源代码.
但我不太明白这个功能是做什么的.

我知道这些符号

/* These magic symbols are provided by the linker.  */
extern void (*__preinit_array_start []) (void) __attribute__((weak));
extern void (*__preinit_array_end []) (void) __attribute__((weak));
extern void (*__init_array_start []) (void) __attribute__((weak));
extern void (*__init_array_end []) (void) __attribute__((weak));
extern void (*__fini_array_start []) (void) __attribute__((weak));
extern void (*__fini_array_end []) (void) __attribute__((weak));
Run Code Online (Sandbox Code Playgroud)

在链接描述文件中定义.
链接器脚本的一部分可能如下所示:

  .preinit_array     :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } >FLASH
  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN …
Run Code Online (Sandbox Code Playgroud)

gcc startup elf linker-scripts newlib

11
推荐指数
3
解决办法
2万
查看次数

了解ARM Cortex-M微控制器的linkerscript

我正在使用STMicroelectronics的STM32F746NG微控制器.该器件基于ARM Cortex-M7架构.我花了很多时间来理解示例项目中的linkerscript.我想出了基础知识,但我仍然无法掌握它的大部分内容.请帮我理解这些部分.

启动linkerscript

linkerscript开头如下:

/* Entry Point */
ENTRY(Reset_Handler) /* The function named 'Reset_Handler' is defined */
                     /* in the 'startup.s' assembly file.             */

/* Highest address of the user mode stack */
/* Remember: the stack points downwards */
_estack = 0x20050000;    /* End of RAM */

/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200;  /* Required amount of heap  */
_Min_Stack_Size = 0x400; /* Required amount of stack */ …
Run Code Online (Sandbox Code Playgroud)

linker arm linker-scripts newlib cortex-m

11
推荐指数
1
解决办法
4427
查看次数

交叉编译 - 错误:所选处理器在 ARM 模式下不支持 `fmrx r3,fpexc' - Beaglebone

我正在尝试交叉编译一个文件以闪入 Beaglebone Black。一切正常,但如果我尝试启用 FPU

#define set_en_bit_in_fpexc() do { \
    int dummy; \
    __asm__ __volatile__ ("fmrx %0,fpexc\n\t" \
                         "orr  %0,%0,#0x40000000\n\t" \
                         "fmxr fpexc,%0" : "=r" (dummy) : :); \
} while (0)
Run Code Online (Sandbox Code Playgroud)

我收到以下错误

Error: selected processor does not support `fmrx r3,fpexc' in ARM mode
Error: selected processor does not support `fmxr fpexc,r3' in ARM mode
Run Code Online (Sandbox Code Playgroud)

我也尝试过thumb mode,但我遇到了同样的错误。当然,如果我删除初始化 FPU 的代码部分,它就可以正常工作。

为什么我会收到这些错误?

生成文件

[...]
CROSSPATH?=/usr/bin
CROSSPFX=$(CROSSPATH)/arm-none-eabi-
CC=$(CROSSPFX)gcc
AS=$(CROSSPFX)as
LD=$(CROSSPFX)ld
NM=$(CROSSPFX)nm
OBJCOPY=$(CROSSPFX)objcopy
OBJDUMP=$(CROSSPFX)objdump
CFLAGS=-Wall -Wextra -O2 -ffreestanding
ARCHFLAGS=-mcpu=cortex-a8 -march=armv7-a -mfpu=neon
CCARCHFLAGS=$(ARCHFLAGS) -marm …
Run Code Online (Sandbox Code Playgroud)

gcc arm cross-compiling newlib beagleboneblack

8
推荐指数
1
解决办法
7276
查看次数

为我的操作系统移植NewLib:一些问题

我正在尝试为我的操作系统移植NewLib(我正在关注本教程:http://wiki.osdev.org/Porting_Newlib ),我有一些问题.

谢谢你的回答!

c gcc ld newlib

7
推荐指数
1
解决办法
1032
查看次数

gcc使用newlib而不是glibc?

我想使用newlib而不是glibc来编译小的静态二进制文件.(我不打算交叉编译,因为二进制文件将由同一台计算机使用.)我相信我需要为此编译一个单独的gcc?

我编译了gcc:

./configure --prefix=/home/myuser/Desktop/gcc-4.4.5 --libexecdir=/home/myuser/Desktop/gcc-4.4.5 --libdir=/home/myuser/Desktop/gcc-4.4.5 --with-gxx-include-dir=/home/myuser/Desktop/gcc-4.4.5 --enable-languages=c --enable-libmudflap --disable-multilib --disable-libssp --disable-nls --with-newlib --with-gnu-as --with-gnu-ld --with-system-zlib
make

它编译没有错误,但现在我尝试编译一个简单的Hello World!程序它想要使用来自/ usr的头文件而不是我上面指定的路径.这些是一些错误:

In file included from /home/myprogram/Desktop/myprogram.c:1:
/usr/include/stdio.h:34:21: error: stddef.h: No such file or directory
In file included from /usr/include/stdio.h:75,
                 from /home/myprogram/Desktop/myprogram.c:1:
/usr/include/libio.h:53:21: error: stdarg.h: No such file or directory
In file included from /usr/include/stdio.h:75,
                 from /home/myprogram/Desktop/myprogram.c:1:
/usr/include/libio.h:332: error: expected specifier-qualifier-list before 'size_t'
/usr/include/libio.h:364: error: expected declaration specifiers or '...' before 'size_t'
/usr/include/libio.h:373: error: expected declaration specifiers or '...' before 'size_t'

我究竟做错了什么 …

gcc newlib

7
推荐指数
2
解决办法
7964
查看次数

fwrite是否刷新'\n'上的缓冲区?

我有自己的执行_open(),_close(),_write(),_read().

我的代码:

FILE *f = fopen("0:test", "wb");  // calls _open()
fwrite("hello ", 6, 1, f);
fwrite("world\r\n\0", 8, 1, f); // calls _write(3, "hello world\r\n", 13)
fflush(f);                      // calls _write(3, "\0", 1)
fclose(f);                      // calls _close(3)
Run Code Online (Sandbox Code Playgroud)

BUFSIZE 是1024

编译器:arm-none-eabi-gcc/版本:5.4.1

即使我有旗帜,为什么要fwrite()解释?'\n'"wb"

是否fopen()解释文件名"0:test"

c stdio stm32 newlib

7
推荐指数
1
解决办法
301
查看次数

如何重建 GNU Arm Embedded Toolchain 的 newlib 和 newlib-nano

我从https://developer.arm.com/open-source/gnu-toolchain/gnu下载了工具链“ gcc-arm-none-eabi-6-2017-q2-update-win32-sha1.exe ”(Windows)-rm/downloads并将其安装在我的 Windows 10 PC 上。

安装文件夹在“ ../share/doc/gcc-arm-none-eabi/ ”中包含一个 release.txt ,它告诉:

此版本包括以下项目:

  • newlib 和 newlib-nano : git://sourceware.org/git/newlib-cygwin.git commit 0d79b021a4ec4e6b9aa1a9f6db0e29a137005ce7

../share/doc/gcc-arm-none-eabi/ ”中的 readme.txt 还包含:

  • C 库使用 *

该工具链与两个基于 newlib 的预构建 C 库一起发布:一个是标准的 newlib (libc.a),另一个是代码大小的 newlib-nano (libc_nano.a)。

现在我想完全重建“ ../arm-none-eabi/lib/thumb ”中包含的所有 libc.a 和 libc_nano.a

目前我可以使用“ gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 ”在Ubuntu上构建

$ # Downloaded newlib-cygwin (with corresponding hash) into folder newlib-cygwin
$ mkdir build
$ cd build
$ ../newlib-cygwin/configure --target=arm-none-eabi --disable-newlib-supplied-syscalls
$ make
Run Code Online (Sandbox Code Playgroud)

我必须如何配置 newlib 以构建 gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 中包含的 libc.a 和 libc_nano.a …

c c++ arm newlib toolchain

7
推荐指数
1
解决办法
6011
查看次数