Segfault抛出一行代码

时间:2015-08-03 21:08:38

标签: c segmentation-fault

我正在使用this library for libgps并遇到一些问题,让它正常运行。

调试器出现错误之后的错误是:

Cannot find bounds of current function

在第132行抛出此代码的行为located in this file,

uint8_t checksum= (uint8_t)strtol(strchr(message, '*')+1, NULL, 16);

我根本不知道这个的背景,我不知道为什么它会/不会抛出一个段错误。

我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <gps.h>
#include <math.h>

/*
 * 
 */
int main(int argc, char** argv) {

    // Open
    gps_init();
    gps_on();

    loc_t data;

    gps_location(&data);
    printf("%lf %lf\n", data.latitude, data.longitude);

    return (EXIT_SUCCESS);
}

函数gps_location()会将您带入gps.c,一旦运行,它就会从serial.c开始运行:

void serial_readln(char *buffer, int len)
{
    char c;
    char *b = buffer;
    int rx_length = -1;
    while(1) {
        rx_length = read(uart0_filestream, (void*)(&c), 1);

        if (rx_length <= 0) {
            //wait for messages
            sleep(1);
        } else {
            if (c == '\n') {
                *b++ = '\0';
                break;
            }
            *b++ = c;
        }
    }
}

break上,它返回gps.c进入:

switch (nmea_get_message_type(buffer)) {

nmea.c转换为上面的nmea_get_message_type

然后运行该行:

if ((checksum = nmea_valid_checksum(message)) != _EMPTY)

将其归结为uint8_t checksum= (uint8_t)strtol(strchr(message, '*')+1, NULL, 16);,这是错误所在。

造成这种情况的原因是什么?

编辑:

uint8_t定义为:typedef unsigned char uint8_t;

2 个答案:

答案 0 :(得分:0)

分段错误不是&#34;抛出异常&#34;本身,这是一个硬件发布的问题(&#34;你说去那里,但我没有看到任何名字&#39;那里&#39;&#34;)。

至于你的问题:当strchr()找不到指定的字符时会发生什么?我建议你试一试,然后找出答案。

答案 1 :(得分:0)

您正在使用的代码非常糟糕,并且在任何地方都没有错误检查。因此,任何意外的输入都可能会变得混乱。这也可能是一个潜在的安全漏洞。

要修复此特定实例,请将代码更改为:

if ( !message )
    return NMEA_CHECKSUM_ERR;  // possibly `exit` or something, this shouldn't happen

char *star = strchr(message, '*'); 
if ( !star )
    return NMEA_CHECKSUM_ERR;

uint8_t checksum = strtol(star, NULL, 16);

nmea_parse_gpgganmea_parse_gprmc也有多个类似问题的实例。

如果在调用这些函数之前存在解析器或正则表达式检查以清理输入,则可以接受这些函数。但是,根据您的问题(我没有检查代码库),似乎数据直接从read传递,这是不可原谅的。

segfaulting函数不是为处理空message而设计的,或者实际上是任何与预期形式不匹配的消息。

另一个灾难性的错误是serial_readln函数从不检查它是否超出len