简体   繁体   English

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

[英]How can the index in this code snippet ever reach 2154? (gcc, embedded C, ARM Cortex M0)

I'm writing a driver for a GSM modem running on an ARM Cortex M0. 我正在为在ARM Cortex M0上运行的GSM调制解调器编写驱动程序。 The only UART on the system is in use for talking to the modem, so the best I can do for logging the UART conversation with the modem is to build up a string in memory and watch it with GDB. 系统上唯一的UART用于与调制解调器进行通信,因此,为了记录与调制解调器的UART对话,我能做的最好的事情是在内存中建立一个字符串,并使用GDB对其进行监视。

Here are my UART logging functions. 这是我的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++];
    }
}

If I set a breakpoint on the line shown above, the first time it's reached, m_gsm_uart_log_index is already well over 2048. I've seen 2154 and a bunch of other values between 2048 and 2200 or so. 如果我在上面显示的行上设置一个断点,那么第一次达到该断点时,m_gsm_uart_log_index已经超过2048。我已经看到2154以及2048至2200左右的其他值。

How is this possible? 这怎么可能? There's no other code that touches m_gsm_uart_log_index anywhere. 没有其他代码可以触及m_gsm_uart_log_index的任何地方。

You have a buffer overflow happening which could trample on m_gsm_uart_log_index . 您正在发生缓冲区溢出,这可能会践踏m_gsm_uart_log_index

The check for end of buffers should be: 缓冲区结束的检查应为:

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

As it stands, m_gsm_uart_log_index can reach 2048, and so writing m_gsm_uart_log_index[2048] is likely to be at the location where m_gsm_uart_log_index is stored. 就目前而言, m_gsm_uart_log_index可以达到2048,因此写m_gsm_uart_log_index[2048]可能位于m_gsm_uart_log_index的存储位置。

You are writing to the buffer when m_gsm_uart_log_index == GSM_MAX_UART_LOG_CHARS , which means that you are overrunning the buffer by 1 character. m_gsm_uart_log_index == GSM_MAX_UART_LOG_CHARS ,您正在写入缓冲区,这意味着您将缓冲区m_gsm_uart_log_index == GSM_MAX_UART_LOG_CHARS了1个字符。 This writes into the first byte of m_gsm_uart_log_index and corrupts it. 这将写入m_gsm_uart_log_index的第一个字节并破坏它。

Change: 更改:

if (m_gsm_uart_log_index > GSM_MAX_UART_LOG_CHARS)

to: 至:

if (m_gsm_uart_log_index >= GSM_MAX_UART_LOG_CHARS)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM