2016-11-19 87 views
0

我有这个简单的程序:OpenSSL的段错误

int main() 
{ 
     /* INITIALIZING OPENSSL */ 
     SSL_library_init();   
     SSL_load_error_strings(); 
     ERR_load_BIO_strings(); 
     OpenSSL_add_all_algorithms(); 

     BIO *bio; 
     connectServerSSL(bio); 
     login(bio); 
} 

而这个功能:

void connectServerSSL (BIO *bio) 
{ 
    SSL_CTX * ctx = SSL_CTX_new(SSLv23_client_method()); 
    SSL * ssl; 

    if(! SSL_CTX_load_verify_locations(ctx, NULL, "/etc/ssl/certs")) 
    { 
     callError(ERR_LOADCERT); 
    } 

    bio = BIO_new_ssl_connect(ctx); 
    BIO_get_ssl(bio, &ssl); 
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); 

    BIO_set_conn_hostname(bio, hostnamePort); 
    if(BIO_do_connect(bio) <= 0) 
    { 
     callError(ERR_CONNECTION); 
    } 

    if(SSL_get_verify_result(ssl) != X509_V_OK) 
    { 
     callError(ERR_VALIDCERT); 
    } 
} 

当我使用这个:

BIO_WRITE(生物,request.c_str() request.size())

In f联系connectServerSSL它工作正常。

但是,当我想在一些其他的功能,使用它:

void login (BIO *bio) 
{ 
    BIO_write(bio, request.c_str(), request.size()); 
} 

我得到分割故障(核心转储)。

+2

你不返回从'connectServerSSL'你'bio'。 – tkausl

+0

我该怎么做? –

回答

0

在C和C++中,偶数指针是按值传递的。所以,你需要connectServerSSL的参数或者更改为BIO * &或者重新定义它在事物的C风格:

void connectServerSSL (BIO ** bio_ptr) 
{ 
    SSL_CTX * ctx = SSL_CTX_new(SSLv23_client_method()); 
    SSL * ssl; 

    if(! SSL_CTX_load_verify_locations(ctx, NULL, "/etc/ssl/certs")) 
    { 
     callError(ERR_LOADCERT); 
    } 

    BIO * bio = BIO_new_ssl_connect(ctx); 
    BIO_get_ssl(bio, &ssl); 
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); 

    BIO_set_conn_hostname(bio, hostnamePort); 
    if(BIO_do_connect(bio) <= 0) 
    { 
     callError(ERR_CONNECTION); 
    } 

    if(SSL_get_verify_result(ssl) != X509_V_OK) 
    { 
     callError(ERR_VALIDCERT); 
    } 
    *bio_ptr = bio; 
} 

// Example usage: 

void example() 
{ 
    BIO * bio; 
    connectServerSSL(&bio); 
    BIO_write(bio, request.c_str(), request.size()); 
} 
0

您的connectServerSSL()函数有一个名为bio的参数,它只写入此临时变量,而不写入未初始化的main()中的bio变量。

connectServerSSL()的签名更改为BIO* connectServerSSL(void)并将其与bio = connectServerSSL()联系起来。您也可以用BIO** newbio参数调用函数,用&bio调用它,并设置*newbio,它将更新main()中的bio变量。

一些很好的习惯可以帮助避免这样的错误:将变量初始化为默认值,使用断言检查输入是否有效,以及在调试器中单步执行。如果你初始化了变量main()BIO* bio = NULL,或者更好,BIO* const bio = connectServerSSL(),那么在调试器中它很明显在返回时它仍然是未初始化的。