【问题标题】:fprintf() on avr-libc instantly crashesavr-libc 上的 fprintf() 立即崩溃
【发布时间】:2023-03-07 20:35:01
【问题描述】:

我正在编写一个在 ATmega328p 上运行的程序 - 裸 avr-libc 而不是 Arduino,尽管它确实使用 Arduino 引导加载程序而不是串行(我不认为这会影响以下问题)。

我已设置 stdout 以希望显而易见的方式写入 UART:

void uart_putc(char c)
{
  // Turn LFs into CRLFs
  if(c == '\n')
    uart_putc('\r');

  while(!(UCSR0A & _BV(UDRE0)))
    ;

  UDR0 = c;
}

static int _putc(char c, FILE *_)
{
  uart_putc(c);
  return 0;
}

...
  fdev_setup_stream(stdout, &_putc, NULL, _FDEV_SETUP_WRITE);

如果我现在只使用fputcfputs 编写程序,那么一切正常。我什至可以调用snprintf() 将格式化的字符串呈现为char buffer[16],然后将fputs() 输出;这些东西都可以正常工作。

fputs("Hello, world\n", stdout);  /* works fine */

char buffer[16];
snprintf(buffer, sizeof buffer, "Hello, %s\n", "world");
fputs(buffer, stdout);             /* also works fine */

但是,当我尝试执行真正的 fprintf()stdout 时,程序崩溃并重新启动 ATmega:

fprintf(stdout, "Hello, %s\n", "world");

它立即崩溃,甚至在此处输出初始 H 之前。

snprintf()fputs() 都可以正常工作时,任何人都可以提出一些可能会导致fprintf() 停止工作的东西吗?

【问题讨论】:

  • 你可能会看看是否有一个带有调试器的模拟器,你可以在上面运行它。
  • 进入fprintf,并“走”反汇编直到发生崩溃。然后再做一次,就在执行导致崩溃的指令之前,打开一个寄存器视图,复制所有寄存器,并在此处发布它们。此外,发布导致崩溃的指令。这可能会为我们提供一些重要的信息。顺便说一句,您可以对fputs 执行相同的操作,并亲眼看看一个如何工作而另一个不工作。
  • 与任何 printf 函数相关的崩溃让我想到了堆栈溢出。尝试增加堆栈大小。

标签: c microcontroller avr libc


【解决方案1】:

您正在使用fdev_setup_stream() 更新stdout 的分配。 documentation of fdev_setup_stream() 明确指出:

注意: fdev_setup_stream() 不会对标准流进行分配。 如果要使用标准流,则需要由用户分配。

同一文档指向code example for using stdio without malloc。 那里的代码看起来和你的很相似,除了两点:

  1. 使用宏 FDEV_SETUP_STREAM() 定义自定义流:

    static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
    
  2. stdout 被初始化为这个自定义流:

    stdout = &mystdout;
    

我认为,您的代码正在使用未初始化的 stdout 流。 "Introduction to the Standard IO facilities" 声明:

提供了标准流 stdin、stdout 和 stderr,但与 C 标准相反,由于 avr-libc 不了解适用的设备,因此这些流在应用程序启动时尚未预初始化。

未初始化时,所有使用stdout 的函数调用的行为都是未定义的。根据stdout 实际指向的位置,某些调用可能仍然有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-11
    • 2015-03-25
    • 1970-01-01
    相关资源
    最近更新 更多