涉及openldap库中ldap_url_parse函数的混乱分段错误

时间:2015-06-18 20:04:22

标签: c linux macos segmentation-fault openldap

在CentOS 6.6服务器上,以下代码编译(使用gcc版本4.4.7或使用clang版本3.4.2)而不会发生意外但在运行时会导致分段错误:

#include <ldap.h>

int main( int argc, char **argv )
{
    LDAPURLDesc **ludpp;
    int parse_status = ldap_url_parse("ldap://ldap.example.com", ludpp);
    char * str;
}

但是,如果我修改它以删除字符串声明,如下所示:

#include <ldap.h>

int main( int argc, char **argv )
{
    LDAPURLDesc **ludpp;
    int parse_status = ldap_url_parse("ldap://ldap.example.com", ludpp);
}

然后它也没有发生任何事故。在我的Mac OS X 10.10.3(Yosemite)上,两个版本(带或不带字符串声明)编译并运行。

我的三个问题是:

  1. 为什么CentOS服务器上的第一个例子是segfault?
  2. 为什么第二个例子不会在CentOS服务器上发生段错误?
  3. 具体来说,我的Mac笔记本电脑和Linux服务器之间的差异导致了两者之间的这种差异?

1 个答案:

答案 0 :(得分:1)

您打算使用这样的功能:

#include <ldap.h>

int main( int argc, char **argv )
{
    LDAPURLDesc *ludp;
    int parse_status = ldap_url_parse("ldap://ldap.example.com", &ludp);
}

这允许函数设置随后在变量ludp中看到的值(指向动态分配的解析结果的指针)。请注意,在这种情况下,第二个函数参数是一个有效的指针。

但是,在原始代码中,传递未初始化指针的值。这绝对是无用的,因为函数可能对该值执行的任何操作都没有定义的行为。可能导致的一种更可能的行为是分段错误,但这种结果无法保证(c.f。&#34; undefined&#34;)。

此外,您的代码负责在不再需要时释放以这种方式提供的对象,它应该通过ldap_free_urldesc()来完成。这在测试程序中并不重要,因为它无论如何都会立即退出,但是如果在真正的程序中你只是继续存在内存泄漏 - 特别是如果你丢失ldap_url_parse()提供的指针,通过覆盖它或让它超出范围。