Форум программистов, компьютерный форум CyberForum.ru

Отладка: _free_base “Error reading register value” - C++

Восстановить пароль Регистрация
 
 
Draiget
 Аватар для Draiget
0 / 0 / 0
Регистрация: 02.05.2013
Сообщений: 31
Завершенные тесты: 2
24.09.2014, 23:12     Отладка: _free_base “Error reading register value” #1
Доброго времени суток, имеется сей код:

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
...
std::fstream f_hStream;
f_hStream.open("<file>", ios_base::binary | ios_base::in);
...
unsigned long size = 0;
...
f_hStream.read( reinterpret_cast< char* >( &size ), 8 );
 
if (size > 0){
    char buff[126];
    f_hStream.read(buff, size);
    string cut_header = zCrypto::from_base64( string(buff, size) );
 
    if ( cut_header.length() == 0 ) break;
                
    string dec = zCrypto::decrypt( cut_header ); //Ошибка тут <<<
    printf( "Header >> %s\n", dec.c_str() );
    vector<string> header = split(dec, ';');  //Ошибка тут <<<
 
    ...
                
} else {
    break;
}
...
Функция дешифровки:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const char* zCrypto::decrypt(const std::string& str_in) {
    const string key = zCrypto::from_base64("<base_64line_here>");
    const string iv = zCrypto::from_base64("<base_64line_here>");
 
    std::string str_out;
    CryptoPP::CBC_Mode<CryptoPP::Rijndael>::Decryption decryption((byte*)key.c_str(), key.length(), (byte*)iv.c_str());
 
    CryptoPP::StringSource encryptor(str_in, true,
        new CryptoPP::StreamTransformationFilter(decryption,
            new CryptoPP::StringSink(str_out)
        )
    );
 
    return str_out.data();
}


Через дебаггер VS ошибку выдает на это, каждая ошибка скипаеться со 2-го раза:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void __cdecl _free_base (void * pBlock)
{
 
        int retval = 0;
 
 
        if (pBlock == NULL)
            return;
 
        RTCCALLBACK(_RTC_Free_hook, (pBlock, 0));
 
        retval = HeapFree(_crtheap, 0, pBlock);
        if (retval == 0)
        {
            errno = _get_errno_from_oserr(GetLastError());
        }
}
Отладка: _free_base “Error reading register value”
Если запускать без дебаггера, программа просто прекращает работу, подскажите куда копать?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.09.2014, 23:12     Отладка: _free_base “Error reading register value”
Посмотрите здесь:

Переменная в register, операция >>, во что компилится? C++
C++ register
C++ Problems reading data
Спецификатор автоматического класса памяти, register C++
C++ underflow error reading the file
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
stima
429 / 284 / 16
Регистрация: 22.03.2011
Сообщений: 923
Завершенные тесты: 1
25.09.2014, 00:25     Отладка: _free_base “Error reading register value” #2
1. Вы уверены, что читаете правильно стартовые байты? Вы читаете 1 байт в переменную размером 4 байта. Это не смертельно, но не совсем стыковка логики.
2. Вы уверены что size >= 126? Я думаю ошибка в этом. Вы просто трете стек.
3. Зачем Вам zCrypto::from_base64 на буфер?
4. Слишком много копирования буфера. Подумайте как избежать этого.
Draiget
 Аватар для Draiget
0 / 0 / 0
Регистрация: 02.05.2013
Сообщений: 31
Завершенные тесты: 2
25.09.2014, 12:01  [ТС]     Отладка: _free_base “Error reading register value” #3
1. Разве у нас unsigned long не 8, или вы о другом?
2. Тут я пытался задавать буфер так-же по size, но разницы никакой, размер там около 44+- везде, думаю не в этом проблема.
3. Попробую без него сделать.
stima
429 / 284 / 16
Регистрация: 22.03.2011
Сообщений: 923
Завершенные тесты: 1
25.09.2014, 13:04     Отладка: _free_base “Error reading register value” #4
1. Используйте std::string как буфер.
2. Вы уверены что Вы читаете сколько просите?

C++
1
2
3
4
    string buf(size, 0);
    size_t rb = f_hStream.read(&buf.c_str(), buf.size());
 
    assert(rb == buf.size());
п.с. Вы точно трете буфер. И точно при манипулировании с буфером и его размером. Будьте внимательны!
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
25.09.2014, 14:46     Отладка: _free_base “Error reading register value” #5
Draiget, в linux на 64 битной системе long 8 байтный. В linux x86 и в Windows x86/x64 он 4 байта.
C++
1
f_hStream.read( reinterpret_cast< char* >( &size ), sizeof( size ));
Цитата Сообщение от stima Посмотреть сообщение
size_t rb = f_hStream.read(&buf.c_str(), buf.size())
Что по Вашему возвращает std::string::c_str() ? И как вы туда собираетесь писать что то?

Добавлено через 1 минуту
Draiget, хотя, если Вы уверены, что размер хранится в 8 байтах, то используйте long long. Он везде 64 битный.
Draiget
 Аватар для Draiget
0 / 0 / 0
Регистрация: 02.05.2013
Сообщений: 31
Завершенные тесты: 2
25.09.2014, 16:20  [ТС]     Отладка: _free_base “Error reading register value” #6
Цитата Сообщение от stima Посмотреть сообщение
C++
1
2
3
string buf(size, 0);
* * size_t rb = f_hStream.read(&buf.c_str(), buf.size());
assert(rb == buf.size());
fstream::read не возвращает size_t, только std::basic_istream, ну и писать в &buf.c_str() невозможно, если только так:
C++
1
2
3
4
string buff(size, 0);
f_hStream.read(&buff[0], buff.size());
if ( buff.length() == 0 ) break;
string dec = zCrypto::decrypt( buff );
Но ошибка все равно есть, и если детальней смотреть она на return str_out; в функции дешифровки.
п.с. Поправил размер до 4х, думаю больше даже и не понадобиться, шарп пишет 8 байт при конверте ulong, поменял там на int32 и нормально стало.

