2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2  След.
 
 ошибка в оконной программе на С++
Сообщение24.08.2019, 23:18 


07/10/15

2400
Здравствуйте уважаемые участники. Помогите найти ошибку в программе
Программа выполняет некоторые расчёты, после чего создаёт окно и выводит разные графики.
При повторном вызове функции новое окно не создаётся, а меняются только данные отрисовки (они хранятся в глобальной области), т.е. перерисовывается содержимое одного и того же окна.
Компиляция проходит нормально. Иногда всё работает правильно, но иногда (примерно 1 раз из 4-х) наблюдается непонятная ошибка - главная программа выводит сообщение об ошибке и прекращает работу. Удалось установить, что ошибка возникает в момент создания окна hwnd. Всё очень похоже на попытку доступа к недопустимой области памяти, но где именно ошибка разобраться не могу. Вот код программы:

код: [ скачать ] [ спрятать ]
Используется синтаксис C++

// глобальная область
 _int64 ni, n[32];              
 double nt[32*8];              
 char sx[(32+1)*4];          

LRESULT CALLBACK ChildProc(HWND, UINT, WPARAM,LPARAM);

void  MyFun(_int64* TBs)      
{
/*-
Расчёты
*/


HINSTANCE hinst;
    WNDCLASS w;
   
    HWND hwnd =FindWindow ("ChildWClass", "title");
   
    if (hwnd==0)
    {    
    hinst=GetModuleHandle(NULL);
        memset(&w, 0, sizeof(WNDCLASS));
        w.lpfnWndProc = ChildProc;
        w.hInstance = hinst;
        w.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        w.lpszClassName = "ChildWClass";
    w.hIcon = LoadIcon (hinst, 0);
        w.hCursor= NULL;
    RegisterClass(&w);
   
    hwnd=CreateWindow("ChildWClass", "title",
                                WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SIZEBOX | WS_SYSMENU | WS_BORDER | WS_VISIBLE,
                30,30,500,300, 0, NULL, hinst, NULL);
    ShowWindow(hwnd, SW_SHOWNORMAL);
    }
    InvalidateRect(hwnd, NULL, true);
}


// обработчик сообщений окна
LRESULT CALLBACK ChildProc(HWND hwnd, UINT Message,
                           WPARAM wparam, LPARAM lparam)
{
    static _int64 HWin=300, LWin=500;
   
    PAINTSTRUCT ps;
        HDC hdc;
    HBRUSH hBrush;
    HPEN hPen;
   
    /*   вычисления параметров отрисовки*/
   
        if (Message == WM_PAINT)
    {
     hdc = BeginPaint(hwnd, &ps);
                // TODO: добавьте любой код отрисовки...
       
     hPen=CreatePen(PS_SOLID,1,RGB(0,0,0)); SelectObject(hdc,hPen);
     hBrush=CreateSolidBrush(RGB(0,0,255)); SelectObject(hdc,hBrush);
       
     MoveToEx(hdc, 1, HWin-25, NULL); LineTo(hdc, LWin, HWin-25);
     MoveToEx(hdc, 15,HWin-25, NULL); LineTo(hdc, 15, HWin-20);
     TextOut(hdc, 5, HWin-20, sx, 4);
     
     for (int ii=1; ii<=ni; ii++)
     { MoveToEx(hdc,15+di*ii,HWin-25,NULL); LineTo(hdc,15+di*ii,HWin-20);
     TextOut(hdc,5+di*ii, HWin-20, sx+ii*4, 4);
     Rectangle(hdc,15+di*(ii-1),floor(HWin-25-n[ii-1]*r),14+di*ii,HWin-25);
     }
     /* и т.п. */
     
         DeleteObject(hPen);
        DeleteObject(hBrush);
        ReleaseDC(hwnd,hdc);
        //
                EndPaint(hwnd, &ps);
    }
   
    if (Message == WM_SIZE)
        {
                HWin=HIWORD(lparam);   // высота
                LWin=LOWORD(lparam);   // ширина
                InvalidateRect(hwnd, NULL, true);
        }
   
    if (Message == WM_DESTROY)
        {
                return 0;
        }
        return DefWindowProc(hwnd, Message, wparam, lparam);
}
 

 Профиль  
                  
 
 Re: ошибка в оконной программе на С++
Сообщение25.08.2019, 11:00 
Заслуженный участник


26/05/14
981
Вам будет легче помочь, если вы приведёте пример сообщения об ошибке и предоставите минимальный полный вариант программы в котором эта ошибка воспроизводится (с инструкциями по сборке). Спасибо.

 Профиль  
                  
 
 Re: ошибка в оконной программе на С++
