TF_NewTensor分段错误:可能的错误?

TF_NewTensor Segmentation Fault: Possible Bug?

本文关键字:错误 NewTensor 分段 TF      更新时间:2023-10-16

我正在使用Tensorflow 2.1 git master branch(提交ID:db8a74a737cc735bb2a4800731d21f2de6d04961(并在本地编译它。使用C API调用TF_LoadSessionFromSavedModel但似乎得到了分段错误。我已经设法在下面的示例代码中钻取了错误。

TF_NewTensor调用崩溃并导致分段错误。


int main()
{
TF_Tensor** InputValues = (TF_Tensor**)malloc(sizeof(TF_Tensor*)*1);
int ndims = 1;
int64_t* dims = malloc(sizeof(int64_t));
int ndata = sizeof(int32_t);
int32_t* data = malloc(sizeof(int32_t));
dims[0] = 1;
data[0] = 10;
// Crash on the next line
TF_Tensor* int_tensor = TF_NewTensor(TF_INT32, dims, ndims, data, ndata, NULL, NULL);
if(int_tensor == NULL)
{
printf("ERROR");
}
else
{
printf("OK");
}
return 0;
}

但是,当我在TF_NewTensor调用后移动TF_Tensor** InputValues = (TF_Tensor**)malloc(sizeof(TF_Tensor*)*1);时,它不会崩溃。如下所示:


int main()
{
int ndims = 1;
int64_t* dims = malloc(sizeof(int64_t));
int ndata = sizeof(int32_t);
int32_t* data = malloc(sizeof(int32_t));
dims[0] = 1;
data[0] = 10;
// NO more crash
TF_Tensor* int_tensor = TF_NewTensor(TF_INT32, dims, ndims, data, ndata, NULL, NULL);
if(int_tensor == NULL)
{
printf("ERROR");
}
else
{
printf("OK");
}
TF_Tensor** InputValues = (TF_Tensor**)malloc(sizeof(TF_Tensor*)*1);

return 0;
}

这是一个可能的错误还是我用错了?我不明白自变量mallocq 如何导致分割错误。

任何人都可以繁殖吗?

我正在使用 gcc (Ubuntu 9.2.1-9ubuntu2( 9.2.1 20191008 进行编译。

更新:

可以进一步简化错误,如下所示。即使没有分配InputValues,也是如此。


#include <stdlib.h>
#include <stdio.h>
#include "tensorflow/c/c_api.h"
int main()
{
int ndims = 1;
int ndata = 1;
int64_t dims[] = { 1 };
int32_t data[] = { 10 };
TF_Tensor* int_tensor = TF_NewTensor(TF_INT32, dims, ndims, data, ndata, NULL, NULL);
if(int_tensor == NULL)
{
printf("ERROR Tensor");
}
else
{
printf("OK");
}
return 0;
}

编译方式

gcc -I<tensorflow_path>/include/ -L<tensorflow_path>/lib test.c -ltensorflow -o test2.out

溶液

正如 Raz 所指出的那样,传递空deallocater而不是 NULL,ndata的大小应该是字节。

#include "tensorflow/c/c_api.h"
void NoOpDeallocator(void* data, size_t a, void* b) {}
int main(){
int ndims = 2;
int64_t dims[] = {1,1};
int64_t data[] = {20};
int ndata = sizeof(int64_t); // This is tricky, it number of bytes not number of element
TF_Tensor* int_tensor = TF_NewTensor(TF_INT64, dims, ndims, data, ndata, &NoOpDeallocator, 0);
if (int_tensor != NULL)
printf("TF_NewTensor is OKn");
else
printf("ERROR: Failed TF_NewTensorn");
}

在这里查看我的Github运行/编译TensorFlow的C API的完整代码

您将ndata设置为sizeof(int32_t)即 4。 您的ndata作为参数传递给TF_NewTensor()len该参数表示data中的元素数(可以在 GitHub 中看到(。因此,在您的示例中,它应设置为 1,因为您有一个元素。

顺便说一下,您可以避免在此处使用malloc()(因为您不检查返回值,这通常可能出错且不太优雅(,而只使用局部变量。

更新

此外,您通过NULLdeallocatordeallocator_arg。我很确定这就是问题所在,因为评论指出"客户必须提供自定义分配器功能......">(可以在这里看到(。deallocatorTF_NewTensor()调用(可以在此处看到(,这可能是分段错误的原因。

因此,总结一下,尝试下一个代码:

void my_deallocator(void * data, size_t len, void * arg)
{
printf("Deallocator called with data %pn", data);
}
void main()
{
int64_t dims[] = { 1 };
int32_t data[] = { 10 };
... = TF_NewTensor(TF_INT32, dims, /*num_dims=*/ 1, data, /*len=*/ 1, my_deallocator, NULL);
}