Ошибка проверки времени выполнения # 2 C / C ++ - PullRequest
0 голосов
/ 01 июля 2010

Я столкнулся с проблемой в моей программе, которая несколько озадачила меня. У меня была программа, которая работала нормально (она работала нормально на VS 2010, это не я обновил до .NET, и эта ошибка начала появляться после) с программой, которая в основном c и немного c ++ (мой босс HATES объектно-ориентированный, так как он обычно включает в себя звонки в библиотеки, которые он параноидальный Microsoft перестанет поддерживать, и их также придется доставлять клиенту, если у них более старая версия, что может быть проблемой, поскольку многие из них являются государственными, и он также считает, что эти звонки вызывают ненужные накладные расходы, поэтому я должен стараться избегать этого как можно больше), затем я раскомментировал блок кода (я опубликую этот блок чуть ниже, так как он был изменен по сравнению с оригинальным, который я комментировал), чтобы начать работу над ним и получено сообщение об ошибке "Ошибка проверки времени выполнения # 2, стек вокруг" std "поврежден", где std - строка в стиле ac для wchar.

Я попытался выяснить, в чем проблема, внедрив некоторые не очень хорошие исправления, так как, если что-то сработает, я узнаю, в чем заключается настоящая проблема, и тогда у меня будет хорошая исходная точка для отладки. Сначала я попытался увеличить размер std, чтобы сделать его достаточно большим, чтобы я не помещал строку больше, чем она может обработать в нем (значения получены не более чем из 3 столбцов из списка, каждый из которых не может быть больше 80 символов), и хотя это заставляло меня реже получать ошибку, я все равно ее получал.

Таким образом, я попытался переключить стандартный вывод в этом блоке кода на msg (который был точно таким же, что и стандартный вывод в то время), чтобы посмотреть, не возникла ли msg та же ошибка (что означало бы, что он был создан этим блоком кода), но Ошибка все еще возникла вокруг стандартного.

case IDC_TXT:
                    //FileSaveBox(hwnd, L"Save as...",L"Text Files (*.txt)\0*.txt\0All Files\0*.*\0",L"*.txt",wFileName);
                    FileSaveBox(hwnd, L"Save as...",L"CSV (Coma delimited) (*.csv)\0*.csv\0All Files\0*.*\0",L"*.csv",wFileName);

                        if(wcslen(wFileName)==0) return 0;

                        fin.open(wFileName);
                        if(fin.is_open())
                            val=MessageBox(hwnd,L"This file allready exists. Do you want to overwrite it?",L"Confirm Save", MB_YESNO);
                        fin.close();

                        if (val == IDNO)
                            return 0;

                        fout.open(wFileName);
                        if(!fout.is_open()) return 0;

                        /*if ((fp = _wfopen (wFileName, L"w"))==NULL)   
                        {
                            Message("Cannot Open File");
                            return 0;
                        }*/

                        _swprintf(msg,L"Some string");
                        if(im.col3)
                            wcscat(msg,L", another string");

                        fout << msg << L"\n";

                        count = ListView_GetItemCount(hlvim);
                        for(i=0;i<count;i++) 
                        {
                                ListView_GetItemText(hlvim,i,0,msg,240);
                                wcscat(msg,L", ");
                                ListView_GetItemText(hlvim,i,1,temp,80);
                                wcscat(msg,temp);
                                if(im.col3)
                                {
                                    wcscat(msg,L", ");
                                    ListView_GetItemText(hlvim,i,2,temp,80);
                                    wcscat(msg,temp);
                                }

                                fout << msg << L"\n";

                            //fprintf(fp,"%s\n",msg);
                        }
                        //fclose(fp);
                        fout.close();
                        SetFocus(hwnd);
                        return 0;

Это заставило меня подумать, что, возможно, это была просто какая-то другая переменная, пишущая поверх канареек вокруг std, поэтому я прокомментировал это после замены всех его экземпляров на msg (за исключением тех, где это локальная переменная для функции, которая не еще не вызывался при возникновении ошибки), но это просто вызвало появление ошибки вокруг сообщения (которое фактически также отображается как локальная переменная для функции).

Затем я попытался объявить msg в куче, а не в стеке, используя static (поскольку использование new могло бы привести к тому, что мои боссы так ненавидели современный код), но это только приводило к возникновению следующей ошибки: «Необработанное исключение в 0x00300030 в HTZx86.exe : 0xC0000005: Место чтения нарушения доступа 0x00300030. " а по адресу 0x00300030 - вызов внешнего API, который я не могу контролировать.

Теперь, после того, как я сделал некоторые несвязанные изменения в других частях моего кода, я случайно получаю стековую ошибку вокруг std и msg в одно и то же время (иногда после вызова функции, а иногда и раньше), а не на согласованной основе. Я хотел бы знать, есть ли какой-нибудь хороший способ отладки этой проблемы, поскольку одни только точки останова не помогают мне, и также не является стеком вызовов (хотя я могу использовать их неправильно)?

