概括
在使用 OCI_THREADED 选项设置 OCI 环境失败后尝试释放 OCIEnv 结构时,会发生分段错误(由于例如错误配置的 NLS_LANG 环境变量而失败)。
当OCIEnvCreate 在没有OCI_THREADED 选项的情况下调用时,示例代码不会崩溃,它会按预期工作。
示例代码
#include <oci.h>;
#include <stdio.h>
#include <string.h>
int my_connect(const char *username, const char *password, const char *sid)
{
OCIEnv *env = NULL;
OCIError *err = NULL;
OCISvcCtx *svc = NULL;
if ( OCIEnvCreate(&env,
OCI_THREADED,
(dvoid *)0,
0,
0,
0,
(size_t)0,
(dvoid **)0) )
{
fprintf(stderr, "unable to initialize environment\n");
if ( env )
{
printf("env:[%p]\n", env);
OCIHandleFree(env, OCI_HTYPE_ENV); // segfault.
}
return -1;
}
printf("env:[%p]\n", env);
if ( OCIHandleAlloc((dvoid *)env,
(dvoid **)&err,
OCI_HTYPE_ERROR,
(size_t)0,
(dvoid **)0) )
{
fprintf(stderr, "unable to alloc error handlers\n");
goto error;
}
if ( OCIHandleAlloc((dvoid *) env,
(dvoid **) &svc,
OCI_HTYPE_SVCCTX,
(size_t) 0,
(dvoid **)0) )
{
fprintf(stderr, "unable to allocate service handlers\n");
goto error;
}
if ( OCILogon(env,
err,
&svc,
(CONST OraText *) username,
strlen(username),
(CONST OraText *) password,
strlen(password),
sid,
strlen(sid)
) )
{
fprintf(stderr, "login failed\n");
goto error;
}
printf("logged in\n");
if ( OCILogoff (svc, err) )
{
fprintf(stderr, "logoff failed\n");
goto error;
}
printf("logged out\n");
error:
if ( err )
OCIHandleFree(err, OCI_HTYPE_ERROR);
if ( svc )
OCIHandleFree(svc, OCI_HTYPE_SVCCTX);
if ( env )
OCIHandleFree(env, OCI_HTYPE_ENV);
return 0;
}
int main()
{
return my_connect("test_user", "qqq123", "XE");
}
运行前
export NLS_LANG=x
堆栈跟踪
问题是使用 NULL 指针调用 __pthread_mutex_destroy。
#0 __pthread_mutex_destroy (mutex=0x0) at pthread_mutex_destroy.c:28
#1 0x00007ffff585e6e0 in sltsmxd () from /lib/libclntsh.so.11.1
#2 0x00007ffff56a147c in kpufhndl0 () from /lib/libclntsh.so.11.1
#3 0x00007ffff56a0185 in kpufhndl () from /lib/libclntsh.so.11.1
#4 0x00007ffff567cac1 in OCIHandleFree () from /lib/libclntsh.so.11.1
#5 0x0000000000400a0c in my_connect (username=0x400dd1 "test_user", password=0x400dca "qqq123", sid=0x400dc7 "XE") at test2.c:24
#6 0x0000000000400c27 in main () at test2.c:84
产品详情
Basic Lite Package Information
Thu Oct 4 13:00:49 UTC 2007
Client Shared Library 64-bit - 11.1.0.6.0
System name: Linux
Release: 2.6.9-34.0.1.0.11.ELsmp
Version: #1 SMP Mon Dec 4 22:20:39 UTC 2006
Machine: x86_64
操作系统详细信息
Linux 3.2.0-37-generic #58-Ubuntu SMP Thu Jan 24 15:28:10 UTC 2013 x86_64 GNU/Linux
Distributor ID: Ubuntu
Description: Ubuntu 10.04.4 LTS
Release: 10.04
Codename: lucid
问题
目前我只是不释放该内存区域,但这不是一个好的解决方案。你怎么看,什么是好的解决方案?