我有一个尝试读取特定密钥文件的应用程序,这可能会在程序的生命周期中多次发生。以下是读取文件的功能:
__status
_read_key_file(const char * file, char ** buffer)
{
FILE * pFile = NULL;
long fsize = 0;
pFile = fopen(file, "rb");
if (pFile == NULL) {
_set_error("Could not open file: ", 1);
return _ERROR;
}
// Get the filesize
while(fgetc(pFile) != EOF) {
++fsize;
}
*buffer = (char *) malloc(sizeof(char) * (fsize + 1));
// Read the file and write it to the buffer
rewind(pFile);
size_t result = fread(*buffer, sizeof(char), fsize, pFile);
if (result != fsize) {
_set_error("Reading error", 0);
fclose(pFile);
return _ERROR;
}
fclose(pFile);
pFile = NULL;
return _OK;
}
现在的问题是,对于单个打开/读取/关闭它可以正常工作,除非我第二次运行该函数 - 它总是会在此行进行段错误:while(fgetc(pFile) != EOF)
跟踪gdb,它表明segfault在fgetc函数本身内发生得更深。 我有点失落,但显然我做错了,因为如果我试着用fseek / ftell告诉大小,我总是得到0。
某些背景信息:
修改 是的,似乎不只是满足于眼睛。让 - 弗朗索瓦·法布尔(Jean-FrançoisFabre)产生了一个我测试过的想法并且它有效,但我仍然对此感到困惑。
一些额外的背景:
假设C中有一个看起来像这样的函数:
_status
init(_conn_params cp) {
_status status = _NONE;
if (!cp.pkey_data) {
_set_error("No data, open the file", 0);
if(!cp.pkey_file) {
_set_error("No public key set", 0);
return _ERROR;
}
status = _read_key_file(cp.pkey_file, &cp.pkey_data);
if (status != _OK) return status;
}
/* SOME ADDITIONAL WORK AND CHECKING DONE HERE */
return status;
}
现在在Python中(使用3.5进行测试),我们生成那些conn_params,然后调用init函数:
from ctypes import *
libCtest = CDLL('./lib/lib.so')
class _conn_params(Structure):
_fields_ = [
# Some params
('pkey_file', c_char_p),
('pkey_data', c_char_p),
# Some additonal params
]
#################### PART START #################
cp = _conn_params()
cp.pkey_file = "public_key.pem".encode('utf-8')
status = libCtest.init(cp)
status = libCtest.init(cp) # Will cause a segfault
##################### PART END ###################
# However if we do
#################### PART START #################
cp = _conn_params()
cp.pkey_file = "public_key.pem".encode('utf-8')
status = libCtest.init(cp)
# And then
cp = _conn_params()
cp.pkey_file = "public_key.pem".encode('utf-8')
status = libCtest.init(cp)
##################### PART END ###################
第二个PART START / PART END不会在这种情况下导致段错误。
有人知道原因吗?