2

I'm using Tensorflow 2.1 git master branch (commit id:db8a74a737cc735bb2a4800731d21f2de6d04961) and compile it locally. Playing around with the C API to call TF_LoadSessionFromSavedModel but seems to get segmentation fault. I've managed to drill down the error in the sample code below.

TF_NewTensor call is crashing and causing a segmentation fault.


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;
}

However, when i move the TF_Tensor** InputValues = (TF_Tensor**)malloc(sizeof(TF_Tensor*)*1); after the TF_NewTensor call, it doesn't crash. Like below:


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;
}

Is it a possible bug or I'm using it wrong? I don't understand how mallocq an independent variable could cause a segmentation fault.

can anybody reproduce?

I'm using gcc (Ubuntu 9.2.1-9ubuntu2) 9.2.1 20191008 to compile.

UPDATE:

can be further simplified the error as below. This is even without the InputValues being allocated.


#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;
}

compile with

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

Solution

As point up by Raz, pass empty deallocater instead of NULL, and ndata should be size in terms of byte.

#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");
}

checkout my Github on full code of running/compile TensorFlow's C API here

5
  • I don't see InputValues being used anywhere, so how could that be the cause of the crash? Commented Jan 23, 2020 at 9:37
  • Did the malloc for InputValues succeed? I don;t see you check that. If it failed, then in your first code al the other mallocs could fail too. Commented Jan 23, 2020 at 9:39
  • Does ndata denote the size of data? Because you only allocate one int32 to it. Commented Jan 23, 2020 at 9:40
  • @PaulOgilvie I'm not using InputValues in this example, but in actual code, I use it to call the SessionRun API. malloc does return non-null values, I did try with ndata = 1 as Raz Haleva suggested as well. Still same segmentation fault
    – AmirulOm
    Commented Jan 24, 2020 at 2:05
  • @PaulOgilvie see the update code that still producing segmentation fault.
    – AmirulOm
    Commented Jan 24, 2020 at 2:12

1 Answer 1

3

You set ndata to be sizeof(int32_t) which is 4. Your ndata is passed as len argument to TF_NewTensor() which represents the number of elements in data (can be seen in GitHub). Therefore, it should be set to 1 in your example, as you have a single element.

By the way, you can avoid using malloc() here (as you don't check for return values, and this may be error-pront and less elegant in general) and just use local variables instead.

UPDATE

In addition, you pass NULL both for deallocator and deallocator_arg. I'm pretty sure this is the issue as the comment states "Clients must provide a custom deallocator function..." (can be seen here). The deallocator is called by the TF_NewTensor() (can be seen here) and this may be the cause for the segmentation fault.

So, summing it all up, try the next code:

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);
}
5
  • I tried to set ndata to 1, but yet the same segmentation fault. Also, I change dims and data as you mentioned. I wonder somebody else could reproduce it or is it just in my environment.
    – AmirulOm
    Commented Jan 24, 2020 at 1:57
  • Funny thing, if I set my data,dims and ndata as you mention, I get segmentation fault EVEN without allocating InputValues
    – AmirulOm
    Commented Jan 24, 2020 at 2:01
  • Please refer to the new code update that are still crashing.
    – AmirulOm
    Commented Jan 24, 2020 at 2:17
  • @AmirulOm please refer to the update section and do not pass NULL both for deallocator and deallocator_arg. Let me know if it helped! Commented Jan 31, 2020 at 10:04
  • Thanks, I figure it by run debugging it through GDB. There is two error. 1) passing NULL to deallocater, should have pass empty deallocater. 2) len is actually size in terms of byte, note length.
    – AmirulOm
    Commented Feb 1, 2020 at 12:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.