【问题标题】:Crash when calling C++ function from C从 C 调用 C++ 函数时崩溃
【发布时间】:2018-02-28 18:22:51
【问题描述】:

我有一个从 C 函数调用的 C++ 库函数。该调用传入 C++ 代码访问的 C 数据结构。访问 C 数据结构时,我的程序在 C++ 代码中崩溃。我已按照 C++ faq 中与混合 C-to-C++ 相关的所有说明进行操作。

崩溃发生在 centos7 机器上。在调试模式下运行相同的代码不会导致崩溃。在 Ubuntu (16.04) 上运行的相同代码不会导致崩溃。这是崩溃的 GDB 分析。

(gdb) frame 5
#5  0x00007fc28e79226e in ngx_http_setup_handler (r=0x2469040)
    at /opt/platform/nginx-noname-module.c:201
201       return ModProcessGetApi(r);
(gdb) p r->unparsed_uri
$1 = {len = 15, data = 0x24572c4 "/__xx/stats/all HTTP/1.1\r\nUser-Agent"}
(gdb) down
#4  0x00007fc28e7945b4 in ModProcessGetApi (r=r@entry=0x2469040)
    at /opt/platform/nginx-body-handler.cc:274
274   ss_rval_t rv = ProcessGetRequest(r, data, &dsize);
(gdb) p r->unparsed_uri
$2 = {len = 38105792, data = 0xf <Address 0xf out of bounds>}
(gdb)

一旦执行进入 C++ 代码,C 数据结构就会显示地址越界。这是 c-to-c++ 函数的胶水代码。

#if __cplusplus
extern "C" {
#endif

#include <nginx.h>
#include <ngx_core.h>
#include <ngx_log.h>
#include <ngx_http.h>

ngx_int_t ModPostRequestBodyHandler(ngx_http_request_t *r);
ngx_int_t ModProcessGetApi(ngx_http_request_t* r);

#if __cplusplus
}
#endif

如果有人能对此有所了解,我将不胜感激。混合 C 和 C++ 代码时是否需要使用任何编译器选项,以便 C++ 代码可以正确访问 C 数据结构?这是操作系统和编译器信息:

Centos 版本:崩溃发生

操作系统:Centos 7,C++:g++ 4.8.5

Ubuntu 版本:不会发生崩溃。

操作系统:Ubuntu 16.04,C++:g++ 5.4.0

不确定这是否重要,但我在两个操作系统上的 docker 容器中运行我的应用程序。

【问题讨论】:

  • GCC 5.1 引入了一个新的ABI。也许值得看看这个gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
  • @Iharob 感谢您抽出宝贵时间。如果我有选择,我会像你建议的那样用 C++ 完成这一切。不幸的是,有时我们的手被束缚了,我们必须让事情在某些环境中发挥作用。这就是我遇到这类问题的地方。
  • @Galik,感谢您对此进行调查。根据您的 GCC 5.1 建议,centos7 默认 GCC 版本是 4.8.5。我想迁移到 5.x,但我必须使用平台上可用的 std 库:(
  • 如果从 C 中调用 C++ 函数,如果它们被实现为 extern "C" 并且不抛出异常,那么它们会非常好。您的问题与 C 与 C++ 无关。你只是在某个地方有一个普通的旧代码错误。
  • 谢谢@Nikos。我也这么想'extern“C”'的东西。但是,如果您查看 GDB 会话输出,一旦我进入 c++ 函数,情况就会发生变化。顺便说一句,这是在单线程环境中。对于我试图弄清楚的其他事情,您仍然可能是正确的。

标签: c++ c ubuntu centos7 g++4.8


【解决方案1】:

事实证明,我的 c++ 和 C 库是使用不同的#defines 编译的,因此,两个库中的 C 数据结构不同。这会导致 c++ 端的访问不对齐。这个问题也可能发生在两个 c 库中。

感谢所有回复的人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-29
    • 2016-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多