Получение ошибок нарушения доступа в разных частях кода - PullRequest
0 голосов
/ 27 ноября 2011

Я получаю эти нарушения произвольного доступа в нашем приложении win32 и совершенно не знаю, что может быть причиной этого.Я мог бы разместить код, но он находится в разных частях и будет слишком длинным.Тем не менее, я думаю, что знаю, в чем может быть проблема:

По сути, у нас есть wndproc:

LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
    static ProgramParams params;

    switch(msg) {
        case WM_CREATE:
            params.hwnd = hwnd;
            params.connected = TRUE;
            //more params assignment here
            return 0;

        case WM_RUNTHREADS:
            _beginthread(Func1, 0, &params);
            _beginthread(Func2, 0, &params);
            return 0;

        case WM_DISCONNECT:
            params.connected = FALSE;
            return 0;

// lot more code
}

В Func1 и Func2 интенсивно используется указатель на params.Под интенсивно я имею в виду множественные назначения и операторы if.Я не уверен, что это плохая идея, но у меня есть ощущение, что такое использование вызывает проблемы.Это как глобальная переменная, которая связывает все потоки вместе.

Вот также некоторые выдержки из разборки:

Необработанное исключение в 0x77c815ee в dc final v2.exe: 0xC0000005: нарушение доступа.

    return TRUE;
001E3AE5  mov         eax,1  
}
001E3AEA  push        edx  
001E3AEB  mov         ecx,ebp  
001E3AED  push        eax  
001E3AEE  lea         edx,[ (1E3B10h)]  
001E3AF4  call        @ILT+220(@_RTC_CheckStackVars@8) (1E10E1h)  
----> 001E3AF9  pop         eax  //green arrow (after clicking "break") pointing here
001E3AFA  pop         edx  
001E3AFB  pop         edi  
001E3AFC  pop         esi  
001E3AFD  pop         ebx  
001E3AFE  add         esp,0E8h  
001E3B04  cmp         ebp,esp  
001E3B06  call        @ILT+610(__RTC_CheckEsp) (1E1267h)  
001E3B0B  mov         esp,ebp  
001E3B0D  pop         ebp  
001E3B0E  ret  

Сборка вокруг адреса 0x77c815ee

77C815C3  nop  
77C815C4  mov         eax,12Eh  
77C815C9  xor         ecx,ecx  
77C815CB  lea         edx,[esp+4]  
77C815CF  call        dword ptr fs:[0C0h]  
77C815D6  add         esp,4  
77C815D9  ret         18h  
77C815DC  mov         eax,12Fh  
77C815E1  xor         ecx,ecx  
77C815E3  lea         edx,[esp+4]  
77C815E7  call        dword ptr fs:[0C0h]  
----> 77C815EE  add         esp,4 
77C815F1  ret         0Ch  
77C815F4  mov         eax,130h  
77C815F9  xor         ecx,ecx  
77C815FB  lea         edx,[esp+4]  
77C815FF  call        dword ptr fs:[0C0h]  
77C81606  add         esp,4  
77C81609  ret         18h  
77C8160C  mov         eax,131h  
77C81611  xor         ecx,ecx  
77C81613  lea         edx,[esp+4]  
77C81617  call        dword ptr fs:[0C0h]  

Включение всех исключений через Debug> Исключения приводит к:

Исключение первого шанса при 0x00000000 в dc final v2.exe: 0xC0000005: нарушение прав доступа.

SendMessage(parentHwnd, WM_TERM, (WPARAM) "ABCD", NULL);
001F1CAF  mov         esi,esp  
001F1CB1  push        0  
001F1CB3  push        465h  
001F1CB8  push        402h  
001F1CBD  mov         eax,dword ptr [pparams]  
001F1CC0  mov         ecx,dword ptr [eax]  
001F1CC2  push        ecx  
001F1CC3  call        dword ptr [__imp__SendMessageW@16 (1FE68Ch)]  
----> 001F1CC9  cmp         esi,esp //green arrow here
001F1CCB  call        @ILT+610(__RTC_CheckEsp) (1F1267h)  

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

Даже если это просто «вероятно, вызвано не назначением переменной», я буду рад это услышать, так как понятия не имею, с чего начать искать прямо сейчас.

Спасибо!

Ответы [ 2 ]

1 голос
/ 27 ноября 2011

Я заметил, что у вас есть статический ProgramParams.Это определенно вызовет проблемы, если потоки Func1 и Func2 начнут получать к нему доступ, и он записывается в основной поток.Вам нужно либо:

1) Создать две копии ProgramParams для передачи Func1 и Func2.Обратите внимание, что это должно быть в куче, а не в стеке.

2) Сделать ProgramParams поточно-ориентированным, используя критические секции.

1 голос
/ 27 ноября 2011

Если вы получаете нарушения произвольного доступа в различных частях кода, ваша куча, скорее всего, повреждена.

Эти ошибки очень сложно найти.Для начала я бы предложил загрузить средства отладки для Windows и использовать Application Verifier с включенной полной проверкой кучи.Обязательно подключите отладчик (либо Visual Studio, либо windbg), так как он вызовет исключение при повреждении кучи.

После этого единственное, что вы действительно можете сделать, это просмотреть весь код длявсе, что выглядит подозрительно.Убедитесь, что каждый указатель инициализирован, и вы не обращаетесь к каким-либо массивам или контейнерам за пределами.

Если несколько потоков выполняют параллельную запись в один и тот же общий объект, возможно, он поврежден.Попробуйте установить блокировку всех обращений к общему объекту, особенно если он имеет какие-либо указатели или данные, связанные с индексами.

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