TF_NewTensor 分段错误:可能是错误?
TF_NewTensor Segmentation Fault: Possible Bug?
我正在使用 Tensorflow 2.1 git master 分支(提交 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;
}
可能是bug还是我用错了?我不明白 malloc
q 自变量如何导致分段错误。
任何人都可以复制吗?
我用的是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 OK\n");
else
printf("ERROR: Failed TF_NewTensor\n");
}
查看我的 Github running/compile TensorFlow 的 C API here
的完整代码
您将 ndata
设置为 sizeof(int32_t)
,即 4。
您的 ndata
作为 len
参数传递给 TF_NewTensor()
,表示 data
中的元素数量(可以在 GitHub 中看到)。因此,在您的示例中应将其设置为 1,因为您只有一个元素。
顺便说一句,你可以避免在这里使用 malloc()
(因为你不检查 return 值,这可能容易出错并且通常不太优雅)并且只需使用取而代之的是局部变量。
更新
此外,您为 deallocator
和 deallocator_arg
传递了 NULL
。我很确定这是评论指出的问题"Clients must provide a custom deallocator function..."(可以看到here). The deallocator
is called by the TF_NewTensor()
(can be seen here),这可能是分段错误的原因。
所以,总结一下,尝试下一个代码:
void my_deallocator(void * data, size_t len, void * arg)
{
printf("Deallocator called with data %p\n", 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);
}
我正在使用 Tensorflow 2.1 git master 分支(提交 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;
}
可能是bug还是我用错了?我不明白 malloc
q 自变量如何导致分段错误。
任何人都可以复制吗?
我用的是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 OK\n");
else
printf("ERROR: Failed TF_NewTensor\n");
}
查看我的 Github running/compile TensorFlow 的 C API here
的完整代码您将 ndata
设置为 sizeof(int32_t)
,即 4。
您的 ndata
作为 len
参数传递给 TF_NewTensor()
,表示 data
中的元素数量(可以在 GitHub 中看到)。因此,在您的示例中应将其设置为 1,因为您只有一个元素。
顺便说一句,你可以避免在这里使用 malloc()
(因为你不检查 return 值,这可能容易出错并且通常不太优雅)并且只需使用取而代之的是局部变量。
更新
此外,您为 deallocator
和 deallocator_arg
传递了 NULL
。我很确定这是评论指出的问题"Clients must provide a custom deallocator function..."(可以看到here). The deallocator
is called by the TF_NewTensor()
(can be seen here),这可能是分段错误的原因。
所以,总结一下,尝试下一个代码:
void my_deallocator(void * data, size_t len, void * arg)
{
printf("Deallocator called with data %p\n", 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);
}