Ниже приведены объявления переменных и единственное другое место, где они будут вызваны до вызова функции:

Объявления:

int i,j,k,count,val,ntx,nrx,IsActive, rxcount;
    BOOL callsign, map2rx, rxhit;
    double f1,f2,f3;
    WCHAR str[80];
    static WCHAR msg[240];
    WCHAR temp[80];
    static short dir;
    //FILE* fp;
    std::wofstream fout;
    std::wifstream fin;
    LV_COLUMN pcol;
    LV_ITEM pit, pit2;
    static HWND hlvtx;
    static HWND hlvrx;
    static HWND hlvim;

и другие звонки:

count = ExternalAPIFunction2t();
            for(i=0;i<count;i++)
            {
                ntx = _wtoi(ExternalAPIFunction1(i+1,_SP_NBTXCH));
                nrx = _wtoi(ExternalAPIFunction1(i+1,_SP_NBRXCH));
                IsActive = _wtoi(ExternalAPIFunction1(i+1,_SP_ISACTIVE));

                try
                {
                for(j=0;j<ntx && IsActive;j++)
                {
                    f1 = _wtof(ExternalAPIFunction1(i+1,_SP_TXCH01+j));
                    _swprintf(msg,L"%09.4f MHz",f1);

                    pit.mask = LVIF_TEXT|LVIF_PARAM;
                    pit.iItem = j;
                    pit.iSubItem = 0;
                    pit.lParam = j; 
                    wcscpy_s(msg,ExternalAPIFunction1(i+1,_SP_CALLSIGN));
                    wcscat_s(msg,L"_CH");
                    _itow(j+1,temp,80);
                    wcscat_s(msg,temp);
                    pit.pszText = msg;
                    ListView_InsertItem(hlvtx,&pit);
                    _swprintf(msg,L"%.4f",f1);
                    pit.mask = LVIF_TEXT;
                    pit.iSubItem = 1;   
                    pit.pszText = msg;
                    ListView_SetItem(hlvtx,&pit);
                    f1 = _wtof(ExternalAPIFunction1(i+1,_SP_NOMINALPOWER));
                    _swprintf(msg,L"%.1f",f1);
                    pit.iSubItem = 2;   
                    pit.pszText = msg;
                    ListView_SetItem(hlvtx,&pit);
                    _swprintf(msg,L"%f",i+1);
                    pit.iSubItem = 3;   
                    pit.pszText = msg;
                    ListView_SetItem(hlvtx,&pit);           

                }
                }catch(std::exception &e)
                {
                    MessageBox(hwnd,(wchar_t*) e.what(),L"Error", MB_OK);
                }

                for(j=0;j<nrx && IsActive;j++)
                {
                    f1 = _wtof(ExternalAPIFunction1(i+1,_SP_RXCH01+j));
                    pit.mask = LVIF_TEXT|LVIF_PARAM;
                    pit.iItem = j;
                    pit.iSubItem = 0;
                    pit.lParam = j; 
                    wcscpy(msg,ExternalAPIFunction1(i+1,_SP_CALLSIGN));
                    wcscat(msg,L"_CH");
                    _itow(j+1,temp,10);
                    wcscat(msg,temp);
                    pit.pszText = msg;
                    ListView_InsertItem(hlvrx,&pit);
                    _swprintf(msg,L"%.4f",f1);
                    pit.mask = LVIF_TEXT;
                    pit.iSubItem = 1;   
                    pit.pszText = msg;
                    ListView_SetItem(hlvrx,&pit);
                    f1 = _wtof(ExternalAPIFunction1(i+1,_SP_RXBANDWIDTH));
                    _swprintf(msg,L"%.2f",f1);
                    pit.iSubItem = 2;   
                    pit.pszText = msg;
                    ListView_SetItem(hlvrx,&pit);
                    _swprintf(msg,L"%f",i+1);
                    pit.iSubItem = 3;   
                    pit.pszText = msg;
                    ListView_SetItem(hlvrx,&pit);
                }
            }

P.S. ExternalAPIFunction1 был с нарушением доступа.

1 Ответ

1 голос
/ 01 июля 2010

Код завален бомбами замедленного действия.Это начинается с FileSaveBox, где вы передаете строковый буфер, но не сообщаете функции, как долго этот буфер.Добавьте большое количество вызовов _swprintf, wcscpy и wcscat, ни один из которых не проверяет, может ли переполниться буфер, и легко ли объясняется ошибка RTC.

Вы знаете, как использовать wcspcy_s и wcscat_s, чтобы они были согласованными.

...