1

У меня есть три класса, относящиеся к этой проблеме. Я реализую аппаратную службу для приложения. PAPI (Platform API) - это класс аппаратного обслуживания, который отслеживает различные аппаратные интерфейсы. Я внедрил абстрактный класс HardwareInterface и класс, который выводит его под названием HardwareWinUSB.Возврат из контекста изменений функций в NULL

Ниже приведены примеры, аналогичные тем, что я сделал. Я оставил из членов, которые не появляются иметь отношение к этому вопросу, как функции, чтобы открыть соединение USB:

class PAPI { 
    HardwareInterface *m_pHardware; 

    PAPI() { 
     m_pHardware = new HardwareWinUSB(); 
    } 

    ~PAPI() { 
     delete m_pHardware; 
    } 

    ERROR_CODE WritePacket(void* WriteBuf) 
    { 
     return m_pHardware->write(WriteBuf); 
    } 
}; 

class HardwareInterface { 
    virtual ERROR_CODE write(void* WriteBuf) = 0; 
}; 

class HardwareWinUSB : public HardwareInterface 
{ 
    ERROR_CODE write(void* Params) 
    { 
     // Some USB writing code. 
     // This had worked just fine before attempting to refactor 
     // Into this more sustainable hardware management scheme 
    { 
}; 

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

Exception thrown at 0x00000000 in <ProjectName.exe>: 0xC0000005: Access violation executing location 0x00000000 

Если я докопаться в код PAPI, я вижу странное поведение. Когда я устанавливаю точку останова в теле WritePacket, все выглядит нормально. Затем я делаю «шаг вперед» в отладчике. После возврата из вызова функции моя ссылка на «this» установлена ​​в 0x00000000.

Что происходит? Похоже, что нулевое значение было нажато на стек возврата? Кто-нибудь видел что-то подобное раньше? Я неправильно использую виртуальные методы?

редактировать После дальнейшей диссекции, я обнаружил, что я читал перед вызовом записи, и буфер, что я читал в была объявлена ​​в локальной области. Когда появились новые чтения, их вставляли в стек, разлагая его. Следующая функция, называемая write, вернется в уничтоженный стек.

+0

Что-то происходит в вашем коде где-то. Результатом общей ошибки садово-паркового разнообразия является «неопределенное поведение», из которых, безусловно, могут быть получены ваши наблюдаемые результаты. Вам просто нужно выяснить, что такое ваша ошибка. К сожалению, нет рецепта красок по номерам для выяснения и отслеживания ошибки. Если бы это было, я был бы без работы ... –

+0

Спасибо за ваш ответ, Сэм. Я понимаю, что это ошибка. Я работаю профессионально на C++ около трех лет, и мне еще предстоит увидеть проблему, в которой поврежден исходный стек. Я надеялся на подсказку от кого-то, у кого больше опыта, чем у меня, а не «твоя проблема в том, что у тебя есть проблема». – Michael

ответ

0

После дальнейшего вскрытия я обнаружил, что читаю перед вызовом write, и буфер, который я читал, был объявлен в локальной области (в функции чтения).

Когда появились новые чтения, их вталкивали в стек, разлагая его. Следующая функция, которую я вызвал, напишу, вернется в уничтоженный стек.

+0

спасибо, что поделились своим решением здесь. Если возможно, пожалуйста, отметьте свой ответ как ответ, чтобы он мог помочь другим членам сообщества. Хорошего дня:) –

1

Переполнение буфера может удалить адрес возврата в стеке. Кажется, вы читаете и пишете пакеты с указателями void и не обходите явные размеры, поэтому простая ошибка переполнения кажется весьма вероятной. У компилятора Visual Studio есть опции для добавления проверки целостности стека, чтобы обнаружить такие ошибки, но они не на 100% идеальны. Тем не менее, убедитесь, что вы включили их.

Также обратите внимание, что отладчик Visual Studio может иногда (но редко) показывать неправильное значение для this, особенно если вы пытаетесь отладить оптимизированный код. Если вы в } в конце метода, я не обязательно буду беспокоиться об отладчике, показывающем странное значение для this.

+0

Спасибо за ваш ответ, Адриан. У меня была такая же мысль, что это может быть причиной переполнения буфера.Поэтому я протестировал эту гипотезу. Для этого я заменил параметры void * на uint8_t (& Buffer) [PACKET_SIZE], где PACKET_SIZE - определенная константа. Это заставило мой код всегда передавать буферы определенного размера. К сожалению, это, похоже, ничего не изменило. Я посмотрел на точки, где я копирую и устанавливаю память, и они выглядят хорошо для меня. Есть ли другие причины, по которым вы думаете, что я могу это увидеть? – Michael

 Смежные вопросы

  • Нет связанных вопросов^_^