0

Considering the following functions:

int get_timestamp(json_object *json_obj, double *timestamp) {
    json_object *value_obj;
    int status;
    if (json_object_object_get_ex(json_obj, "timestamp", &value_obj)) {
        if (json_object_is_type(value_obj, json_type_double)) {
            *timestamp = json_object_get_double(value_obj);
            status = JSONPARSER_OK;
        }
        else
            status = JSONPARSER_EBADTYPE;
    } else
        status = JSONPARSER_ENODENOTFOUND;
    free(value_obj);
    return status;
}

int get_display_name(json_object *json_obj, char **display_name) {
    json_object *value_obj;
    int status;
    const char* holder;
    if (json_object_object_get_ex(json_obj, "display_name", &value_obj)) {
        if (json_object_is_type(value_obj, json_type_string)) {
            // The returned string memory is managed by the json_object and will
            // be freed when the reference count of the json_object drops to zero.
            holder = json_object_get_string(value_obj);
            strcpy(*display_name, holder);
            status = JSONPARSER_OK;
        }
        else
            status = JSONPARSER_EBADTYPE;
    } else
        status = JSONPARSER_ENODENOTFOUND;
    free(value_obj);
    return status;
}

int get_organization(json_object *json_obj, char **organization) {
    json_object *value_obj;
    int status;
    const char* holder;
    if (json_object_object_get_ex(json_obj, "organization", &value_obj)) {
        if (json_object_is_type(value_obj, json_type_string)) {
            // The returned string memory is managed by the json_object and will
            // be freed when the reference count of the json_object drops to zero.
            holder = json_object_get_string(value_obj);
            strcpy(*organization, holder);
            status = JSONPARSER_OK;
        }
        else
            status = JSONPARSER_EBADTYPE;
    } else
        status = JSONPARSER_ENODENOTFOUND;
    free(value_obj);
    return status;
}

Used as:

json_object *response_obj, *idp_obj;
int status;
char *display_name;
char *organization;
response_obj = json_tokener_parse(raw_data);
json_object_object_get_ex(response_obj, "idp", &idp_obj);

get_timestamp(response_obj, timestamp);
get_display_name(idp_obj, &display_name);
get_organization(idp_obj, &organization);

free(idp_obj);
free(response_obj);
return status;

What happens:

1) by removing get_organization(idp_obj, &organization); everything seems work fine;

2) by removing get_display_name(idp_obj, &display_name); everything seems work fine again;

3) with the code "as is", there is an error on the strcpy used inside the method get_organization:

No source available for "__strcpy_sse2_unaligned() at 0x7ffff763f001" 

I would really like to understand this behavior in order to improve my knowledge in this amazing but hard languages.

vdenotaris
  • 13,297
  • 26
  • 81
  • 132

1 Answers1

0

That error message is a debugger error message, because it's in a function which it can't locate source to. The only thing you need to do is to walk up the function call stack until you reach your code.

As for why the debugger stops in that function, that's really should be another question, but I'll answer it anyway: It's because of undefined behavior because the destination pointer you pass to it is an uninitialized local variable: display_name. In the code where you call get_display_name you declare the local variable display_name, but you don't initialize it. The value of uninitialized non-static local variable is indeterminate, and using them without initialization leads to undefined behavior.

You have basically two solutions to this problem: Either declare display_name as an array of a fixed size, or use make it point to valid allocated memory, for example by using malloc.

You will also have the same problem with the organization variable.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Hi. Thanks for the answer. Just to understand: why in the case `1` or `2` everything seems work fine? – vdenotaris Aug 26 '15 at 14:38
  • 1
    @vdenotaris That's the thing with *undefined behavior*, sometimes it might *seem* to work, when in reality there's probably something bad happening that you just don't notice (yet). – Some programmer dude Aug 26 '15 at 14:41