Небольшое дополнение, вторая ошибка которая была на
C++
1
vector<string> header = split(dec, ';');
на самом деле возникает в конце условия:
C++
1
2
3
4
5
6
...
if (size > 0){
...
f_hStream.seekp(dataLen, ios_base::cur);
} else { //Вот тут, и один раз
...
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
25.09.2014, 16:37     Отладка: _free_base “Error reading register value” #7
Цитата Сообщение от Draiget Посмотреть сообщение
return str_out.data();
Во-первых:
std::string::data() возвращает указатель на внутренне представление строки в виде C-массива. Он действителен до тех пор, пока Вы не изменили строку.

Во-вторых ( вытекает из первого ):
После возвращения из функции decrypt объект str_out разрушается, следовательно указатель, который возвращает std::string::data() невалиден.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
std::string zCrypto::decrypt(const std::string& str_in) {
    const string key = zCrypto::from_base64("<base_64line_here>");
    const string iv = zCrypto::from_base64("<base_64line_here>");
 
    std::string str_out;
    CryptoPP::CBC_Mode<CryptoPP::Rijndael>::Decryption decryption((byte*)key.c_str(), key.length(), (byte*)iv.c_str());
 
    CryptoPP::StringSource encryptor(str_in, true,
        new CryptoPP::StreamTransformationFilter(decryption,
            new CryptoPP::StringSink(str_out)
        )
    );
 
    return str_out;
}
Добавлено через 9 минут
И еще - в C++98 не гарантируется, что последовательность, на которую указывает возвращаемый функцией std::string::data() указатель, будет заканчиваться символом конца строки ( '\0' ). Функция std::string::c_str() же это гарантирует. В С++11 std::string::data() и std::string::c_str() являются синонимами и возвращают одно и то же значение.
Draiget
 Аватар для Draiget
0 / 0 / 0
Регистрация: 02.05.2013
Сообщений: 31
Завершенные тесты: 2
25.09.2014, 16:40  [ТС]     Отладка: _free_base “Error reading register value” #8
Извиняюсь, засунул старый код дешифровки в первый пост, я закоментил строки от старого и в аргументах был только const std::string& str_in, в качестве возвращаемое значения был std::string.

А если таким образом? Сие работает, но ошибки не пропали.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...
string dec = string();
zCrypto::decrypt( dec, buff );
...
 
void zCrypto::decrypt(std::string& str_out, const std::string& str_in) { 
    const string key = zCrypto::from_base64("<base_64_line>");
    const string iv = zCrypto::from_base64("<base_64_line>");
 
    //std::string str_out;
    CryptoPP::CBC_Mode<CryptoPP::Rijndael>::Decryption decryption((byte*)key.c_str(), key.length(), (byte*)iv.c_str());
 
    CryptoPP::StringSource decryptor(str_in, true,
        new CryptoPP::StreamTransformationFilter(decryption,
            new CryptoPP::StringSink(str_out)
        )
    );
    
    //return str_out;
}
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
25.09.2014, 16:56     Отладка: _free_base “Error reading register value” #9
Ну раз с этим разобрались, тогда продолжаем. Что происходит в конструкторе Decryption?
Меня сильно смущает вот эта запись:
C++
1
CryptoPP::CBC_Mode<CryptoPP::Rijndael>::Decryption decryption((byte*)key.c_str(), key.length(), (byte*)iv.c_str());
И полный текст ошибок был бы кстати.

Добавлено через 10 минут
Непонятно, почему Вы используете std::string, когда в документации к Crypto++ везде используется собственный тип byte и SecByteBlock. Думаю, Вам нужно использовать именно их. Посмотрите пример вот здесь:
http://www.cryptopp.com/wiki/CBC_Mode
Draiget
 Аватар для Draiget
0 / 0 / 0
Регистрация: 02.05.2013
Сообщений: 31
Завершенные тесты: 2
25.09.2014, 17:12  [ТС]     Отладка: _free_base “Error reading register value” #10
Цитата Сообщение от Toshkarik Посмотреть сообщение
И полный текст ошибок был бы кстати.
pBlock - Variable is optimized away and not available.
retval - Error reading register value.

Немного скриншотов прилагается.

Цитата Сообщение от Toshkarik Посмотреть сообщение
Что происходит в конструкторе Decryption?
Хм, поменял на следующий код и ошибки на этом месте пропали, осталась только ошибка на } else { в главном коде
C++
1
2
3
4
5
6
    ...
byte key[] = { ... };
byte iv[] = { ... };
 
CryptoPP::CBC_Mode<CryptoPP::Rijndael>::Decryption decryption(key, 32, iv)
...
Миниатюры
Отладка: _free_base “Error reading register value”   Отладка: _free_base “Error reading register value”  
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
25.09.2014, 17:28     Отладка: _free_base “Error reading register value” #11
Draiget, на этом месте заканчивается блок, следовательно, объекты начинают уничтожаться, вызываются их деструкторы. Ошибка в одном из них.

Вы привели ошибки отладчика, он Вам говорит, что переменная pBlock не доступна, так как была убрана при оптимизации. Отлаживайте Debug версию. Вы, по всей видимости, пробуете отлаживать Release версию.

Я ранее не знаком был с данной библиотекой, и узнал о ней только в этой теме, поэтому не могу точно сказать, в чем проблема. Но, скорей всего, как и в функции decrypt, проблема в неправильном использовании типов/объектов.
Draiget
 Аватар для Draiget
0 / 0 / 0
Регистрация: 02.05.2013
Сообщений: 31
Завершенные тесты: 2
25.09.2014, 17:37  [ТС]     Отладка: _free_base “Error reading register value” #12
Цитата Сообщение от Toshkarik Посмотреть сообщение
Вы, по всей видимости, пробуете отлаживать Release версию.
Угу, ибо я компилил Crypto++ под релизную, а под дебагом он не компилиться:
error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in DLLMain.obj
error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MT_StaticRelease' doesn't match value 'MTd_StaticDebug' in DLLMain.obj
Попробую посмотреть что там криво удаляется.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
25.09.2014, 17:43     Отладка: _free_base “Error reading register value” #13
Вот отсюда:
This problem arises in newer versions of Visual C++ (the older versions usually just silently linked the program and it would crash and burn at run time.) It means that some of the libraries you are linking with your program (or even some of the source files inside your program itself) are using different versions of the CRT (the C RunTime library.)

To correct this error, you need to go into your Project Properties (and/or those of the libraries you are using,) then into C/C++, then Code Generation, and check the value of Runtime Library; this should be exactly the same for all the files and libraries you are linking together. (The rules are a little more relaxed for linking with DLLs, but I'm not going to go into the "why" and into more details here.)

There are currently four options for this setting:

Multithreaded Debug
Multithreaded Debug DLL
Multithreaded Release
Multithreaded Release DLL
Your particular problem seems to stem from you linking a library built with "Multithreaded Debug" (i.e. static multithreaded debug CRT) against a program that is being built using the "Multithreaded Debug DLL" setting (i.e. dynamic multithreaded debug CRT.) You should change this setting either in the library, or in your program. For now, I suggest changing this in your program.

Note that since Visual Studio projects use different sets of project settings for debug and release builds (and 32/64-bit builds) you should make sure the settings match in all of these project configurations.
Draiget
 Аватар для Draiget
0 / 0 / 0
Регистрация: 02.05.2013
Сообщений: 31
Завершенные тесты: 2
25.09.2014, 18:02  [ТС]     Отладка: _free_base “Error reading register value” #14
Я примерно помню как под дебаг компилить, немого поковырявшись сделал, теперь ошибка немного яснее, вы были правы насчет удаления:

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
void operator delete(
        void *pUserData
        )
{
        _CrtMemBlockHeader * pHead;
 
        RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
 
        if (pUserData == NULL)
            return;
 
        _mlock(_HEAP_LOCK);  /* block other threads */
        __TRY
 
            /* get a pointer to memory block header */
            pHead = pHdr(pUserData);
 
             /* verify block type */
            _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)); //Ошибка здесь <<<
 
            _free_dbg( pUserData, pHead->nBlockUse );
 
        __FINALLY
            _munlock(_HEAP_LOCK);  /* release other threads */
        __END_TRY_FINALLY
 
        return;
}
 
