【问题标题】:Segmentation Fault (Core Dumped): Error while returning from function分段错误(核心转储):从函数返回时出错
【发布时间】:2013-01-12 17:10:57
【问题描述】:

我有两个功能。

struct logger_message vget_log_msg(enum LogStatus log_status, const char* format, va_list args) {    
    struct logger_message log_msg;
    log_msg.status = log_status;
    log_msg.timestamp = get_current_timestamp();

    memset(log_msg.message_buffer, 0, MESSAGE_SIZE);
    if(format){    
        vsprintf(log_msg.message_buffer, format, args);
    }
    return log_msg;
}

int send_log_message_to_mqueue(mqd_t mqd, enum LogStatus log_status, const char* format, ...) {
    struct logger_message msg;
    va_list argp;
    va_start(argp, format); 
    msg = vget_log_msg(log_status, format, argp);
    va_end(argp);
    int res; 
    res = send_message_to_mqueue(mqd, (char *)&msg, sizeof(msg));
    return res;
}

所以,我从在线 vget_log_msg 返回时收到错误“Segmentation Fault(Core dumped)”:

msg = vget_log_msg(log_status, format, argp);

编辑:也许这些信息会有用

struct logger_message{
    enum LogStatus status;
    time_t timestamp;
    char message_buffer[MESSAGE_SIZE];    
};

有人知道我为什么会收到这个错误吗?如何纠正?

【问题讨论】:

  • 编译时使用-Wall吗?您收到任何警告吗?
  • 是的,当然。编译项目时我没有收到任何警告或错误。
  • 您的vsprintf() 是否有可能离开您的消息缓冲区的末尾?如果是这样,您是否考虑过使用vsnprintf() 代替?既然你有缓冲区大小,为什么不使用它。希望您的工具链和运行时符合 C99 或更高版本,因为我相信这是我们第一次使用它的时候。

标签: c segmentation-fault return


【解决方案1】:

什么是 MESSAGE_SIZE?那有多大?您可以通过减小它的大小来检查,还是使用指针而不是整个结构返回。

【讨论】:

  • 没错。不幸的是,MESSAGE_SIZE 等于 24,这太小了。谢谢。
【解决方案2】:

我的猜测是你使用了vget_log_msg,而没有在包含send_log_message_to_mqueue的文件中实际声明它的原型。例如,不包括定义vget_log_msg 的头文件,或者,如果两者在同一个文件中,则不在send_log_message_to_mqueue 之前定义vget_log_msg

在这种情况下,编译器会假定vget_log_msg 返回一个int,并且不对返回结构的函数使用正确的调用约定。这样的结构由调用者返回,它在堆栈的一侧为返回的结构分配一个缓冲区,并将指向该缓冲区的指针作为隐式参数传递给被调用函数;那么,使用错误的调用约定会导致该隐式指针丢失并因此出错,然后返回函数将返回的结构写入无效位置。

或者,它们可以使用不同版本的struct logger_message,例如,包括声明不同的不同头文件。

【讨论】:

  • 我正在尝试考虑任何现代编译器(在过去十年左右),它 not 标记来自未声明函数的此类赋值(因此假设 @987654329 @return value) 当返回除了一个值之外的任何东西时都会出错,该值至少可以尝试将 强制 int 到正在使用的左值。例如:在不声明函数的情况下,OP 的代码将导致编译错误,指出“错误:struct logger_messageint 是不兼容的类型。”虽然您的观点对于来自int(尤其是指针)的强制类型非常有效,但我不确定它在这里是否有效。
  • 确实如此。我添加了另一种解释。
  • 没有。如果您尝试将 'int' 分配给结构,任何体面的编译器都会给您带来错误。
  • 原型在头文件中声明,并包含头文件。所以建议不起作用。
猜你喜欢
  • 1970-01-01
  • 2013-08-14
  • 1970-01-01
  • 1970-01-01
  • 2014-02-10
  • 1970-01-01
  • 1970-01-01
  • 2020-12-08
  • 1970-01-01
相关资源
最近更新 更多