关闭优化后,C库崩溃

时间:2015-02-26 20:39:57

标签: c xcode clang libwebsockets

我正在使用XCode 6在Mac OS X上用C语言编写库。该库基本上是由X-Plane加载的插件,并通过Web套接字服务器提供数据。

反过来,库使用libwebsockets库,我使用开发人员存储库文档here中的指南编译了该库。简而言之,我检查了libwebsockets存储库,创建了一个构建目录并运行

cmake ..
make

我的插件100%正常工作,X-Plane无需投诉即可加载... 打开优化后

当我在XCode中禁用我的库优化时,无[-O0] ,crap命中风扇,当libwebsockets函数 libwebsocket_create_context()时,库崩溃强>被称为。

如何在关闭优化时引入错误/崩溃?通常情况下反之亦然,通过优化 可能会出现问题?

这里是关于失败点的图书馆代码的摘录:

PLUGIN_API int XPluginStart(char *outName, char *outSig, char *outDesc) {
    strcpy(outName, "XP Web Socket");
    strcpy(outSig, "sparkbuzz.plugins.xpwebsocket");
    strcpy(outDesc, "Web socket plugin for streaming data to the browser.");

    struct lws_context_creation_info info;
    info.port = port;
    info.iface = NULL;
    info.protocols = protocols;
    info.extensions = libwebsocket_get_internal_extensions();
    info.ssl_cert_filepath = NULL;
    info.ssl_private_key_filepath = NULL;
    info.gid = -1;
    info.uid = -1;
    info.options = opts;

    context = libwebsocket_create_context(&info); // FAILS HERE WITH EXC_BAD_ACCESS

    if (context == NULL) {
        // libwebsockets initialization has failed!
        return -1;
    }

    // Find XPlane datarefs
    gIAS = XPLMFindDataRef("sim/cockpit2/gauges/indicators/airspeed_kts_pilot");

    // Register flight loop callback
    XPLMRegisterFlightLoopCallback(MyFlightLoopCallback, 1.0, NULL);

    return 1;
}

1 个答案:

答案 0 :(得分:0)

您似乎没有初始化struct lws_context_creation_info中的所有字段,从而导致未定义的行为。根据编译器选项和其他不太可预测的情况,您的程序实际上似乎可以正常运行......纯粹的机会!

您可以通过使用memset

清除结构来轻松解决此问题
struct lws_context_creation_info info;
memset(&info, 0, sizeof info);
info.port = port;
info.iface = NULL;
info.protocols = protocols;
info.extensions = libwebsocket_get_internal_extensions();
info.ssl_cert_filepath = NULL;
info.ssl_private_key_filepath = NULL;
info.gid = -1;
info.uid = -1;
info.options = opts;

在C99中执行此操作的另一种方法是以这种方式初始化结构:

struct lws_context_creation_info info = {
    .port = port,
    .iface = NULL,
    .protocols = protocols,
    .extensions = libwebsocket_get_internal_extensions(),
    .ssl_cert_filepath = NULL,
    .ssl_private_key_filepath = NULL,
    .gid = -1,
    .uid = -1,
    .options = opts };

根据类型,任何其他字段都会初始化为00.0NULL,因此您可以省略ifacessl_cert_filepathssl_private_key_filepath的初始值设定项。 strcpy(outName, "XP Web Socket"); strcpy(outSig, "sparkbuzz.plugins.xpwebsocket"); strcpy(outDesc, "Web socket plugin for streaming data to the browser.");

重要的是始终使用通用方法来初始化具有自动存储的结构,以防止在稍后使用新字段扩展结构时或在忘记某些初始化器的位置时很难发现错误。

另请注意,此功能的3个顶行也存在风险:

{{1}}

输出字符数组的大小未知。可能会发生缓冲区溢出。将缓冲区大小作为参数传递或将它们指定为常量并检查内容是否合适。