Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 23, средняя оценка - 4.87
Petrolion
24 / 24 / 7
Регистрация: 02.02.2016
Сообщений: 124
#1

Битовые утечки при записи данных на диск - C++

06.06.2016, 14:42. Просмотров 3600. Ответов 119
Метки нет (Все метки)

Доброго дня форумчане!
Сорри если оффтоп но... Пишу в консольке на C++ (MSVCE 2010) различные движки по расчетам и тут столкнулся с опасной проблемой.
При записи на диск искажаются данные на один бит, где то один раз на 109 - 1011 данных. Бит просто "теряется" (был 1 стал 0 или наоборот) , соответственно данные уже не верны, что приводит к нулю все проделанную работу.
Из исследованного:
Бит теряется при записи как в поток текстового значения переменных (типа fileout << a[i] << endl;)
Так и при записи в двоичном виде (типа fileout.write(reinterpret_cast<char*>(a),size*sizeof(a[0]));)
Замечено, что данные в памяти верные, т.к. были пойманы моменты при повторном выводе из того же массива все данные были записаны корректно.
Ошибка не зависит от винчестера на который данные были записаны (были записи на 3 различных винта, один из которых рейд массив).
Чаще всего теряется один из старших битов (типа 24-й бит в unsigned long или 24-й в unsigned long long). Других потерянных бит не замечено.
Термин "потерянный" возможно применяю в данном случае не верно. Т.к. заметно искажение только при его инвертировании. Соответственно если был сбой и он вместо 1 записал сбойную 1 - этого я не найду.
Система молчит про контроль целостности данных. Винт тоже. У винтов и рейда все показатели в порядке (блоки не сыпятся, SMART в порядке).

Сталкивался ли кто с подобным? В чем может быть проблема?

В ближайшем будущем хочу переустановить систему и MSVCE 2013. Но не уверен, что система виновата.
Кто что подскажет?
1
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.06.2016, 14:42
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Битовые утечки при записи данных на диск (C++):

Избежать утечки памяти при преобразовании строки в массив символов - C++ Builder
Всем привет! Как избежать утечки памяти в таком коде: char* ConvertString(String input) { char *output = new char; ...

Утечки памяти при использовании new/delete для двумерных массивов - C++
Добрый день. Суть в том, что есть несколько функций, получающих на вход и возвращающих двумерные массивы. Реализация передачи массивов...

Битовые операции с разными типа данных - C++
Здравствуйте. В голове возник такой странный вопрос, а мб и не странный. Возможны ли битовые операции с разными типа данных, например int...

Битовые операции, битовые поля. - C++
Здравствуйте! Еслть 4 диапазона чисел: 0-100, 0-100, 0-6000, 0-3. Сделать в виде битовых операций. Записать в unsigned int. Использовать...

Ошибка при записи данных в файл - C++
Для записи перменной типа string выделяю динамически массив из 64 элементов char,после записи данных освобождаю память,но почему-то при...

Ошибка при записи в файл данных из обьекта класса - C++
#include &lt;iostream&gt; #include &lt;conio.h&gt; #include &lt;fstream&gt; using namespace std; class Vector { public: double x; ...

119
HighPredator
5545 / 1858 / 346
Регистрация: 10.12.2010
Сообщений: 5,444
Записей в блоге: 2
06.06.2016, 14:49 #2
Petrolion, факт ошибки подтвержен? Т.е. показано несоответствие данных, записываемых на диск, и считанных с него же? Как именно (код)?
1
Petrolion
24 / 24 / 7
Регистрация: 02.02.2016
Сообщений: 124
06.06.2016, 15:14  [ТС] #3
HighPredator, к сожалению факт ошибки подтвержден и не раз. Есть данные (возрастающая последовательность) полученные многократно, при этом иногда одиночные значения делают резкий провал или вылет из общей последовательности на один бит. При проверке с остальными проходами видно что это именно инвертирование (или потеря) одного бита.
Цитата Сообщение от HighPredator Посмотреть сообщение
Т.е. показано несоответствие данных, записываемых на диск, и считанных с него же?
вот здесь возможна семантическая неувязочка. Т.к. возможно именно библиотека C++ отдает на запись не верные данные, соответственно винт принял и отдал именно те данные которые ему предоставили.
Думаю в коде нет смысла. Пробовал даже обычное считывание и запись данных. Ошибка при том же коде возникает не всегда, но при многочисленных повторах да. Отлавливаю отличие в выходных данных обычным fc для текстовых или fc /b для бинарных данных из командной строки. (Для контроля делаю сравнение по нескольку раз тоже). Ошибок fc не обнаружено.
0
Renji
2015 / 1383 / 312
Регистрация: 05.06.2014
Сообщений: 3,950
06.06.2016, 15:22 #4
Либо сыпится память, либо все же труднообнаружимый баг в программе.
1) Загрузитесь с Лайв-CD Дебиана, зайдите в Advanced options и запустите Memory Diagnostic Tool. Ну или что там в Винде вместо этого, если Дебиан качать не хотите.
2) Все же прогоните простенький тестик на тему "записал, прочитал обратно, сравнил".
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main ()
{
    const int size=100500;
    char*data=new char[size];
    char*copy_data=new char[size];
    for(int i=0;i<size;++i)
        data[i]=rand();
 
    std::ofstream ostream("test");
    ostream.write(data,size);
    ostream.close();;
 
    std::ifstream istream("test");
    istream.read(copy_data,size);
    istream.close();
 
    if(memcmp(data,copy_data,size))
        cout<<"опс..."<<endl;
}
2
Petrolion
24 / 24 / 7
Регистрация: 02.02.2016
Сообщений: 124
06.06.2016, 15:34  [ТС] #5
Renji, память проверил сразу. Но в Винде. С ней порядок. Нашел, что данные в памяти хранятся нормально, т.к. без выхода из программы (данные все еще в памяти) повторный вывод данных может быть другим. Для одно и двухбайтовых данных проблем не обнаружил. Ошибки с 4 и 8-ми байтовыми данными. Потому и подозрительно. Грешу на MSVCE. Но где копать, не знаю.
ЗЫ. Оперирую с большими динамическими массивами от 107 до 109 значений.
0
HighPredator
5545 / 1858 / 346
Регистрация: 10.12.2010
Сообщений: 5,444
Записей в блоге: 2
06.06.2016, 15:41 #6
Цитата Сообщение от Petrolion Посмотреть сообщение
Думаю в коде нет смысла.
В коде больше смысла, чем в вашем утверждении
Цитата Сообщение от Petrolion Посмотреть сообщение
возможно именно библиотека C++ отдает на запись не верные данные
Так что давайте вы создадите тестовый пример на котором у вас воспроизводится данный кейс, а мы посмотрим. Иначе все просто голословные рассуждения.
2
Petrolion
24 / 24 / 7
Регистрация: 02.02.2016
Сообщений: 124
07.06.2016, 12:50  [ТС] #7
Итак, тестовая прога (x64):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
    int n = 1<<30;
    int k = 1<<24;
    int c = 1;
    ofstream fbin, ftxt;
    unsigned long long * b = new unsigned long long[n];
    for (int i = 0; i < n; i++)
        b[i]=k+i;
    cout << "Table ready." << endl;
    do
    {
        cout << endl << "Menu:" << endl << "1 - output binary (Data.dat)" << endl << "2 - output text (Data.txt)" << endl << "0 - Exit" << endl << "your choise: ";
        cin >> c;
        switch(c)
        {
        case 1:
            fbin.open("Data.dat",ios_base::binary);
            fbin.write(reinterpret_cast<char*>(b),n*sizeof(b[0]));
            fbin.close();
            break;
        case 2:
            ftxt.open("Data.txt");
            for (int i = 0; i < n; i++)
                ftxt << b[i] << endl;
            ftxt.close();
            break;
        }
        cout << "Done." << endl;
    } while (c != 0);
    cin.get();
