Ошибка сегментации возникает только при конфигурации выпуска - PullRequest
0 голосов
/ 25 марта 2012

По какой-то странной причине мое приложение любит ломаться, когда я переключаюсь на релиз и запускаю его вне моего отладчика.Вот что у меня работает, а что нет

(Qt Creator - это IDE)

  • Отладка с конфигурацией отладки - ок
  • Запуск с настройкой отладки - ok
  • Отладка с настройкой выпуска - ok
  • Запуск с настройкой выпуска - сбой приложения

Мой пользовательский интерфейс - это один проект, а ядро ​​для некоторых вещей - отдельная зависимость.В Windows (компиляция с MSVCC) я нажимаю кнопку меню, которая в итоге вызывает функцию.В этой функции приложение прерывается при добавлении нового элемента в вектор.Например:

str *x = new str();
str *y = new str();
/* ...set some of x & y's members... */
vector.push_back(x); // works fine
vector.push_back(y); // causes crash

Если я закомментирую строку vector.push_back(y);, приложение не будет иметь никаких проблем, пока приложение не покинет область действия события (то есть конец OnMenuButtonClick).В OS X это похоже на проблему добавления элемента в вектор, за исключением того, что у меня есть:

std::vector<foo *> SomeFunction()
{
   std::vector<foo *> returningVector;
   /* do stuff */
   std::vector<foo *> goo = GetFooObjects();
   for (int i = 0; i < goo.size(); i++)
   {
       returningVector.push_back(goo[i]); // breaks here
   }
}

Так, каковы некоторые причины этого странного поведения без подключенного отладчика и не в конфигурации отладки?Я проверил, чтобы все мои переменные были инициализированы, поэтому я в тупике.Если вы хотите просмотреть код выше, первая часть может быть расположена здесь , а вторая часть здесь .Пожалуйста, прости все, что ты считаешь «плохим», и если у тебя есть предложения, которые ты просто не можешь вместить, тогда, пожалуйста, напиши мне на GitHub.

Редактировать:

Я посмотрел больше на этои выяснил, в чем именно причина проблемы, но не знаю, как ее исправить.Это функция, в которой происходит сбой моего приложения (в OS X):

vector<Drive *> Drive::GetFATXDrives( bool HardDisks )
{
    vector<Drive *> Return;
    if (HardDisks)
    {
        vector<DISK_DRIVE_INFORMATION> Disks = GetPhysicalDisks();
        for (int i = 0; i < (int)Disks.size(); i++)
        {
            DISK_DRIVE_INFORMATION ddi = Disks.at(i);
            // First, try reading the disk way
            Streams::xDeviceStream* DS = NULL;
            try
            {
                char path[0x200] = {0};
                wcstombs(path, ddi.Path, wcslen(ddi.Path));
                DS = new Streams::xDeviceStream(ddi.Path);
            }
            catch (xException& e)
            {
                continue;
            }

            if (DS == NULL || DS->Length() == 0 || DS->Length() < HddOffsets::Data)
            {
                // Disk is not of valid length
                continue;
            }
            DS->SetPosition(HddOffsets::Data);

            // Read the FATX partition magic
            int Magic = DS->ReadInt32();
            // Close the stream
            DS->Close();

            // Compare the magic we read to the *actual* FATX magic
            if (Magic == FatxMagic)
            {
                Drive *d = new Drive(Disks.at(i).Path, Disks.at(i).FriendlyName, false);
                Return.push_back(d);
            }
        }
    }

    vector<Drive *> LogicalDisks = GetLogicalPartitions();
    for (int i = 0; i < (int)LogicalDisks.size(); i++)
    {
        Return.push_back(LogicalDisks.at(i));
    }

    return Return;
}

Если я изменю if (HardDisks) на if (HardDisks = false), приложение будет работать нормально.Итак, я посмотрел в эту область и обнаружил, что после vector<DISK_DRIVE_INFORMATION> Disks = GetPhysicalDisks(); куча становится поврежденной или что-то в этом роде.Я заметил это, потому что в отладчике после вызова этой функции мой HardDisks bool меняется на «ложь», а это не то, что было раньше.

Вот GetPhysicalDisks:

vector<Drive::DISK_DRIVE_INFORMATION> Drive::GetPhysicalDisks( void )
{
    // RIGHT AFTER this vector is initialized, everything goes to hell
    vector<Drive::DISK_DRIVE_INFORMATION> ReturnVector;

DIR *dir;
dirent *ent;
dir = opendir("/dev/");
if (dir != NULL)
{
    // Read the shit
    while ((ent = readdir(dir)) != NULL)
    {
        // Check the directory name, and if it starts with "disk" then keep it!
        QRegExp exp("disk*");
        exp.setPatternSyntax(QRegExp::Wildcard);
        exp.setCaseSensitivity(Qt::CaseInsensitive);
        if (exp.exactMatch(ent->d_name))
        {
            DISK_DRIVE_INFORMATION curdir;
            memset(curdir.FriendlyName, 0, sizeof(curdir.FriendlyName));
            memset(curdir.Path, 0, sizeof(curdir.Path));

            char diskPath[0x50] = {0};
            sprintf(diskPath, "/dev/r%s", ent->d_name);

            mbstowcs(curdir.Path, diskPath, strlen(diskPath));

            int device;
            if ((device = open(diskPath, O_RDONLY)) > 0)
            {
#ifdef __linux
                hd_driveid hd;
                if (!ioctl(device, HDIO_GET_IDENTITY, &hd))
                {
                    swprintf(curdir.FriendlyName, strlen(hd) * 2, L"%hs", hd.model);
                }
#elif defined __APPLE__
                mbstowcs(curdir.FriendlyName, ent->d_name, strlen(ent->d_name));
#endif
                ReturnVector.push_back(curdir);
            }
        }
    }
}
    return ReturnVector;
}

1 Ответ

0 голосов
/ 26 марта 2012

Хотя это не реальный ответ относительно того, что произошло , я нашел способ решить проблему. Глядя на мои правки выше, я отредактировал свою функцию Drive::GetFATXDrives так:

vector<Drive *> Drive::GetFATXDrives( bool HardDisks )
{
    // Initialize Disks vector up here
    vector<DISK_DRIVE_INFORMATION> Disks;
    // Call the function to get the hard disks
    if (HardDisks)
        Drive::GetPhysicalDisks(Disks);

    vector<Drive *> ReturnVector;
    if (HardDisks)
    {
        Streams::xDeviceStream* DS = NULL;
        for (int i = 0; i < (int)Disks.size(); i++)
        {
            /* ... */
        }
        if (DS)
        {
            DS->Close();
            delete DS;
        }
    }

    vector<Drive *> LogicalDisks = GetLogicalPartitions();
    for (int i = 0; i < LogicalDisks.size(); i++)
    {
        ReturnVector.push_back(LogicalDisks[i]);
    }

    return ReturnVector;
}

И моя Drive::GetPhysicalDisks функция теперь берет ссылку vector<DISK_DRIVE_INFORMATION> вместо ее возврата. Казалось, что после этого моя программа работает нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...