C ++ Libzip + remove = дамп ядра

У меня проблема при использовании libzip. Я использую Linux и установил библиотеку, используя sudo apt-get install libzip2 libzip-dev (так что это не последняя версия).

Вот мой код:

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

Этот код должен взять два файла в папке filesToZip и сжать их в файл zipTest в папке filesZip.

Для этого сначала он проверяет, существует ли уже файл zipTest. Если да, то он его удаляет. Затем он открывает zip-архив, заархивирует файлы для добавления и добавляет их в архив перед закрытием архива.

Итак, моя проблема:

когда файлы zip-архива Zip / zipTest не существуют, он работает нормально. когда файлы zip-архива Zip / zipTest действительно существуют, я получил дамп ядра.

Что я пробовал до сих пор:

  • Я думал, это потому, что я использовал строки для имен файлов. Я пробовал с char, и ничего не изменилось
  • тогда я подумал, что это потому, что задача удаления не была завершена, и тогда может возникнуть конфликт. Поэтому я кладу sleep (180) (в секундах) после каждого вызова функции. Ничего не изменилось
  • Еще я пробовал положить в архив только один файл. Ничего не менял
  • I ran gdb to see what was happening. I tried both when the zip archive already existed and did not.
    • if the archive didn't already existed : everything went smoothly till the return 0 and then i saw that the program redefined fileToZip and fileToZip2, then did another return 0 then would stop.
    • если архив уже существует: он делает то же самое, но затем сообщает, что не может найти границы текущей функции. (я прочитал здесь Это означает, что GDB не имеет отладочной информации и недоволен этим ..)

Кто-нибудь знает, в чем может быть моя проблема?


person M0rkHaV    schedule 13.10.2014    source источник


Ответы (1)


Это опасно:

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

Вы не выделяете память для своего struct stat*, поэтому при вызове функции в нее записывается случайная память, что может вызвать сбой.

Попробуйте это:

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
}

Он создает локальный объект struct stat и передает его адрес функции.

person Galik    schedule 13.10.2014
comment
Вроде работает! Спасибо ! Однако у меня все еще есть 3 странные строчки в конце программы. Есть идеи, что могло вызвать это? - person M0rkHaV; 13.10.2014
comment
@ M0rkHaV Я не вижу странных строк, когда запускаю его, не могли бы вы дать дополнительную информацию? - person Galik; 13.10.2014
comment
Я вижу их при запуске программы с gdb. После return 0 у меня string fileToZip2("filesToZip/test2"); string fileToZip("filesToZip/test1");return 0; - person M0rkHaV; 13.10.2014
comment
@ M0rkHaV Вы имеете в виду в переменной отладчика после вызова return 0? Если это так, я бы не беспокоился о том, как выглядит содержимое переменных после вызова их деструкторов, их содержимое теперь не определено. Я могу получить то же самое, удалив всю программу, кроме strings. После вызова их деструктора отладчик, кажется, теряет их длину и отображается за их пределами. - person Galik; 13.10.2014