return 0;
}
На очередном запуске вывода бинарника (текстовик выводит очень долго, а с двух раз проблем не случилось) поймал одну ошибку, сегодня с утра вторую. В сумме ушло около 12 часов прогонов. И опять 24-й бит.

Сравнение файлов Data0.dat и DATA4.DAT
00000001E142D92B: 3C 3D

Сравнение файлов Data.dat и DATA4.DAT
000000018C02E8DB: 33 32

Согласитесь, код наиэлементарнейший.
1
Миниатюры
Битовые утечки при записи данных на диск   Битовые утечки при записи данных на диск  
HighPredator
5545 / 1858 / 346
Регистрация: 10.12.2010
Сообщений: 5,444
Записей в блоге: 2
07.06.2016, 14:53 #8
Посмотрел. Походу действительно косяк есть. По второму скрину разобрал назад. В общем постоянное слагаемое К равно 16777216. Три четырехбайтовые значения в порядке возрастания с косяком:
Код
32 80 5D 1A = 847273242
33 80 5D 1B = 864050459
32 80 5D 1C = 847273244
Отняв слагаемое, выходит, что состояние счетчика i было:
Код
847273242 - 16777216 = 830496026
864050459 - 16777216 = 847273242
847273244 - 16777216 = 830496028
Выходит, что во втором случае i должен был быть равен 830496027. Битовое представление:
Код
847273242 (10) = 0011 0010 1000 0000 0101 1101 0001 1010 (2)
830496027 (10) = 0011 0001 1000 0000 0101 1101 0001 1011 (2)
Итого действительно налицо кривой бит три кривых бита (посмотрел внимательно).

Не по теме:

Разбор для наглядности. Ясен пень, что из хекс представления это и так видно.


Мое мнение такое, что причина такого аппаратная. Я не могу себе представить ни один кейс программной ошибки в системной либе. Если бы это было так, то частота воспроизводимости ошибки была бы в разы выше. У вас я так понял, оно очень плохо воспроизводится?

АПД. Короче, я все еще уверен, что ошибка аппаратная. Но меня смущает именно три бита. Может кто меня проверить? Я все так высчитал?
2
Renji
2015 / 1383 / 312
Регистрация: 05.06.2014
Сообщений: 3,950
07.06.2016, 15:11 #9
Цитата Сообщение от HighPredator Посмотреть сообщение
АПД. Короче, я все еще уверен, что ошибка аппаратная.
И называется "bit flipping". Таки да, симптомы посыпавшейся памяти.
2
Petrolion
24 / 24 / 7
Регистрация: 02.02.2016
Сообщений: 124
07.06.2016, 15:35  [ТС] #10
Цитата Сообщение от HighPredator Посмотреть сообщение
864050459 - 16777216 = 847273242
ошибка
864050459 - 16777216 = 847273243
Но можно было и не вычислять. Там сразу в HEX видно было отличие на 1 бит в 4 байте.
Постоянную (это именно 24-й бит) добавил, чтобы было видно если ее потеря будет на младших значениях.
Я возможно бы согласился (хотел бы) что ошибка аппаратная, но результат непостоянен. Кроме этого контроллер памяти молчит о целостности данных. Память у меня без коррекции ошибок (CORSAIR CMX8GX3M1A1333C9). Средний ценовой диапазон.
Почему то этот бит, то устанавливается, то сбрасывается...
И на весь файл только 1 ошибочное значение. Была бы линия в памяти битая, я бы получил таких значений вагон и еще тележку при таком кол-ве данных.
Сейчас добавлю к коду еще момент вывода адреса таблицы и операции с ячейками, чтобы понять - это всегда один и тот же адрес или нет.

PS. Почему стресс-тест памяти не нашел проблему?

Добавлено через 4 минуты
Цитата Сообщение от Renji Посмотреть сообщение
И называется "bit flipping". Таки да, симптомы посыпавшейся памяти.
Печально если так... Два года работы псу под хвост. Я не могу доверять данным.
2
HighPredator
5545 / 1858 / 346
Регистрация: 10.12.2010
Сообщений: 5,444
Записей в блоге: 2
07.06.2016, 15:42 #11
Цитата Сообщение от Petrolion Посмотреть сообщение
ошибка
Спасибо, обновил.