Сообщение25.08.2019, 11:45 


09/05/16
138
Andrey_Kireew в сообщении #1411903 писал(а):
Всё очень похоже на попытку доступа к недопустимой области памяти, но где именно ошибка разобраться не могу.


Попробуйте Dr. Memory. Программа рассчитана на то, чтобы автоматически находить в других программах неправильный доступ к памяти во время их работы. Без воспроизводимого примера дать более осмысленный ответ, к сожалению, очень сложно.

 Профиль  
                  
 
 Re: ошибка в оконной программе на С++
Сообщение25.08.2019, 16:20 


07/10/15

2400
Дело в том, что это не самостоятельная программа, а функция для Matlab, воспроизвести её работу будет сложновато.
Но общий смысл такой: эта функция запускается из по работающего Matlab, находит его hInstance и создаёт с ним окно. Так как Matlab всё время работает, глобальные переменные по завершении работы функции никуда не деваются, не исчезает и само окно (но его при желании можно закрыть). Повторные вызовы функции приводят только к изменению данных отрисовки, т.е. изменяются находящиеся в окне графики.

Ошибка возникает обычно при первом запуске функции. Кода ошибки нет - Matlab просто прекращает работать, перед этим он пишет "Matlab System Error ... " в деталях ошибки можно ещё найти, что ошибка именно в этой функции. Визуальная среда С++ при компиляции там не используется, всё происходит в командной строке. Точки останова поставить нельзя. Чтобы выяснить в каком месте функции возникает ошибка я использовал printf(); и сдвигал его в низ по тексту, до тех пор, пока сообщение не перестало выводится на экран. Оказалось, что ошибка возникает в CreateWindow(), из неё программа уже не выходит (происходит это не всегда, и непонятно по каким причинам).
Может я неправильно заполнил структуру WNDCLASS w; или может как то изменить параметры CreateWindow()?

К стати, до этого обнаружил такой нюанс: не всегда работает функция UpdateWindow() из-за этого у меня иногда не перерисовывалось содержимое окна. Проблема решена с помощью InvalidateRect(). Тем не менее, возможно, всё это как то связано. Читал, что UpdateWindow() не посылает WM_PAINT если область обновления окна пуста. Но как и на что это влияет, честно говоря не понимаю

 Профиль  
                  
 
 Re: ошибка в оконной программе на С++
Сообщение25.08.2019, 16:40 


14/01/11
2916
А написать самостоятельную программку с такой же функцией создания окна пробовали?

 Профиль  
                  
 
 Re: ошибка в оконной программе на С++
Сообщение25.08.2019, 17:39 
Заслуженный участник
Аватара пользователя


01/09/13
4318
Andrey_Kireew в сообщении #1411970 писал(а):
это не самостоятельная программа, а функция для Matlab

А MatLab разрешает так издеваться над собой??...
Помнится, (по крайней мере раньше) даже файл нельзя открывать "стандартными" функциями...

 Профиль  
                  
 
 Re: ошибка в оконной программе на С++
Сообщение25.08.2019, 17:42 


09/05/16
138
Andrey_Kireew в сообщении #1411970 писал(а):
Дело в том, что это не самостоятельная программа, а функция для Matlab

Попробуйте официальную инструкцию по отладке MEX на Windows.
Если не поможет, попробуйте запустить из-под Dr.Memory сам Matlab: drmemory.exe -- c:/path/to/matlab.exe. Всё будет тормозить, а лог будет заполнен ошибками в самом матлабе и его сторонних компонентах, но добраться до ошибки в функции для Matlab будет возможно.

 Профиль  
                  
 
 DLL
Сообщение25.08.2019, 18:19 
Аватара пользователя


10/10/18
739
At Home
Возможно, DLL с функцией (и оконной процедурой) выгружается слишком рано. А так как окно остаётся, то оконная процедура вызывается "в никуда".

Если необходимо поддерживать окно в контексте процесса, то нужен свой поток, где будет всё делаться (и оконная процедура крутиться).

 Профиль  
                  
 
 Re: ошибка в оконной программе на С++
Сообщение25.08.2019, 20:08 


07/10/15

2400
Sender в сообщении #1411974 писал(а):
А написать самостоятельную программку с такой же функцией создания окна пробовали?

Если Вы имеете ввиду WinMain() с бесконечным циклом, то особого смысла это делать не вижу. Работать то оно, скорее всего, будет, но это будет уже совсем не то. Думаю многим понятно, что в таком виде как сейчас, эту функцию будет очень просто подключить и к любой другой программе.

SergeCpp в сообщении #1411986 писал(а):
Возможно, DLL с функцией (и оконной процедурой) выгружается слишком рано. А так как окно остаётся, то оконная процедура вызывается "в никуда".

Я бы с этим согласился, но наверное дело не в этом, ведь ошибка возникает как раз когда окно создаётся впервые.

aitap в сообщении #1411982 писал(а):
Попробуйте официальную инструкцию по отладке MEX на Windows.

Спасибо! сейчас попробую разобраться

 Профиль  
                  
 
 Re: ошибка в оконной программе на С++
Сообщение25.08.2019, 22:36 


07/10/15

2400
Спасибо aitap! сделал всё по инструкции, теперь программу можно отлаживать через Deduger VC++2010

пока обнаружил необработанное исключение 0xC000041D в Matlab.exe,
после остановки процесса в VC++2010 прекратил работу и сам Matlab, выдав сообщение об ошибке

 Профиль  
                  
 
 Re: ошибка в оконной программе на С++
Сообщение26.08.2019, 00:03 


07/10/15

2400
Опять та же ошибка. Сначала пишет
Цитата:
Первый этап обработки исключения в "0x000007fdbd0e2d90" в "MATLAB.exe": 0xC0000005: Нарушение прав доступа к "0x000007fdbd0e2d90".

а потом всю дорогу идут вот такие сообщения
Цитата:
Необработанное исключение в "0x000007fdbd0e2d90" в "MATLAB.exe": 0xC000041D: Во время обратного вызова пользователя обнаружено необработанное исключение

видимо проблема в этом месте. Можно ли это как то исправить?

 Профиль  
                  
 
 Re: ошибка в оконной программе на С++
Сообщение26.08.2019, 10:08 
Заслуженный участник
Аватара пользователя


01/08/06
3049
Уфа
Возможно, CreateWindow не возвращается, пока не вызовет оконную функцию с какими-нибудь сообщениями. По крайней мере, в документации написано, что WM_CREATE посылается до того, как CreateWindow вернёт управление. Возможно, ещё что-то посылается. Так что есть смысл покрыть printf'ами и внутренности ChildProc. Ну и я бы на всякий случай проверил, что CALLBACK разворачивается во что-то, содержащее __stdcall вру, какой stdcall, 64 бита же.

 Профиль  
                  
 
 Re: ошибка в оконной программе на С++
Сообщение26.08.2019, 13:35 


09/05/16
138
Andrey_Kireew в сообщении #1412025 писал(а):
Первый этап обработки исключения в "0x000007fdbd0e2d90" в "MATLAB.exe": 0xC0000005: Нарушение прав доступа к "0x000007fdbd0e2d90".

Инструкция почему-то предлагает отключить обработку нарушения прав доступа:
Цитата:
Do not enable "Access Violation" for handling exceptions when debugging MEX files. To avoid breaking at this exception, clear the check box for Win32 Exceptions. For Visual Studio 2015, look for the check box in Debug > Windows > Exception Settings...

но в нашем случае отловить нужно именно его (т.е. временно включить остановку при первом access violation). Тогда отладчик сможет показать цепочку вызовов функций (stack trace), которая привела к падению. Есть ли среди них код из MEX-файла, или весь поток принадлежит Matlab'у целиком? Если код из MEX-файла есть, какой именно вызов функции приводит к падению? Откуда взялся указатель 0x000007fdbd0e2d90, есть ли он среди переменных MEX-файла?

 Профиль  
                  
 
 Re: ошибка в оконной программе на С++
Сообщение26.08.2019, 17:19 


07/10/15

2400
aitap в сообщении #1412105 писал(а):
Откуда взялся указатель 0x000007fdbd0e2d90, есть ли он среди переменных MEX-файла?


включить остановку при первом access violation у меня не получилось, но я поставил точку останова в CALLBACK ChildProc() и просматривал переменные по ходу работы. Оказалось, что все видимые функции MEX-файла размещаются по адресам 0x000007fdb ...
Скорее всего, вызов одной из них и приводит к ошибке, но какой именно - непонятно

 Профиль  
                  
 
 Re: ошибка в оконной программе на С++
Сообщение26.08.2019, 19:57 
Заслуженный участник


27/04/09
28128
Потому-то наверно Sender и предлагал написать этот код и скомпилировать как отдельную единицу. Там можно будет обойти все ограничения, которые накладывает Matlab. И может быть ошибка останется и сможет быть выловлена более просто. Конечно, она может быть вызвана именно нюансами взаимодействия с матлабом, но почему бы не попробовать?

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 30 ]  На страницу 1, 2  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


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

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group