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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Draiget
1 / 1 / 0
Регистрация: 02.05.2013
Сообщений: 31
Завершенные тесты: 2
#1

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

24.09.2014, 23:12. Просмотров 1116. Ответов 25
Метки нет (Все метки)

Доброго времени суток, имеется сей код:

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” (C++):

underflow error reading the file - C++
Программа вываливается с ошибкой: Вот код Как я понял, эта ошибка появляется когда слишком часто выполнятся функция f_read(), но...

Про спецификатор Register - C++
Решил испытать register. Есть 2 кода: #include &lt;iostream&gt; #include &lt;ctime&gt; int main() { time_t timer; ...

Ключевое слово register - C++
локальная переменная которая задается : register int a; так же будет локальной и сохраняется в регистр если есть свободное место. но...

Problems reading data - C++
Написал такой код: #include&lt;iostream&gt; #include&lt;vector&gt; using namespace std; int main(){ int xa,ya,xb,yb,ob; ...

Спецификатор автоматического класса памяти, register - C++
Прочитал: Register. Ещё один спецификатор автоматического класса памяти. Применяется к объектам, по умолчанию располагаемым в локальной...

Переменная в register, операция >>, во что компилится? - C++
Если объявлена переменная register unsigned int i=100; и затем мне надо выполнять операцию &gt;&gt;1 (деление на 2), в цикле, дак вот,...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
stima
463 / 312 / 26
Регистрация: 22.03.2011
Сообщений: 1,021
Завершенные тесты: 2
25.09.2014, 00:25 #2
1. Вы уверены, что читаете правильно стартовые байты? Вы читаете 1 байт в переменную размером 4 байта. Это не смертельно, но не совсем стыковка логики.
2. Вы уверены что size >= 126? Я думаю ошибка в этом. Вы просто трете стек.
3. Зачем Вам zCrypto::from_base64 на буфер?
4. Слишком много копирования буфера. Подумайте как избежать этого.
Draiget
1 / 1 / 0
Регистрация: 02.05.2013
Сообщений: 31
Завершенные тесты: 2
25.09.2014, 12:01  [ТС] #3
1. Разве у нас unsigned long не 8, или вы о другом?
2. Тут я пытался задавать буфер так-же по size, но разницы никакой, размер там около 44+- везде, думаю не в этом проблема.
3. Попробую без него сделать.
stima
463 / 312 / 26
Регистрация: 22.03.2011
Сообщений: 1,021
Завершенные тесты: 2
25.09.2014, 13:04 #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
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
25.09.2014, 14:46 #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
1 / 1 / 0
Регистрация: 02.05.2013
Сообщений: 31
Завершенные тесты: 2
25.09.2014, 16:20  [ТС] #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
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
25.09.2014, 16:37 #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
1 / 1 / 0
Регистрация: 02.05.2013
Сообщений: 31
Завершенные тесты: 2
25.09.2014, 16:40  [ТС] #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
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
25.09.2014, 16:56 #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
1 / 1 / 0
Регистрация: 02.05.2013
Сообщений: 31
Завершенные тесты: 2
25.09.2014, 17:12  [ТС] #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
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
25.09.2014, 17:28 #11
Draiget, на этом месте заканчивается блок, следовательно, объекты начинают уничтожаться, вызываются их деструкторы. Ошибка в одном из них.

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

Я ранее не знаком был с данной библиотекой, и узнал о ней только в этой теме, поэтому не могу точно сказать, в чем проблема. Но, скорей всего, как и в функции decrypt, проблема в неправильном использовании типов/объектов.
Draiget
1 / 1 / 0
Регистрация: 02.05.2013
Сообщений: 31
Завершенные тесты: 2
25.09.2014, 17:37  [ТС] #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
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
25.09.2014, 17:43 #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
1 / 1 / 0
Регистрация: 02.05.2013
Сообщений: 31
Завершенные тесты: 2
25.09.2014, 18:02  [ТС] #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
1 / 1 / 0
Регистрация: 02.05.2013
Сообщений: 31
Завершенные тесты: 2
25.09.2014, 18:14  [ТС] #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. Сори за дабл, посты не редактирует старые.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.09.2014, 18:14
Привет! Вот еще темы с ответами:

Access violation reading location - C++
Помогите пожалуйста! Создаю программу, которая ведет учет данных. В бинарный dat-файл записываются объекты класса (Account) -...

access violation reading location - C++
access violation reading location такая проблема если вести информацию про двух и больше студентов помогите пожалуйста очень срочно надо ...

Access violation reading location - C++
Уважаемые знатоки, подскажите пожалуйста в чем проблема или хотя бы типовые причины возникновения, данного исключения (см. заголовок). На...

Дает ли register прирост в скорости? И есть ли толк в inline? - C++
Всем привет Читал про типы данных и набрел на такую переменную как register. Написано что если ее объявить в программе то, она...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
25.09.2014, 18:14
Ответ Создать тему
Опции темы

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