这段代码中的索引如何达到2154? (gcc,嵌入式C,ARM Cortex M0)

时间:2014-04-15 11:34:40

标签: c gcc arm

我正在为ARM Cortex M0上运行的GSM调制解调器编写驱动程序。系统上唯一的UART用于与调制解调器通信,因此我最好能够记录与调制解调器的UART对话,即在内存中构建一个字符串并使用GDB进行观察。

以下是我的UART日志记录功能。

// Max number of characters user in the UART log, when in use.
#define GSM_MAX_UART_LOG_CHARS (2048)

static char m_gsm_uart_log[GSM_MAX_UART_LOG_CHARS] = "";
static uint16_t m_gsm_uart_log_index = 0;

// Write a character to the in-memory log of all UART messages.
static void gsm_uart_log_char(const char value)
{
    m_gsm_uart_log_index++;

    if (m_gsm_uart_log_index > GSM_MAX_UART_LOG_CHARS)
    {
        // Clear and restart log.
        memset(&m_gsm_uart_log, 0, GSM_MAX_UART_LOG_CHARS); // <-- Breakpoint here
        m_gsm_uart_log_index = 0;
    }

    m_gsm_uart_log[m_gsm_uart_log_index] = value;
}

// Write a string to the in-memory log of all UART messages.
static void gsm_uart_log_string(const char *value)
{
    uint16_t i = 0;
    char ch = value[i++];

    while (ch != '\0')
    {
        gsm_uart_log_char(ch);
        ch = value[i++];
    }
}

如果我在上面显示的行上设置断点,第一次到达时,m_gsm_uart_log_index已经超过2048.我已经看到2154和2048到2200之间的一堆其他值左右

这怎么可能?没有其他代码可以在任何地方触及m_gsm_uart_log_index。

2 个答案:

答案 0 :(得分:3)

发生了缓冲区溢出,可能会在m_gsm_uart_log_index上进行操作。

检查缓冲区的结尾应该是:

if (m_gsm_uart_log_index >= GSM_MAX_UART_LOG_CHARS) {
...
}

目前,m_gsm_uart_log_index可以达到2048,所以写m_gsm_uart_log_index[2048]可能会在m_gsm_uart_log_index存储的位置。

答案 1 :(得分:0)

您在m_gsm_uart_log_index == GSM_MAX_UART_LOG_CHARS时写入缓冲区,这意味着您将缓冲区超过1个字符。这会写入m_gsm_uart_log_index的第一个字节并破坏它。

变化:

if (m_gsm_uart_log_index > GSM_MAX_UART_LOG_CHARS)

为:

if (m_gsm_uart_log_index >= GSM_MAX_UART_LOG_CHARS)