#endif  /* _DEBUG */
Миниатюры
Отладка: _free_base “Error reading register value”  
Draiget
 Аватар для Draiget
0 / 0 / 0
Регистрация: 02.05.2013
Сообщений: 31
Завершенные тесты: 2
25.09.2014, 18:14  [ТС]     Отладка: _free_base “Error reading register value” #15
Нашел я на каком месте он высирает ошибку, при удалении dec, проверял через delete &dec;

C++
1
2
3
4
5
6
7
string dec = string();
zCrypto::decrypt( dec, buff );
printf( "Header >> %s\n", dec.c_str() );
vector<string> header = split(dec, ';');
...
} else {
...
p.s. Сори за дабл, посты не редактирует старые.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
25.09.2014, 18:16     Отладка: _free_base “Error reading register value” #16
Цитата Сообщение от Draiget Посмотреть сообщение
delete &dec
Так нельзя делать. Это автоматический объект, он был создан на стеке, он сам освободить занятые ресурсы в деструкторе, после чего будет удален. Ошибка в том, что где то вызывается delete для объекта, который не был создал функцией new.
Draiget
 Аватар для Draiget
0 / 0 / 0
Регистрация: 02.05.2013
Сообщений: 31
Завершенные тесты: 2
25.09.2014, 18:22  [ТС]     Отладка: _free_base “Error reading register value” #17
Цитата Сообщение от Toshkarik Посмотреть сообщение
Так нельзя делать.
А если так? Ошибка то все равно на delete идет, еще до } else {. Но меня больше интересует, почему она там вообще возникает.
C++
1
2
3
string * dec = new string();
...
delete dec;
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
25.09.2014, 18:25     Отладка: _free_base “Error reading register value” #18
Я не смогу сказать без всего кода. Выложите его, будем разбираться. Как минимум, нужен весь блок
C++
1
2
3
if ( size > 0 ) {
   ...
}
Draiget
 Аватар для Draiget
0 / 0 / 0
Регистрация: 02.05.2013
Сообщений: 31
Завершенные тесты: 2
25.09.2014, 18:32  [ТС]     Отладка: _free_base “Error reading register value” #19
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...
if (size > 0){
    string buff(size, 0);
    f_hStream.read(&buff[0], buff.size());
 
    if ( buff.length() == 0 ) break;
                
    string * dec = new string();
    zCrypto::decrypt( *dec, buff );
    printf( "Header >> %s\n", (*dec).c_str() );
    vector<string> header = split(*dec, ';');
                
    //delete dec;
    unsigned long dataLen = atol(header[1].data());
    f_hStream.seekp(dataLen, ios_base::cur);
                
} else {
    break;
}
...
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.09.2014, 18:47     Отладка: _free_base “Error reading register value”
Еще ссылки по теме:

C++ Про спецификатор Register
access violation reading location C++
Access violation reading location C++

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

Или воспользуйтесь поиском по форуму:
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
25.09.2014, 18:47     Отладка: _free_base “Error reading register value” #20
Цитата Сообщение от Draiget Посмотреть сообщение
string buff(size, 0);
* * f_hStream.read(&buff[0], buff.size());
Вот так делать нельзя.

И вот это не имеет смысла:
C++
1
if ( buff.length() == 0 ) break;
C++
1
2
3
4
5
6
7
8
char buff[ size ] = { };
f_hStream.read( buff, size );
 
if ( f_hStream.gcount() == 0 ) break;
 
string dec;
 
zCrypto::decrypt( dec, string( buff ));
Yandex
Объявления
25.09.2014, 18:47     Отладка: _free_base “Error reading register value”
Ответ Создать тему
Опции темы

Текущее время: 10:48. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru