Finn
Finn

Reputation: 83

C code works when run with gdb but not normally

My code only works if I run it with gdb: gdb ./MyCode run

and not if I just type: ./MyCode

This is the part of my code that is failing:

bool packageBuildFileDownload(char* receiver, char* finished, char* file_name, char* payload, char** json_string, size_t json_string_size) {
    cJSON* json = packageCreateJson();
    if (!json) return false;
        
    typedef struct PackageAttribute {
        char
            *name, 
            *value;
    } PackageAttribute;
    
    PackageAttribute attributes[] = {
        {
            .name = "type", 
            .value = "filedownload"
        }, 
        {
            .name = "receiver", 
            .value = receiver
        }, 
        {
            .name = "file_name", 
            .value = file_name
        }, 
        {
            .name = "finished", 
            .value = finished
        }, 
        {
            .name = "payload", 
            .value = payload
        }           
    };
    int attributes_size = sizeof(attributes) / sizeof(attributes[0]);
    
    for (int i = 0; i < attributes_size; i++) {
        if (!cJSON_AddStringToObject(json, attributes[i].name, attributes[i].value)) {
            cJSON_Delete(json);
            return false;
        }
    }

    if (!cJSON_PrintPreallocated(json, *json_string, json_string_size, false)) {
        // cJSON_PrintPreallocated returns failour 
        cJSON_Delete(json);
        return false;
    }
    
    cJSON_Delete(json);
    return true;
}

static bool filedownloadrequestSendResponse(Socket* socket, uint8_t* file_buffer, size_t file_buffer_size, char* receiver, char* finished, char* file_name) {
    char* b64_encode_buffer;
    base64Encode(file_buffer, file_buffer_size, &b64_encode_buffer);

    char* json_string = malloc(RESPONSE_PACKAGE_BUFFER_SIZE);
    if (!packageBuildFileDownload(receiver, finished, file_name, b64_encode_buffer, &json_string, strlen(json_string))) {
        free(json_string);
        return false;
    }
    
    free(b64_encode_buffer);
    
    CURLcode result = sendWs(socket->curl, json_string);
    free(json_string);
    if (result != CURLE_OK) {
        fprintf(stderr, "sendWs() failed: %s\n", curl_easy_strerror(result));
        return false;
    }
    
    return true;
}

My packageBuildFileDownload() function returns false because cJSON_PrintPreallocated is failing (cJSON_PrintPreallocated is part of the cJSON library). This only happends if I dont use gdb for some reason.

If you need more code please let me know :)

Upvotes: 0

Views: 121

Answers (1)

Employed Russian
Employed Russian

Reputation: 213947

My code only works if I run it with gdb:

GDB by default disables ASLR. Your code will probably stop working under GDB if you re-enable ASLR:

gdb ./MyCode run
(gdb) set disable-randomization off
(gdb) run

If enabling ASLR makes the program fail, it is exceedingly likely is failing due to using uninitialized memory.

And as Stanislav Volodarskiy commented, this is definitely a bug (and exactly the reading of uninitialized memory bug at that):

char* json_string = malloc(RESPONSE_PACKAGE_BUFFER_SIZE);
if (!packageBuildFileDownload(..., &json_string, strlen(json_string))) {

To fix that bug, do this:

char* json_string = malloc(RESPONSE_PACKAGE_BUFFER_SIZE);
if (!packageBuildFileDownload(..., &json_string, RESPONSE_PACKAGE_BUFFER_SIZE)) {

Upvotes: 1

Related Questions