Исправления:
Код
847273243 (10) = 0011 0010 1000 0000 0101 1101 0001 1011 (2)
830496027 (10) = 0011 0001 1000 0000 0101 1101 0001 1011 (2)
Цитата Сообщение от HighPredator Посмотреть сообщение
состояние счетчика i было:
Код
847273242 - 16777216 = 830496026
864050459 - 16777216 = 847273243
847273244 - 16777216 = 830496028
Цитата Сообщение от Petrolion Посмотреть сообщение
Почему стресс-тест памяти не нашел проблему?
С учетом того, насколько низкая частота воспроизводимости, немудрено.

Добавлено через 2 минуты
Цитата Сообщение от Petrolion Посмотреть сообщение
И на весь файл только 1 ошибочное значение
С учетом количества информации в нем, это отличный результат имхо.
2
Toshkarik
1147 / 864 / 51
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
07.06.2016, 17:10 #12
Скорее не состояние счетчика, а то, как сумма записалась в память. Ошибка произошла при записи суммы в память. Причем, вроде как, редких ошибок не избежать даже на самой стабильной системе. Вам придется пользоваться ECC-память.

Добавлено через 1 час 18 минут
Вот интересная статья https://geektimes.ru/post/71748/
Вернее даже заметка, но в ней есть ссылка на полное исследование.
2
Petrolion
24 / 24 / 7
Регистрация: 02.02.2016
Сообщений: 124
08.06.2016, 11:29  [ТС] #13
Вчера полдня гонял по памяти memtest86 (старинную версию). Всю ночь работала 4-я версия (свежее у меня не грузится) по памяти всеми тестами и всеми ядрами. В обоих случаях ошибок нет. :-( (Последний скрин в аттаче)
Теоретически отловить мою ошибку должна была еще на тесте #2.
1
Миниатюры
Битовые утечки при записи данных на диск  
Petrolion
24 / 24 / 7
Регистрация: 02.02.2016
Сообщений: 124
08.06.2016, 11:46  [ТС] #14
Toshkarik, спасибо за интересную статью. Жаль не указаны производители матерей и памяти.
Но в моем случае ошибку получить можно чаще чем в исследованиях Гугла. В диапазоне 10-12 часов можно отловить 1-2 ошибки.
При этом стресс-тест памяти без системы и приложений, не находит этой ошибки вовсе за то же время.
0
Evg
Эксперт CАвтор FAQ
18377 / 6424 / 441
Регистрация: 30.03.2009
Сообщений: 17,818
Записей в блоге: 28
08.06.2016, 13:43 #15
Цитата Сообщение от Petrolion Посмотреть сообщение
В чем может быть проблема?
Процессор разогнанный?

По описанию не исключаю ошибку процессора. Ради интереса попробуй всё это воспроизвести на другом компе. memtest тут вряд ли что-то покажет
3
08.06.2016, 13:43
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.06.2016, 13:43
Привет! Вот еще темы с ответами:

Утечки при использовании порта завершения и соккетов - C++
Здравствуйте, уважаемые Гуру! Реализовываю сервер с использованием порта завершения. Всё работает, всё прекрасно. Одно меня смущает -...

ClientDataSet, Blob утечки памяти при записи в файл - Delphi
столкнулся с такой ситуацией, есть ClientdataSet в котором есть блоб поле, которое я записываю процедурой ниже: Procedure...

При записи файлов на диск, комптютер выдал ошибку, что данный диск не может дальше использоваться - Windows 7
При записи файлов на диск, через некоторое время мой комптютер выдал ошибку, что данный диск не может дальше использоваться(или что-то...

При закачке игры на жесткий диск пишет "Ошибка при записи на диск" - Жесткие диски
В системе 2 жестких диска. Так вот, при попытке установить на жесткий диск игры со стима пишет &quot;Ошибка при записи на диск&quot;, загрузка...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.