C++ Libzip + Delete = Core dump

C++ Libzip + Delete = Core dump … here is a solution to the problem.

C++ Libzip + Delete = Core dump

I’m having trouble with libzip. I installed the library on Linux and using sudo apt-get install libzip2 libzip-dev (so it’s not the latest version).

Here is my code :

#include <iostream>
#include <zip.h>
#include <unistd.h>
#include <sys/stat.h>

#define ZIP_ERROR 2

using namespace std;

bool isFilePresent(string const& path)
{
    struct stat *buf;
    return(stat(path.c_str(), buf)==0);
}

int main(void)
{
    struct zip *zip;
    struct zip_source *zip_source;
    int err(0);
    string zipFile("filesZip/zipTest");
    string fileToZip("filesToZip/test1");
    string fileToZip2("filesToZip/test2");
    char tmp[] = "filesZip/zipTest\0";

 Test if the file is present
    if(isFilePresent(zipFile))
    {
         if(remove(tmp) != 0)
        if(remove(zipFile.c_str()) != 0)
        {
            return ZIP_ERROR;
        }
    }
     Open a zip archive
    zip = zip_open(zipFile.c_str(), ZIP_CREATE, &err);

 if there is an error on the opening
    if(err != ZIP_ER_OK)
    {
        cout << "error when opening" << endl;
        return ZIP_ERROR;
    }

 If the zip file is not open
    if(zip == NULL)
    {
        zip_close(zip);
        cout << "error when zip opens" << endl;
        return ZIP_ERROR;
    }

 zip_source_file zip a file so that it can be added to the zip
    if((zip_source = zip_source_file(zip, fileToZip.c_str(), (off_t)0, (off_t)0))== NULL)
    {
        zip_close(zip);
        zip_source_free(zip_source);
        cout << "pb when zipping file1" << endl;
        return ZIP_ERROR;
    }

 Add the zipped file to the zip  
    if(zip_add(zip, fileToZip.c_str(), zip_source)==-1)
    {
        zip_close(zip);
        zip_source_free(zip_source);
        cout << "pb when adding file1" << endl;
        return ZIP_ERROR;
    }

 zip_source_file zip a file so that it can be added to the zip
    if((zip_source = zip_source_file(zip, fileToZip2.c_str(), (off_t)0, (off_t)0))== NULL)
    {
        zip_close(zip);
        zip_source_free(zip_source);
        cout << "pb when zipping file2" << endl;
        return ZIP_ERROR;
    }

if(zip_add(zip, fileToZip2.c_str(), zip_source)==-1)
    {
        zip_close(zip);
        zip_source_free(zip_source);
        cout << "pb when adding file2" << endl;
        return ZIP_ERROR;
    }

 sleep(180);

 Closing the archive
    zip_close(zip);

return 0;
}

This code should take the two files in the filesToZip folder and compress them into a zipTest file in the filesZip folder.

To do this, it first checks if the zipTest file already exists. If so, delete it. It then opens a zip archive, compresses the files to be added and adds them to the archive before closing it.

So my question is:

When the zip archive file Zip/zipTest is not present, it works fine.
When the zip archive file Zip/zipTest did exist, I got a core dump.

What I’ve tried so far :

  • I think it’s because I’m using a string for the filename. I tried using char and it didn’t change anything
  • Then I think it’s because the deletion task is not completed and then there may be a conflict. So I put sleep(180) (in seconds) after each function call. It didn’t change anything
  • I’ve also tried putting only one file in the archive. Nothing has changed
  • I run gdb to see what’s going on. I tried both when the zip archive already existed and didn’t exist.
    • If the archive is not there: everything goes fine until it returns 0, then I see that the program redefines fileToZip and fileToZip2 before returning 0 and then stopping.
    • If the archive already exists: it does the same thing but then says that the boundaries of the current function cannot be found. (I’ve read .) Here This means gdb has no debugging information and is not happy with it ..).

Does anyone know what my problem is?

Solution

It’s dangerous :

bool isFilePresent(string const& path)
{
    struct stat *buf;
    return(stat(path.c_str(), buf)==0);
}

You don’t allocate any memory for your struct stat*, so random memory is written when the function is called – which can cause a crash.

Try this :

bool isFilePresent(string const& path)
{
    struct stat buf;  memory is allocated on the stack for this object
    return(stat(path.c_str(), &buf)==0);  pass its address to the function
}

It creates a local struct stat object and passes its address to the function.

Related Problems and Solutions