Неправильный указатель visual studio
Независимо от обстоятельств код, создаваемый разработчиками программного обеспечения, далеко не всегда работает так, как задумано. В некоторых случаях все идет совершенно не по плану! В подобных ситуациях необходимо выяснить, почему так происходит. При этом вместо многочасового изучения кода в поисках ошибок гораздо проще и эффективнее будет использовать средство отладки (отладчик).
К сожалению, отладчик не является той волшебной палочкой, по мановению которой будут выявлены абсолютно все проблемы в коде. Процесс отладки подразумевает пошаговое выполнение кода в средстве отладки (например, в Visual Studio) в поисках точки, в которой вы допустили ошибку при написании программы. Таким образом, вы получите возможность проанализировать код и внести в него необходимые исправления. При этом средства отладки часто допускают внесение временных изменений, благодаря чему вы можете продолжать выполнение программы.
Эффективное использование отладчика также требует определенных навыков, которые вырабатываются только с практикой, однако умение работать с ним является основополагающим требованием к любому разработчику программного обеспечения. В этой статье мы познакомим вас с основными принципами отладки и поделимся рекомендациями о том, с чего можно начать.
Проанализируйте проблему, задавая себе правильные вопросы
Это поможет вам выяснить, в чем состоит проблема, прежде чем приступать к ее решению. Мы полагаем, что вы уже сталкивались с проблемами в коде, иначе вряд ли читали бы сейчас эту статью в поисках советов по его отладке! Итак, прежде чем начать отладку, проанализируйте проблему, которую вы пытаетесь решить:
Что именно должен был выполнить код?
Что произошло вместо этого?
Если во время выполнения приложения вы столкнулись с ошибкой или исключением, это может быть хорошим признаком! Исключение возникает в том случае, если при выполнении кода происходит непредвиденное событие (как правило, это ошибка какого-либо рода). С помощью средства отладки вы можете перейти точно к тому месту в коде, где возникло исключение, и исследовать возможные способы исправления ситуации.
Если произошло что-то еще, каковы признаки проблемы? Есть ли у вас предположения относительно того, в каком месте кода возникла проблема? Например, если код должен выводить какой-то текст, но при этом текст содержит ошибки, вы можете сделать вывод, что в этом случае используются неверные данные или код вывода текста содержит ошибки другого рода. При пошаговом выполнении кода в отладчике вы можете изучить каждое изменение переменных и точно определить, когда и каким образом были присвоены неверные значения.
Проверьте свои предположения
Прежде чем исследовать причины возникновения ошибки, проверьте предположения, на основании которых вы ожидаете тот или иной результат. Скрытые или неизвестные предположения могут помешать выявлению проблемы, даже если вы изучаете непосредственно место ее возникновения в отладчике. Перечень возможных предположений может быть достаточно большим. Чтобы проверить их, задайте себе несколько вопросов.
Используете ли вы нужный API (то есть соответствующие объект, функцию, метод или свойство)? Возможно, используемый вами API работает не так, как вы ожидаете. (После проверки вызова API в отладчике для исправления проблемы и выявления нужного API вам может потребоваться обратиться к документации.)
Правильно ли вы используете API? Даже если вы выбрали нужный API, он может использоваться неправильно.
Нет ли в вашем коде опечаток? Некоторые опечатки, например ошибки в написании имени переменной, могут быть незаметными, особенно при работе с языками, в которых не требуется объявление переменных перед их использованием.
Вносили ли вы изменения в код и могут ли они быть связаны с возникшей проблемой?
Должны ли объект или переменная содержать определенное значение (или определенный тип значения) и соответствует ли это действительности?
Известно ли назначение кода? Как правило, отладка кода, написанного другим разработчиком, дается гораздо сложнее. Если это не ваш код, возможно, для его эффективной отладки вам потребуется изучить, что он делает.
При написании кода старайтесь начинать с небольших и гарантированно работающих фрагментов! (В этом вам может помочь хороший пример кода.) В некоторых случаях для исправления большого сложного фрагмента кода можно начать с маленького сегмента, демонстрирующего основную задачу, которую требуется выполнить. Затем вы можете последовательно изменять или добавлять код в поисках точки возникновения ошибки.
Анализируя собственные предположения, вы можете сократить время, необходимое на поиск проблем в коде. Кроме того, вы можете ускорить решение самих проблем.
Используйте режим пошагового выполнения во время отладки для поиска места возникновения проблемы.
При выполнении приложения в отладчике (в так называемом режиме отладки) осуществляется активный мониторинг всего, что происходит во время работы программы. Кроме того, вы можете в любой точке приостановить работу приложения, исследовать его состояние и при необходимости перейти в режим пошагового выполнения, чтобы изучить необходимые строки кода более детально.
Чтобы перейти в режим отладки в Visual Studio, необходимо нажать клавишу F5 (также вы можете выбрать пункт меню Отладка > Начать отладку или нажать кнопку Начать отладку в панели инструментов "Отладка"). Если возникает исключение, помощник по исправлению ошибок Visual Studio направит вас к точке его появления и предоставит другую необходимую информацию. См. дополнительные сведения об обработке исключений в коде в разделе Приемы и инструменты отладки.
Если исключение не возникает, возможно, вам следует проанализировать определенные места в коде, которые могут являться источником проблемы. На этом этапе следует использовать точки останова в отладчике, благодаря которым вы сможете исследовать код более внимательно. Точки останова — это один из самых простых и важных компонентов надежной отладки. Точка останова указывает, где Visual Studio следует приостановить выполнение кода, чтобы вы могли проверить значения переменных, поведение памяти или последовательность выполнения кода.
Чтобы задать точку останова в Visual Studio, достаточно щелкнуть в левом поле рядом с интересующей вас строкой кода. Также для этого можно поместить указатель мыши в нужную строку и нажать клавишу F9.
Создание образца приложения с ошибками
Сейчас мы создадим приложение, которое содержит некоторые ошибки.
Установите Visual Studio бесплатно со страницы скачиваемых материалов Visual Studio, если еще не сделали этого.
Запустите Visual Studio.
Visual Studio создаст консольный проект и откроет его в обозревателе решений (правая область).
Этот код выводит список, содержащий название галактики, расстояние до нее, а также тип галактики. При отладке важно учитывать предназначение кода. Ниже показан формат одной строки списка, который должен выводить код.
название галактики, расстояние, тип галактики.
Запуск приложения
Нажмите клавишу F5 или кнопку Начать отладку на панели инструментов "Отладка", которая расположена над редактором кода.
По результатам запуска приложения отладчик не демонстрирует никаких исключений. Тем не менее данные, выводимые в окно консоли, не соответствуют ожиданиям. Вот, что мы должны были увидеть.
Вместо этого выводятся следующие данные.
Проанализировав выходные данные и код, мы можем сделать вывод, что в классе GType содержится тип галактики. Нам необходимо выводить на экран тип галактики (например, Spiral), а не название класса.
Отладка приложения
Во время выполнения приложения щелкните в левом поле рядом с вызовом метода Console.WriteLine , чтобы задать точку останова в этой строке кода.
В месте установки точки останова в левом поле появится красный круг.
Поскольку возникшая проблема связана с выходными данными, необходимо начать отладку с проверки кода, который выполняется перед установкой выходных данных.
Выполнение приложения приостановится в заданной точке останова. Место приостановки отладчика будет выделено желтым цветом (при этом желтая строка кода на этот момент не выполнена).
Наведите указатель мыши на переменную GalaxyType справа. После этого разверните theGalaxy.GalaxyType слева от значка гаечного ключа. Как вы можете видеть, GalaxyType содержит свойство MyGType , которому присваивается значение Spiral .
Во время отладки этого же кода установите указатель мыши в конец элемента theGalaxy.GalaxyType и измените его на theGalaxy.GalaxyType.MyGType . Несмотря на допустимость такого изменения, в редакторе кода отображается ошибка, свидетельствующая о невозможности выполнить компиляцию. (В Visual Basic этой ошибки не возникнет, и этот раздел кода будет работать)
Чтобы выполнить отладку примера кода Visual Basic, пропустите несколько следующих шагов до инструкции, по которой нужно щелкнуть Перезапустить .
Анализируя код, в котором задается тип галактики, вы можете увидеть, что свойство GalaxyType класса Galaxy задается как object вместо GType .
Измените предшествующий код на следующий.
Когда отладчик приостановит выполнение на строке Console.WriteLine , вы можете навести указатель мыши на theGalaxy.GalaxyType.MyGType и убедиться, что значение задано правильно.
Удалите точку останова, щелкнув ее кружок в левом поле (также для этого можно выбрать команду Точка останова > Удалить точку останова). После этого нажмите клавишу F5 для продолжения.
Приложение запускается и отображает выходные данные. Теперь все работает правильно, однако вы можете заметить еще одну неточность. Для галактики Small Magellanic Cloud, которая имеет тип Irregular, в консоли не выводится никакой тип.
Установите точку останова в этой строке кода перед инструкцией switch (перед инструкцией Select в Visual Basic).
Здесь задается тип галактики, поэтому нам необходимо изучить эту строку более пристально.
Отладчик приостановит работу в строке кода, где вы задали точку останова.
Наведите указатель мыши на переменную type . Отображается значение S (после кода символа). Вас интересует значение I , поскольку эта галактика должна иметь тип Irregular.
Нажмите клавишу F5 и снова наведите указатель мыши на переменную type . Повторяйте этот шаг, пока в переменной type не появится значение I .
Нажмите клавишу F11 (выберите Отладка > Шаг с заходом или нажмите кнопку Шаг с заходом в панели инструментов "Отладка").
При нажатии клавиши F11 отладчик переходит на одну инструкцию вперед и выполняет соответствующий код. Клавиша F10 (Шаг с обходом) имеет схожую функцию и также полезна при работе с отладчиком.
Нажимайте клавишу F11 до тех пор, пока вы не остановитесь в строке кода с инструкцией switch для значения "I" (инструкция Select для Visual Basic). Здесь вы увидите очевидную ошибку, связанную с опечаткой. Вы ожидали, что код будет выполнен дальше до места, где для MyGType задается тип галактики Irregular, однако вместо этого отладчик полностью пропускает этот код и приостанавливает работу в разделе default инструкции switch (инструкция Else для Visual Basic).
Взглянув на код, вы заметите опечатку в инструкции case 'l' . Вместо этого она должна иметь вид case 'I' .
Щелкните код case 'l' и замените его на case 'I' .
Удалите точку останова и нажмите кнопку Перезапустить, чтобы запустить приложение снова.
Теперь все ошибки исправлены и приложение выдает ожидаемые результаты.
Нажмите любую клавишу, чтобы завершить работу приложения.
Сводка
Если вы сталкиваетесь с проблемой, воспользуйтесь отладчиком и командами пошагового выполнения, такими как F10 и F11, для поиска области кода, в которой возникают ошибки.
Выявив проблемную область кода, используйте отладчик для ее детального анализа. Чтобы определить причину возникновения проблемы, проверьте код во время выполнения приложения в отладчике.
Проверьте переменные и убедитесь, что они содержат значения того типа, который вы ожидаете. Если переменная содержит недопустимое значение, найдите, где оно было задано. Для этого может потребоваться перезапустить отладчик, проверить стек вызовов или выполнить одновременно оба этих действия.
Проверьте, выполняет ли ваше приложение код, который вы ожидаете. (Так, в примере приложения должна была выполняться инструкция switch, устанавливающая тип галактики Irregular, однако нужный код был пропущен из-за опечатки.)
Отладчик представляет собой эффективное средства для выявления ошибок. Средство отладки может искать ошибки вместо вас в том случае, если ему известно предназначение кода. Для этого вы должны указать предназначение. Этого можно добиться с помощью модульных тестов.
Следующие шаги
Из этой статьи вы узнали общие принципы отладки приложений. Теперь вы можете приступить к изучению других возможностей отладчика.
В настоящее время у меня проблема с VS08. Я получил следующую (упрощенную) структуру класса:
Этот код отлично работает в режиме Release, но когда я пытаюсь запустить Debug Build, он мгновенно падает на new CDerived .
Дальнейший анализ привел меня к тому моменту, когда я смог найти катастрофу. Он разбивается на CBase :: CBase (созданный компилятором конструктор). Точнее, он сбой в 04AE46C6 mov dword ptr [eax],offset CBase:: vftable '(505C2CCh)'.
Любые подсказки? Режим выпуска в порядке, но я не могу правильно отлаживать его.
Нет, кажется, все в порядке. Моя догадка заключается в отладке, память как-то перезаписывается. Поскольку нет способа сказать только из кода, который вы опубликовали, вот что вы можете сделать.
Я предполагаю, что вы создаете объект где-то с:
или похожие. В режиме отладки установите контрольную точку памяти в точке p . Вы можете настроить его на 4 байта. Visual C++ (как и большинство компиляторов) сохранит vfptr как первую вещь в классе, поэтому эта точка останова будет отслеживать, было ли это место перезаписано. Если точка останова ударяется, прежде чем вы вызовете функцию, в которой она сработает, возникнет проблема (и стек вызовов покажет вам, почему она перезаписана).
Это может быть много причин: вы можете перекрыть некоторую память и перезаписать объект (как предложил Эрик) - версия выпуска может разрешить вызов напрямую, чтобы предотвратить накладные расходы на динамическую отправку, и это объясняет, почему это не сбой.
Также может быть, что вы вызываете delete на объекте, а версия отладки фактически обнуляет память, тогда как в версии выпуска нет. Невозможно рассказать об этом.
Necro-posting немного здесь, но есть точка, которую я хочу сделать для будущих посетителей.
Как говорили другие, это, вероятно, было проблемой с повреждением памяти или возможностью бесплатного повторного использования. Вы не должны предполагать, что это была ошибка компилятора только потому, что вы смогли устранить сбой, изменив настройки компилятора или изменив код. Если это ошибка коррупции, то, что вы, вероятно, сделали, это переместить коррупцию в какую-то память, которая не приводит к сбою вашей программы, а не в вашей текущей сборке, на вашей текущей ОС и архитектуре.
Просто дойти до того, чтобы не сбой, возможно, было достаточно для ваших непосредственных потребностей, но пока вы не научились избегать любой практики, которая заставила вас написать ошибку в первую очередь. Есть давняя пословица среди инженеров и, вероятно, справедливое число других дисциплин:
"То, что уходит само по себе, может вернуться само собой".
Это может быть одна из самых настоящих и важных пословиц в любой форме техники. Если вы не заметили, что ошибка умирает, сама по себе, вы всегда должны беспокоиться об этом. Это должно сильно вас беспокоить. Вероятно, ошибка все еще существует, ожидая ночи вашей следующей вехи, прежде чем она снова вернется.
Лучиан Григоре дал хороший совет по поиску реальной проблемы с точкой прерывания памяти.
Ошибка при попытке vs2010 запустить проект, неверный указатель
Некоторые говорят, что это причина для IntelliTrace, но мой элемент просто закрыт.
Два решения:
1) Откройте свойства проекта, выберите вкладку отладки и отметьте пункт «Включить отладку неуправляемого кода».
2) Откройте свойства проекта, выберите вкладку отладки и установите флажок «Включить хост-процесс Visual Studio».
Интеллектуальная рекомендация
Michael.W Поговорите о Hyperledger Fabric. Проблема 20 - Подробная индивидуальная сортировка узла с пятью порядками с исходным кодом для чтения.
Michael.W Поговорите о Hyperledger Fabric. Проблема 20 - Подробная индивидуальная сортировка узла с пятью порядками с исходным кодом чтения Fabric Файл исходного кода одиночного режима находится в ord.
Мяу Пасс Матрица SDUT
Мяу Пасс Матрица SDUT Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Problem Description Лянцзян получил матрицу, но эта матрица была особенно уродливой, и Лянцзян испытал отвращение. Чт.
Гессенская легкая двоичная структура удаленного вызова
Hessian - это легкая двоичная структура удаленного вызова, официальный адрес документа, в основном он включает протокол удаленного вызова Hessian, протокол сериализации Hessian, прокси-сервер клиента .
TCP Pasket и распаковка и Нетти Solutions
Основные введение TCP является ориентированным на соединение, обеспечивая высокую надежность услуг. На обоих концах (клиенты и терминалы сервера) должны иметь один или более гнезда, так что передающий.
В настоящее время я столкнулся с проблемой с VS08. Я получил следующую (упрощенную) структуру классов:
Этот код отлично работает в режиме выпуска, но когда я пытаюсь запустить отладочную сборку, он мгновенно падает на new CDerived .
Дальнейший анализ привел меня к точке, где я смог обнаружить место крушения. Он падает на CBase::CBase (конструктор, сгенерированный компилятором). Точнее, он падает на 04AE46C6 mov dword ptr [eax],offset CBase:: vftable' (505C2CCh)`.
Какие-нибудь улики? Режим выпуска в порядке, но я не могу правильно отлаживать его.
2 ответа
Странная проблема Visual Studio (TS 2008): IDE полностью зависает всякий раз, когда я переключаюсь из режима выпуска в режим отладки в конкретном проекте. Это происходит прямо во время переключения, прежде чем я попытаюсь построить или сделать что-то еще. Все началось как гром среди ясного неба.
Нет, кажется, все в порядке. Я предполагаю, что в отладке память каким-то образом перезаписывается. Поскольку невозможно определить это только по коду, который вы опубликовали, вот что вы можете сделать.
Я предполагаю, что вы создаете объект где-то с помощью:
или что-то подобное. В режиме отладки установите точку останова памяти в расположении p . Вы можете настроить его на мониторинг 4 байт. Visual C++ (как и большинство компиляторов) сохранит vfptr в качестве первой вещи в классе, поэтому эта точка останова будет отслеживать, перезаписано ли это местоположение. Если точка останова будет достигнута до того, как вы вызовете функцию, в которой она выйдет из строя, это ваша проблема (и стек вызовов покажет вам, почему она перезаписана).
Это может быть вызвано множеством причин - вы можете переполнить некоторую память и перезаписать объект (как предположил Эрик) - версия выпуска может разрешить вызов напрямую, чтобы предотвратить накладные расходы на динамическую отправку, и это объяснило бы, почему он не сбой.
Также может быть так, что вы вызываете delete для объекта, и отладочная версия фактически обнуляет память, в то время как версия выпуска этого не делает. По одному этому не скажешь.
Некро-постинг здесь немного, но есть один момент, который я хочу сделать для будущих посетителей.
Как уже говорили другие, это, вероятно, было повреждением памяти или проблемой свободного повторного использования. Вы не должны предполагать, что это была ошибка компилятора только потому, что вам удалось устранить сбой, изменив настройки компилятора или изменив код. Если это ошибка с повреждением, то вы, вероятно, переместили повреждение в некоторую память, которая не приведет к сбою вашей программы-во всяком случае, не в вашей текущей сборке, а в вашей текущей архитектуре OS &.
Возможно, для ваших непосредственных нужд было достаточно просто дойти до точки, когда вы не разбились, но в то же время вы не научились избегать любой практики, которая привела вас к написанию ошибки в первую очередь. Существует давняя пословица среди инженеров и, вероятно, многих других дисциплин:
"What goes away by itself can come back by itself."
Это может быть одна из самых верных и важных пословиц в любой форме инженерии. Если вы не видели, как жук умер от вашей собственной руки, вы всегда должны беспокоиться об этом. Это должно вас сильно беспокоить. Жук, вероятно, все еще там, ожидая ночи вашей следующей вехи, прежде чем он снова поднимет голову.
Лучиан Григоре дал хороший совет по поиску реальной проблемы с точкой останова памяти.
Похожие вопросы:
У меня есть приложение в app store. После обновления моего приложения оно выходит из строя сразу после запуска. (смотрите на черный экран меньше секунды, а затем как будто я нажал кнопку Домой.) Я.
С некоторых пор я столкнулся с проблемой в Visual Studio 2008, связанной с моим программным обеспечением C++. Если я установлю настройки Visual Studio в режим Release Win32, он будет работать.
Всем доброго дня. У меня есть следующий вопрос: WPF designer как в VS 2008, так и в VS 2010 вылетает с Visual Studio, когда я пытаюсь отредактировать форму UI. Более того, он выходит из строя даже.
Странная проблема Visual Studio (TS 2008): IDE полностью зависает всякий раз, когда я переключаюсь из режима выпуска в режим отладки в конкретном проекте. Это происходит прямо во время переключения.
В visual studio 2008, находясь в режиме отладки, Когда мы инициируем поток и помещаем точки останова внутри функции потока. Visual Studio не отлаживается, давая объяснение, что у меня нет кода.
Я работаю над Windows, используя Visual Studio 2008. Моя программа Cuda выходит из строя во время запуска, то есть экран становится черным, и я предполагаю, что OS убивает kernel, так как она.
Я сделал приложение с помощью google map. Я только что узнал, что есть два режима: режим отладки и режим выпуска. Я установил SHA для режима выпуска, и это действительно сработало. Но мой режим.
Читайте также: