Страницы

Поиск по вопросам

Показаны сообщения с ярлыком отладка. Показать все сообщения
Показаны сообщения с ярлыком отладка. Показать все сообщения

суббота, 11 апреля 2020 г.

Как подключить отладчик GDB для Qt Creator 2.5.2 под виндовс?

#отладка #gdb #qtcreator #qt #cpp

                    
При отладке Qt программы ругается на отсутствие отладчика. Облазил все меню настроек,
но так и не нашел, где нужно указать путь до отладчика.


    


Ответы

Ответ 1



Нашел. См. скриншот:

понедельник, 30 марта 2020 г.

Виды отладочной информации в PE файлах

#отладка #pe


Существует несколько форматов отладочной информации. Меня интересует 4 наиболее известных:
CodeView, PDB, FPO, MISC. В сети ответов не нашёл и решил задать вопрос тут.

Верно ли, что PDB - это тот же CodeView только вынесенный в отдельный файл?
Что кроме отладочных символов может содержать файл PDB?

Что такое Frame Pointer Omission?

Поскольку любая отладочная информация в PE описывается структурой IMAGE_DEBUG_DIRECTORY,
что должно находиться в соответствующей директории отладки, если вся информация вынесена
в отдельный файл (в случае использования MISC это вроде DBG, PDB - файл PDB)? Наверное
есть какая то ссылка на этот файл?..

MISC - это какой то конкретный формат отладочных данных или просто обозначает то,
что отладочная информация вынесена в отдельный файл DBG?
    


Ответы

Ответ 1



Типы отладочной информации перечислены документации формата PE, а также в заголовочном файле winnt.h: #define IMAGE_DEBUG_TYPE_UNKNOWN 0 #define IMAGE_DEBUG_TYPE_COFF 1 #define IMAGE_DEBUG_TYPE_CODEVIEW 2 #define IMAGE_DEBUG_TYPE_FPO 3 #define IMAGE_DEBUG_TYPE_MISC 4 #define IMAGE_DEBUG_TYPE_EXCEPTION 5 #define IMAGE_DEBUG_TYPE_FIXUP 6 #define IMAGE_DEBUG_TYPE_OMAP_TO_SRC 7 #define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC 8 #define IMAGE_DEBUG_TYPE_BORLAND 9 #define IMAGE_DEBUG_TYPE_RESERVED10 10 #define IMAGE_DEBUG_TYPE_CLSID 11 #define IMAGE_DEBUG_TYPE_VC_FEATURE 12 #define IMAGE_DEBUG_TYPE_POGO 13 #define IMAGE_DEBUG_TYPE_ILTCG 14 #define IMAGE_DEBUG_TYPE_MPX 15 #define IMAGE_DEBUG_TYPE_REPRO 16 Из всего этого зоопарка наибольшее значение имеют следующие: IMAGE_DEBUG_TYPE_COFF Наиболее старый формат, предполагает встраивание отладочной информации в исполняемый файл. Поддерживает только ограниченный набор отладочной информации (соответствие строк исходников адресам в бинарнике и FPO, если оно применяется для файла). Такой тип информации использовали версии Visual C++ примерно до 2005, современные версии его не используют. IMAGE_DEBUG_TYPE_CODEVIEW Более новый формат, он допускает как встраивание информации в EXE-файл, так и вынесение в отдельный файл (.PDB). Однако в современных версиях Visual C++ отладочная информация всегда вынесена в .PDB, и Debug Directory данного формата содержит только ссылку на внешний PDB-файл. (Отдельного типа записи "PDB" в Debug Directory не существует.) IMAGE_DEBUG_TYPE_FPO Если программа компилируется без оптимизации FPO, ее стек представляет из себя связный список, в котором каждый элемент содержит указатель на следующий, так что отладчик может легко его обходить без дополнительной информации. Если же включена оптимизация FPO, указателя на следующий элемент не будет, поэтому для успешного анализа стека нужен размер данных на стеке у конкретной функции. Эта информация и включается в Debug Directory типа FPO. IMAGE_DEBUG_TYPE_MISC Ссылка на внешний файл .DBG, содержащий отладочную информацию формата COFF и/или CodeView. Файл .DBG аналогичен по структуре PE файлам, его обычно получали с помощью утилиты rebase, входящей в состав старых версий Visual Studio. Сейчас редко используется. IMAGE_DEBUG_TYPE_VC_FEATURE Некоторая служебная информация компилятора (для Visual C++ начиная с версии 2010 при сборке с параметром /GL). Для иллюстрации возьмем программу, собранную Visual C++ 2012 в отладочной конфигурации, и изучим ее Debug Directory с помощью команды dumpbin /headers: Debug Directories Time Type Size RVA Pointer -------- ------- -------- -------- -------- 5BAC500B cv 3E 000167B0 5BB0 Format: RSDS, {A11BDEB7-1F5D-4BFC-8E80-CE407A215DE8}, 39, C:\PROJECTS\CppTest\Debug\CppTest.pdb 5BAC500B feat 10 000167F0 5BF0 Counts: Pre-VC++ 11.00=7, C/C++=27, /GS=27, /sdl=0, guardN=unreported Первая строка - запись формата IMAGE_DEBUG_TYPE_CODEVIEW. RSDS - это сигнатура формата, дальше идет GUID, номер версии файла (для отслеживания изменений) и путь к файлу. Вторая строка - запись формата IMAGE_DEBUG_TYPE_VC_FEATURE. Из надписи sdl=0, например, можно сделать вывод, что параметр /sdl (дополнительные проверки безопасности) был выключен. Источники PE Format Generating debug information with Visual C++ Параметр компоновки /DEBUG Параметры компиляции /Z7, /Zi, /ZI Walking the Stack Without Symbols and With FPO (Frame Pointer Omission) The .dbg Files

воскресенье, 15 марта 2020 г.

Как создать ассерт времени компиляции(аналог static_assert) в C?

#c #компиляция #отладка


В некоторых ситуациях для облегчения обнаружения и исправления ошибок в программе
может потребоваться сделать несколько утверждений об истинности/ложности какого-то
выражения, не только во время выполнения, но и во время компиляции. 

В С++ для этого применяется static_assert. 

Примеры:

Утверждение о версии подключенной библиотеки: 

#include "SomeLibrary.h"

static_assert(SomeLibrary::Version > 2, "Старые версии SomeLibrary не поддерживаются,
используйте новые.");


Утверждение о количестве бит в unsigned int:

static_assert(sizeof(unsigned int) * CHAR_BIT == 32, "Компиляция на неподдерживаемой
платформе");


Как создавать подобные утверждения в обычном C, где есть только ассерты времени выполнения
в виде макроса из assert.h?
    


Ответы

Ответ 1



Для этого можно использовать любую ошибку компиляции, например структуры с битовыми полями отрицательного размера: #define CT_ASSERT_NULL(x) ((void *)sizeof(struct { int:-!!(x); })) #define CT_ASSERT_ZERO(x) sizeof(struct { int: -!!(x); })) #define CT_ERROR sizeof(struct { int: -1;}); Кроме того такая функция добавлена, начиная со стандарта C11 и в gcc-4.6 теперь можно делать так: _Static_assert( sizeof(int) == sizeof(long int), "Error!");

вторник, 25 февраля 2020 г.

Как узнать, откуда был инициирован callback?

#javascript #google_chrome #отладка


Есть функция, использующая внутри вызов с асинхронным callback ($.ajax или просто
window.setTimeout):



function someFuncton() {
  window.setTimeout(function() {
    debugger;
  });
}

function a() {
  someFuncton();
}

function b() {
  someFuncton();
}

b();




В отладчике хрома при этом callstack выглядит как

(anonymous function) (js:15)


Как, при остановке отладчиком на строчке debugger;, узнать, откуда был инициирован
callback - из a() или из b()? 
    


Ответы

Ответ 1



В стеке вызовов, предварительно установив галочку "Async" - асинхронные вызовы захватываются только когда установлена:

понедельник, 24 февраля 2020 г.

Visual Studio меняет поток при отладке и теряются данные

#c_sharp #visual_studio #mvc #отладка


Пишу на mvc3. Передаю данные из представления в контроллер (используя форму, методом
POST). В контроллере стоит у меня точка останова. Когда я нажимаю на кнопку "След.
шаг"(при отладке) он переходит к следующему шагу но потом сразу перескакивает обратно.
Приходится нажимать на кнопку два раза, что бы VS выполнил одну операцию. Текст который
выдает при этом VS на скринах.



    


Ответы

Ответ 1



Visual Studio отлаживает приложение целиком. Если вам в приложение пришло два запроса - они будут выполняться в двух разных потоках. Оба потока попадут на ваш breakpoint. И студия будет прыгать между ними при отладке туда-сюда. Хотите удобной пошаговой отладки - сделайте так, чтобы приходил ровно один поток (например, запишите запрос fiddler-ом, и проигрывайте его). Или, если совсем не получается избежать двух запросов, поставьте на паузу все остальные потоки в Debug / Window / Threads.

суббота, 22 февраля 2020 г.

Удаленная отладка Visual Studio 2017

#отладка #visual_studio_2017


Для отладки приложений Visual Studio 2015, развернутых на других компьютерах я пользовался
удаленным отладчиком Remote Debugger Visual Studio 2015. Сейчас, решил перейти на Visual
Studio 2017, все успешно, проекты работают и все собирается. Но вот я что-то не могу
найти удаленный отладчик для новой версии среды разработки, где искать? Данного функционала
еще нет? В самой VS2017 есть пункты Debug=>Attach to Process... но где взять сам отладчик,
для установки на сервер? 

На MSDN нашел утилиты для отладки только для 2012, 2013 и 2015 версии: Remote Debugging

Для справки, установлена: Microsoft Visual Studio 2017 Enterprise Edition
Удаленный сервер, где ранее был установлен удаленный отладчик для VS2015 и успешно
работал с ней в паре: Microsoft Windows Server 2012 
    


Ответы

Ответ 1



При установке пункт меню не был создан. Но отладчик нашелся там же, где он был у предыдущих версий - по пути C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\Remote Debugger\x64 (ну и соответственно х86-версия рядышком). Сам он есть, просто ярлык не создается. Достаточно скопировать папку x64/x86 на удаленную машину и запустить с правами администратора файл msvsmon.exe

Ответ 2



После долгих поисков на MSDN удаленного отладчика для Visual Studio 2017 нашел одну довольно-таки интересную статью: Remote Debugging, опубликованную 4 ноября 2016 года. Там есть пункт: Download and Install the Remote Tools - это именно то, что нужно. Переходим по ссылке на страницу Visual Studio Downloads, там находим пункт: Tools for Visual Studio 2017, раскрываем список и находим Remote Tools for Visual Studio 2017 и скачивает отладчик нужной версии кликнув на кнопку Download напротив пункта меню. Поиск через поисковые системы Google и Yandex результатов не дал, сумел найти только во внутреннем поиске MSDN. Надеюсь данный вопрос и ответ будут полезны другим участникам.

воскресенье, 16 февраля 2020 г.

Удаленная отладка Visual Studio 2017

#отладка #visual_studio_2017


Для отладки приложений Visual Studio 2015, развернутых на других компьютерах я пользовался
удаленным отладчиком Remote Debugger Visual Studio 2015. Сейчас, решил перейти на Visual
Studio 2017, все успешно, проекты работают и все собирается. Но вот я что-то не могу
найти удаленный отладчик для новой версии среды разработки, где искать? Данного функционала
еще нет? В самой VS2017 есть пункты Debug=>Attach to Process... но где взять сам отладчик,
для установки на сервер? 

На MSDN нашел утилиты для отладки только для 2012, 2013 и 2015 версии: Remote Debugging

Для справки, установлена: Microsoft Visual Studio 2017 Enterprise Edition
Удаленный сервер, где ранее был установлен удаленный отладчик для VS2015 и успешно
работал с ней в паре: Microsoft Windows Server 2012 
    


Ответы

Ответ 1



При установке пункт меню не был создан. Но отладчик нашелся там же, где он был у предыдущих версий - по пути C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\Remote Debugger\x64 (ну и соответственно х86-версия рядышком). Сам он есть, просто ярлык не создается. Достаточно скопировать папку x64/x86 на удаленную машину и запустить с правами администратора файл msvsmon.exe

Ответ 2



После долгих поисков на MSDN удаленного отладчика для Visual Studio 2017 нашел одну довольно-таки интересную статью: Remote Debugging, опубликованную 4 ноября 2016 года. Там есть пункт: Download and Install the Remote Tools - это именно то, что нужно. Переходим по ссылке на страницу Visual Studio Downloads, там находим пункт: Tools for Visual Studio 2017, раскрываем список и находим Remote Tools for Visual Studio 2017 и скачивает отладчик нужной версии кликнув на кнопку Download напротив пункта меню. Поиск через поисковые системы Google и Yandex результатов не дал, сумел найти только во внутреннем поиске MSDN. Надеюсь данный вопрос и ответ будут полезны другим участникам.

воскресенье, 9 февраля 2020 г.

GDB пропускает строки кода с++

#cpp #отладка #gdb


Вот программа:

#include 

int main()
{
    try
    {
        throw std::out_of_range("Huston, we have a problem");
    }
    catch(std::out_of_range obj)
    {

    }

    std::cout << "Hello world" << std::endl;

return 0;
}


Компилирую ее с помощью команды:

g++ -g -O0 main.cpp


Запускаю в gdb и пытаюсь отладить:

(gdb) break main
Breakpoint 1 at 0x100000d42: file main.cpp, line 7.
(gdb) run
Starting program: /Users/admin/repositories/oop_workspace/a.out 
[New Thread 0x1c03 of process 5743]
warning: unhandled dyld version (15)

Thread 2 hit Breakpoint 1, main () at main.cpp:7
7           throw std::out_of_range("Huston, we have a problem");
(gdb) next
Hello world
[Inferior 1 (process 5743) exited normally]
(gdb) 
The program is not being run.


Код ниже try-catch блока не отлаживается, а вместо этого просто выполняется.
В чем может быть проблема?
    


Ответы

Ответ 1



Где-то в сети я видел сообщение, что в Linux проблема (останов по stepping после С++ exception) решена, но не нашлось никого, кто перенес бы этот fix в MinGW :). Однако, оказалось что в моей Linux avp-ubu1 4.4.0-127-generic #153-Ubuntu SMP Sat May 19 10:58:46 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux, также как у вас, не работает. Остается воспользоваться советом из Debugging with GDB и ввести команду catch catch перед запуском. Вот результат: avp@avp-ubu1:hashcode$ g++ t.cpp -g avp@avp-ubu1:hashcode$ gdb ./a.out GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1 Copyright (C) 2016 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: . Find the GDB manual and other documentation resources online at: . For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ./a.out...done. (gdb) catch catch Catchpoint 1 (catch) (gdb) r Starting program: /home/avp/hashcode/a.out Catchpoint 1 (exception caught), 0x00007ffff7ae1711 in __cxa_begin_catch () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (gdb) n Single stepping until exit from function __cxa_begin_catch, which has no line number information. main () at t.cpp:14 14 std::cout << "Hello world" << std::endl; (gdb) Hello world 16 return 0; (gdb) 17 } (gdb) c Continuing. [Inferior 1 (process 11769) exited normally] (gdb) q avp@avp-ubu1:hashcode$ Как видите, все получилось. Если остановиться в начале (br main) и идти построчно (next), то тоже все нормально работает. P.S. Для останова в точке генерации exception введите команду catch throw.

Как поставить програмную точку останова

#отладка #любой_язык #faq


Как поставить програмную точку останова в разных языках средах и IDE. Часто вижу
вопросы не могу отладить программу потому что программа большая, обьёмы большие. Цикл
на 10000000. Такие ситуации можно отловить, например, при возникновении ошибки у меня
i=357489, а не понятно почему возникло исключение, тогда делаем, напимер так:

 for (i=0;i<10000000;i++) {
   if (i==357489) DebugBreak();
   // код
   }


Но DebugBreak - функция windows. Как можно поставить точки останова в других средах?
    


Ответы

Ответ 1



В с с++ есть такие варианты поставить точку останова DebugBreak(); - среда windows __builtin_trap() - среда linux raise(SIGTRAP) - работа с сигналами POSIX posix __EMIT__(0xCC) или __emit__(0xcc); - некоторые среды поддерживают вставку кода __asm { int 3;} или __asm { db 0xCC;} ассемблерная вставка Для других сред с# System.Diagnostics.Debugger.Break(); javascript debugger; java try {throw new TurnOnDebuggerException();}catch(TurnOnDebugger td) {/*Nothing*/ } pascal inline($CC); vbscript visual-basic stop

пятница, 31 января 2020 г.

Python Вывод ошибки и stacktrace в консоль

#python #отладка


Доброе время суток!
Скажите пожалуйста как вывести в консоль текст ошибки и stacktrace так, как это делается
при необработанном исключении:

    Traceback (most recent call last):
  File "file", line 67, in 
    M.logoutv()
  File "file", line 260, in __getattr__
    raise AttributeError("Unknown IMAP4 command: '%s'" % attr)
AttributeError: Unknown IMAP4 command: 'logoutv'


хочу поймать в try:
обработать в except Exception as err:
    


Ответы

Ответ 1



Получить текст стека трассы можно используя traceback: import traceback try: ... except Exception as e: print('Ошибка:\n', traceback.format_exc())

Ответ 2



Следуя вашим словам, например: try: do_something() except Exception as err: print(err) do_something_else()

Как использовать отладку при запуске программы?

#c_sharp #visual_studio #отладка #visual_studio_2017


Первая программа запускает вторую. У второй меняются относительные пути на путь расположения
первой. Путь становится неверным.

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


Ответы

Ответ 1



Проще всего вот как. В подходящем месте в начале второй программы напишите if (!Debugger.IsAttached) Debugger.Launch(); Debugger.Break(); Первую программу запускайте без Visual Studio. Когда вторая программа будет запущена, появится диалог: Выберите в нём экземпляр Visual Studio для отладки и нажмите OK. Откроется отладчик Visual Studio и загрузит вашу программу.

Ответ 2



Если нужно именно отладить косвенно запускаемый процесс, а не просто приаттачить отладчик в определенный момент, или если не хочется менять код и пересобирать стороннее приложение ради остановки, то можно использовать расширение Microsoft Child Process Debugging Power Tool. Устанавливаете его в студию, включаете отладку в настройках. Ставите чекбокс Enable native code debugging в свойствах проекта: и студия начинает автоаттачить дебаггер к дочерним процессам.

воскресенье, 26 января 2020 г.

Как отменить подавление ошибок в php

#php #отладка


Доброе время суток, на работе сегодня столкнулся с такой задачей есть некая платная
CMS (если ее можно так назвать ) в которой гов... тоесть "разработчики" по 10 раз в
каждом файле ( а их больше 1000 ) установили  error_reporting none и им подобные конструкции
( во общем сделали все что бы скрыть следы своих косяков ) приложение платное код с
обфускацией, выискивать в коде все error_reporting none не реально... Скрипт падает
где то в середине из за 


  mod_fcgid: read data timeout in 300 seconds


Почему скрипт так подвисает я уже догадываюсь, не могу найти место где это происходит,
включить уровень логирование debug не дало ни каких результатов т.к. везде понапихан
error_reporting none что по уровню иерархии является приоритетнее для интерпретатора PHP 

Вопрос: что нужно сделать что бы игнорировать error_reporting и выводить всё по возможности
для отладки? Как быть? как отменить глобально подавление ошибок? какие есть способы? 

php 5.6 FreeBSD 9 apache22
    


Ответы

Ответ 1



Если есть возможность вставить дополнительно свой код в код CMS (например, дописать в какой-то файл, подключаемый всегда), то можно зарегистрировать собственный обработчик ошибок. Он будет вызываться независимо от error_reporting. Стандартно, предполагается, что в этом обработчике будет проверяться уровень ошибки и сравниваться с настройкой error_reporting, но это на усмотрение разработчика. Т.е. примерно так: function myErrorHandler($errno, $errstr, $errfile, $errline) { if (!(error_reporting() & $errno)) { // This error code is not included in error_reporting, so let it fall // through to the standard PHP error handler return false; } echo "$errstr at $errfile on line $errline\n"; } Вот этот if в функции можно не делать, а всегда показывать ошибки. А лучше не показывать, а просто писать в лог, вместе с бэктрейсом. Потом анализировать.

Ответ 2



можно с помощью ide убрать все эти error_reporting none, вернее заменить их или на что-то своё или на пустую строку в итоге они исчезнут

Ответ 3



Если есть доступ на запись к httpd.conf, то прописать в нем php_admin_value error_reporting -1

Ответ 4



Вставьте вначале файла #PHP ini_set("display_errors", 1); error_reporting(E_ALL);

четверг, 23 января 2020 г.

Как при наличии отладочных символов только своей dll получить её переменные из дампа памяти приложения?

#visual_studio #dll #отладка #dump


Есть моя DLL библиотека (проект Visual Studio 2013). Ее используют чужие программы.
Во время работы этих программ было сохранено несколько полных дампов память процессов
этих программ.
Я открываю эти дампы в моем Visual Studio проекте. Отладочные символы я имею только
для моей DLL. При этом, если во время сохранения дампа исполнялся код одной из функций
моей DLL, то видно все символы в исходном коде, место текущего исполнения итд. Но если,
исполнялся другой код, я никаких данных не вижу и посмотреть текущее значение переменных
моей DLL не могу. Локальные переменные ясное дело недоступны, так как их нет, но и
статические данные тоже не видны.  

Как просматривать данные моей DLL?
    


Ответы

Ответ 1



Не уверен, можно ли это сделать через студию. Но точно можно через WinDBG: Открыть дамп. Включить ссылки в выводе: .prefer_dml 1 Прописать путь к символам: .sympath+ srv* Загрузить SOS (пусть исправить на соответствующий версии и платформе) для 4.0: .loadby sos clr для <4.0 .loadby sos mscorwks или по полному пути .load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SOS.dll Найти EEClass для того типа, для которого хочется посмотреть статические поля > !name2ee mscorlib.dll System.Console Module: 0000064278854000 (mscorlib.dll) Token: 0x000000000200008b MethodTable: 00000642788c8d10 EEClass: 0000064278a271a8 Name: System.Console Посмотреть статические поля: > !dumpclass 0000064278a271a8 Class Name: System.Console mdToken: 000000000200008b (C:\WINDOWS\assembly\GAC_64\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll) Parent Class: 00000642788c0c30 Module: 0000064278854000 Method Table: 00000642788c8d10 Vtable Slots: 4 Total Method Slots: 78 Class Attributes: 100181 Abstract, NumInstanceFields: 0 NumStaticFields: d MT Field Offset Type VT Attr Value Name 00000642788f5aa0 40002ae d8 System.IO.TextReader 0 shared static _in Дальше перемещаться кликами по адресам объектов - в режиме DML по клику будет выполнятся соответствующая команда для дампа объекта. По настройке WinDBG есть отличный мануал Debugging Managed Code Using the Windows Debugger.

среда, 22 января 2020 г.

Какие есть способы предупреждения ошибок, их нахождения и устранения?

#отладка #любой_язык #обработка_ошибок


При разработке часто могут возникать разного рода ошибки, а у меня нет знаний о том
как и с помощью чего можно было бы их обнаруживать или упреждать. Даже мелкие ошибки.
Поэтому часто задаю вопросы в формате "Где ошибка в коде?" на разных ресурсах, вместо
того, чтобы самостоятельно всё исправить.

Так как общие инструменты и практики есть во всех языках, то хотелось бы все их узнать,
от простых до сложных. Напишите, пожалуйста, какие способы есть?

Спасибо.
    


Ответы

Ответ 1



Мой ответ будет про IDE. IDE (англ. Integrated Development Environment - Интегрированная среда разработки). Их очень много. Например часто используют: для c# — Visual Studio для javascript — WebStorm, NetBeans, Eclipse, Brackets, Sublime и т.д. для php — PHPStorm, NetBeans, Eclipse и т.д. для java — Intellij IDEA для других языков еще что-то В IDE много бесконечных возможностей, например: детектор дублируемого кода рефакторинг инструменты для работы с базами данных интеграция с системами управления версиями автодополнение кода подсветка синтаксиса подсказки при наборе кода (функции, ключевые слова, переменные, которые объявлял ранее) и многое другое Как это поможет? Среда знает, что она редактирует код и знает язык, на котором написан код. В неё встроен синтаксический анализатор языка программирования. Еще на самом первом этапе написания кода она может показать строки с банальными (и не только) ошибками, но которые уже могут привести к нерабочему или неправильно функционирующему коду. IDE показывает номер строки кода, где предположительно ошибка; краткое и полное описание ошибки, которое можно прочитать, проанализировать и исправить. Ошибки показываются как на боковой панели, так и в самом редакторе еще на этапе написания, а для компилируемых языков еще и в консоли при запуске программы. Примеры: Visual Studio Intellij IDEA WebStorm и PHPStorm Можно сразу видеть: уровень ошибки (предупреждение, уведомление, ошибка) полный текст ошибки в каком файле номер строки, на которой ошибка Можно перейти в скрипт на указанную строку и проанализировать. Не знаете английский? Откройте любой онлайн переводчик и скопируй туда текст ошибки заменив заглавные буквы на строчные: C# CS0103 The name 'getSum' does not exist in the current context ConsoleApp2017 C:\VS\ConsoleApp2017\Program.cs 6 Имя «getSum» не существует в текущем контексте ConsoleApp2017 в файле C:\VS\ConsoleApp2017\Program.cs На линии №6 Не может найти метод getSum в классе Program.cs на линии 6. Значит вызов есть, а объявления нет и искать надо в указанном направлении. Java Error:(34, 9) java: cannot find symbol symbol: method getSum() location: class test.Test Ошибка: (34, 9) java: не удается найти символ Символ: метод getSum () Местоположение: класс test.Test и так далее. Исправлять желательно все ошибки, как минимум уровня опасности "красный". warning и notice могут быть временно забыты, например сообщение о неиспользованной переменной, которую вы точно намерены потом использовать. Но в итоге надо починить их все! В IDE еще много полезных и не упомянутых возможностей. Для их использования: - определись с языком, подбери нужную IDE и изучай.

Странный баг с мусорными строками в Unity

#c_sharp #unity3d #отладка


Появился ооочень странный наполовину плавающий баг с мусорными строками.

Всю архитектуру описывать очень долго, поэтому напишу вкратце, но если будет надо,
обновлю вопрос с детальным описанием.

В кратце так:

создал систему для локализации игры. Есть класс Localization со статическими строковыми
полями только для чтения, и есть файл xml со строками. Данный клас, с помощью стандартного
XmlTextReader и рефлексии, заполняет нужные поля соответствующими значениями.

using System;
using System.Reflection;
using UnityEngine;
using System.Xml;
using System.IO;

public sealed class Localization
{
    const string PATH_TO_LOCALIZATION_FILES = @"TextAssets\Localization\";
    public static SystemLanguage CurrentLanguage { get; private set; }

    #region strings;

    static public readonly string downloading;

    static public readonly string play_game;
    static public readonly string settings;
    static public readonly string squad;

    //тут еще куча static public readonly string полей 

    #endregion;


    /// 
    /// Уставнавливает новый язык локализации, если для него есть определение.
    /// 
    /// Новый язык локализации
    /// Если язык локализации был изменен, возвратится true, иначе - false
    public static bool SetLanguage(SystemLanguage language)
    {
        SystemLanguage newLanguage;
        ReloadStrings(language, out newLanguage);

        var res = true;
        if (newLanguage == CurrentLanguage)
            res = false;
        else
            CurrentLanguage = newLanguage;

        return res;
    }

    /// 
    /// Находит в соответствующем файле локализации нужные строки и устанавливает
их значения соответствующим полям.
    /// Так как не все языки поддерживаются, то загружен будет либо указанный
язык, либо язык по умолчанию (английский)
    /// 
    /// Язык локализации для загрузки
    /// Сюда будет занесено значение загруженого языка
локализации
    static void ReloadStrings(SystemLanguage language, out SystemLanguage newLanguage)
    {
        string languageFileName = string.Empty;

        switch (language)
        {
            case SystemLanguage.Russian:
                languageFileName = "RU";
                newLanguage = SystemLanguage.Russian;
                break;
            default:
                //english
                languageFileName = "EN";
                newLanguage = SystemLanguage.English;
                break;
        }

        TextAsset localisationFile = Resources.Load(PATH_TO_LOCALIZATION_FILES
+ languageFileName);
        using (TextReader txtReader = new StringReader(localisationFile.text))
        {
            using (XmlTextReader reader = XmlReader.Create(txtReader) as XmlTextReader)
            {
                while (reader.ReadToFollowing("string"))
                {
                    reader.MoveToAttribute("name");
                    var name = reader.Value;
                    reader.MoveToContent();
                    var value = reader.ReadElementContentAsString();

                    SetString(name, value);
                }
            }
        }
    }

    /// 
    /// Устанавливает значение строкового ресурса по его имени
    /// 
    /// Имя строкового ресурса
    /// Новое значение строкового ресурса
    static void SetString(string name, string value)
    {
        var field = typeof(Localization).GetField(name, BindingFlags.Static | BindingFlags.Public);

        if (field == null)
            throw new Exception(string.Format("Поля строкового ресурса с именем \"{0}\"
не существует.", name));

        field.SetValue(null, value);
    }

    /// 
    /// Получает значение строкового ресурса по его имени
    /// 
    /// Имя строкового ресурса
    /// Значение строкового ресурса
    public static string GetString(string name)
    {
        var field = typeof(Localization).GetField(name, BindingFlags.Static | BindingFlags.Public);

        if (field == null)
            throw new Exception(string.Format("Поля строкового ресурса с именем \"{0}\"
не существует.", name));

        return field.GetValue(null) as string;
    }
}


Когда будет нужно, обращаемся к нужному полю класса и берем нужное значение. Если
же строку нужно задать не с кода, а с редактора Unity, то передаем нужное имя поля,
а в коде вызываем метод Localozation.GetString(string name).



Теперь самое интересное

При первом запуске уровня все работает нормально. Но при перезапуске уровня случается
вот такая дичь:

Запускаем отладку и видим, что с классом локализации и значениями полей все нормально:



Пропускаем шаг отладки и видим, что, на самом деле, было передано "мусорное значение"
строки.



Причем, это случается не просто при перезапуске уровня, но именно при перезапуске
уровня, если на этот предмет уже кликали перед перезапуском уровня.

Дальше больше

Если вытаскивать значение полей с помощью рефлексии, то все нормально. А если обращаться
к полям напрямую (через имя класса и имя поля), то там оказываются мусорные значения.

using System.Text;
using UnityEngine;

public class TestGarbageStrings : MonoBehaviour
{
    public void DoTestFields()
    {
        StringBuilder builder = new StringBuilder();

        builder.Append("\r\n" + Localization.downloading);

        builder.Append("\r\n" + Localization.play_game);
        builder.Append("\r\n" + Localization.settings);
        builder.Append("\r\n" + Localization.squad);

        //тут еще куча обращений к другим полям

        DialogBox.Instance
            .AddCancelButton("Ясно")
            .SetText(builder.ToString(), true)
            .SetSize(800, 600)
            .Show();
    }

    public void DoTestReflection()
    {
        StringBuilder builder = new StringBuilder();

        var fields = typeof(Localization).GetFields(System.Reflection.BindingFlags.Static
| System.Reflection.BindingFlags.Public);
        foreach (var f in fields)
        {
            builder.Append("\r\n");
            builder.Append(f.GetValue(null));
        }

        DialogBox.Instance
            .AddCancelButton("Ясно")
            .SetText(builder.ToString(), true)
            .SetSize(800, 600)
            .Show();
    }
}


Если обращаться к полям на прямую(мусорные значения):



Если брать значения с помощью рефлексии(правильные значения):



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


Ответы

Ответ 1



Модификатор readonly подразумевает, что поле не будет меняться после создания объекта (или после вызова статического конструктора). В связке со static это предположение разрешает JIT-у кэшировать значения в тех местах, где вы обращаетесь к полю. Или вообще кэшировать значения полей где-то глобально после первого обращения к ним. И даже убирать из кода if-ы, проверяющие значения полей - вобщем, JIT считает такие поля константами времени выполнения. При просмотре через отладчик вы видите реальное значение поля. При вытягивании через reflection - тоже. А реально выполняется код, в который JIT вписал константный старый адрес. Потому что вы ему это явно разрешили. Соответствующие оптимизации для static readonly были в основном CLR со времен 3.5, в Core - появились 2 года назад - Treat readonly fields as JIT time constants. В mono (не уверен, на чем сейчас Unity работает) они скорее всего тоже есть. Уберите readonly и все заработает. Скорее всего, т.к. минимального кода для воспроизведения проблемы в вопросе нет.

суббота, 11 января 2020 г.

Andoid. Debuggable приложение тормозит

#android #android_studio #отладка #сборка


Условия:

Я работаю на двух компьютерах - дома и на работе.
Я собираю одно и то же приложение с опцией debuggable=true.
Делаю я это на одном и том же девайсе.

Проблема:

При сборке на работе приложение не тормозит ни в debug buildType (будучи debuggable),
ни в release buildType.
Но стоит мне собрать его дома, как в debug buildType приложение начинает тормозить
на экранах с тяжелой версткой (множество 'ов). А если еще и в debug-режим
войти, то просто кромешный ад! При этом в release buildType все летает на тех же самых
экранах.

Вопрос:
Должны ли быть включены/выключены какие-то особые настройки Android Studio, чтобы
оптимизировать работу debuggable приложения? (вроде и на работе и дома ставил студию
одинаково, не изменяя каких-либо важных настроек). Быть может от самого компьютера
зависит скорость работы приложения на телефоне (звучит фантастически, но я уже не знаю
на что думать)
    


Ответы

Ответ 1



Подобное поведение может быть вызвано функцией Instant Run - она обновляет приложение в реальном времени при изменениях в коде в дебаг режиме. Это, надо полагать, требует постоянного обмена данными и их обработки, что нагружает и комп и девайс. Отключение оной может помочь.

пятница, 3 января 2020 г.

Средства и методы нахождения ошибок в коде их исправления. Сборник

#отладка #любой_язык #обработка_ошибок #faq


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

В вопросы, перечисленные ниже в списке МОЖНО и нужно добавлять еще ответы!

Метки пишем в алфавитном порядке. 



Люди смогут использовать его для выявления схожих проблем в различных технологиях. 

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


"Что не так в коде?"
"Где у меня ошибка?"
"Почему программа не работает?"
и подобные

    


Ответы

Ответ 1



Общие практики и советы Какие есть способы предупреждения ошибок, их нахождения и устранения? Список по языкам c# Как и какими средствами находить ошибки в коде на C#? java Как и какими средствами находить ошибки в коде Java? javascript Как и какими средствами находить ошибки в Javascript коде? php Как и какими средствами находить ошибки в PHP коде? css Что делать, если не работает css-класс

среда, 1 января 2020 г.

Как работает отладчик?

#отладка


Как технически реализованы функции остановки и дальнейшего исполнения нативной программы?
Как реализован просмотр стека, регистров и памяти?

В случае интерпретатора, понятно. Ему можно скомандовать "остановись", "покажи стек"
потому что интерпретатор отдельная программа со своим интерфейсом. А вот при нативной
отладке происходит какое-то волшебство, программа и отладчик работают на одном процессоре,
но отладчик при этом управляет другой программой и видит все ее кишки. Как работает
это волшебство?
    


Ответы

Ответ 1



В процессорах есть аппаратная поддержка отладчика. Команды останова, бит пошагового выполнения программ и прочие чудеса. Все это обычно работает на системном уровне приоритета. В старых процессорах (до 80386) бит пошагового выполнения был, а аппаратных приоритетов еще не было. Там отладчики работали в режиме пользователя. Впрочем, там и ОС работала в режиме пользователя. :-) Если конечно DOS можно назвать ОС. UPD1: Пожалуйста подробней Давно это было. Подробнее Вам надо читать описание аппаратной архитектуры процессоров. Причем поддержка отладчика теперь есть во всех более-менее уважающих себя процессорах типа ARM и прочих. В старых процессорах типа однокристаллок 51 серии от INTEL этой поддержки нет. Когда я этим занимался, то все работали под DOS и отладчики и программа работали в реальном режиме. Тогда в системе команд процессора была однобайтовая команда программного прерывания. Если пользователь ставил точку останова в программе, то отладчик модифицировал программу пользователя, записывая в начало ассемблерной последовательности (которая реализует Сишную команду) эту самую однобайтовую команду программного прерывания. Когда (и если) программа проходила через эту точку, возникало программное прерывание, которое обрабатывал отладчик. Он останавливал программу пользователя, считывал все регистры общего назначения, и другую информацию, интересную для программиста типа содержимого стека, сегментных регистров, сегментов памяти и прочего. И всю эту информацию распихивал по окнам и останавливался. Когда пользователь снимал точку останова, то отладчик восстанавливал программу пользователя, записывая вместо этой самой однобайтовой команды прерывания старую инструкцию. Также был так называемый Т-бит в регистре флагов процессора. Если в этот Т-бит записать единицу, то процессор вырабатывал Т-прерывание со своим отдельным вектором после выполнения каждой инструкции. Это Т-прерывание тоже обрабатывалось отладчиком и с его помощью можно было реализовать пошаговое выполнение программы. По этому прерыванию отладчик тоже собирал всю информацию о состоянии процессора и представлял эту информацию в удобном для человека виде в разных окнах. Как сейчас сделано я точно не знаю, но думаю что тоже что-то вроде этого. За исключением того, что теперь, конечно, отладчик работает в системном режиме процессора, а программа пользователя работает в пользовательском режиме процессора.

воскресенье, 29 декабря 2019 г.

Метод Trace.TraceInformation(string)?

#c_sharp #net #юнит_тесты #отладка #логирование


Для чего и как используется этот метод?

[TestMethod]
public void Q_GetAllCustomers_NoExc()
{
     foreach(var i in context.GetAll())
     {
          Trace.TraceInformation($"{i.FirstName} {i.LastName}")
     }
}


Куда попадёт string, который я передаю этому методу. И как это вообще связано с TDD?
    


Ответы

Ответ 1



Это встроенное средство отладки, трассировочное сообщение. У вас есть конфигурируемый через app.config (или вручную) список слушателей трассировочных сообщений. Им и доставляется полученная строка. Например, вы можете направить ваши трассировочные сообщения в файл или на консоль, положить в системный event log, отправить по сети или положить на web-страницу. В случае, если вы запускаете проект из-под Visual Studio, ваши трассировочные сообщения слушает IDE, и показывает их в окошке Debug. В случае, когда вы запускаетесь не из-под Visual Studio, трассировочные сообщения уходят системе (если вы не отконфигурировали по-другому). Вы можете их видеть при помощи, например, утилиты DebugView. С TDD не связано никак.

Ответ 2



В дополнение к ответу @VladD добавлю, что в случае с запуском теста из-под Visual Studio, вся отладочная и трассировочная информация также доступна в тест аутпуте:

Ответ 3



Куда попадёт string, который я передаю этому методу. Если компиляция проходила при включенном TRACE, то зависит от того какие TraceListener'ы подключены. Посмотреть можно так: using System.Linq; using System.Diagnostics; for(var i=0; i < Trace.Listeners.Count; i++) { Console.WriteLine(Trace.Listeners[i].GetType().Name); } при выполнении кода в C# interactive выводится DefaultTraceListener. Коллекцию Trace.Listeners можно менять, и например, если требуется выводить информацию в файл, после запуска приложения вызываем: Trace.Listeners.Add(new TextWriterTraceListener(@"c:\temp\trace.txt")); Дальше, где-бы ни находился вызов Trace.TraceInformation("test"); в файл выводит test вместе с именем процесса. Формат вывода можно настроить и выводить время, идентификатор потока и т.д.

Как находить ошибки в коде?

#javascript #отладка


Как находить ошибки в коде JavaScript?
Например, написал я скрипт, а он не работает. Если взять, например, Pascal, то там
есть трассировка: жмёшь на пробел, и код построчно выполняется. Видно когда в цикл
заходит, сколько раз там пробегается, когда из него выходит и другие вещи.
    


Ответы

Ответ 1



Моё имхо - Chrome Dev Tools это все что нужно. Ссылка. Конкретно про дебаг JS - тут

Ответ 2



Линтеры На раннем этапе, ещё до запуска приложения, очень помогают статические анализаторы кода, вот несколько из самых популярных: JSLint от дедушки Крокфорда, создателя JSON. Попахивает валерьянкой, но вполне работает, не считая того, что настроек с гулькин нос. JSHint отличный линтер с гибкими настройками, 6к звед на гитхабе. ESLint, и слитый с ним JSCS пожалуй самая крутая штука, если нужно написать свои плагины для каких то специфических проверок. Наверняка в вашу среду разработки можно их интегрировать так, чтобы они работали в фоне, и помечали найденные ошибки прямо в коде. Например для WebStorm достаточно просто поставить галку в настройках. Кстати, WebStorm имеет и свой собственный анализатор. Немного про типизацию JavaScript не имеет (пока?) возможности указывать типы для аргументов функций, но можно воспользоваться, например, JSDoc. Пишите что-то вроде этого (обратите внимание на формат комментария): /** * Creates a new Circle from a diameter. * * @param {number} d The desired diameter of the circle. * @return {Circle} The new Circle object. */ Circle.fromDiameter = function (d) { return new Circle(d / 2); }; И теперь если где-то fromDiameter вызывается к примеру со строкой, то jsdoc в несложных случаях сможет это определить до запуска программы. В добавок к этому jsdoc дает ещё много разных плюшек, не считая основного предназначения - генерировать документацию по вашим комментариям. Более брутальный вариант для настоящих бородатых гуру (например из команды AngularJS) взять и переписать все на TypeScript, который как JavaScript, но позволяет использовать (по желанию!) типы для переменных. И тогда, например, вы сразу увидите (по ошибке компилятора), что вызываете функцию, ожидающую строку, передав ей число. Отладка Здесь старый добрый Console.log('Ohh, shitt!') никто не отменял. Но конечно же не стоит отказывать себе в удовольствии использовать продвинутые отладчики. Тот же WebStorm имеет вполне современные возможности по отладке, но и все мажорные браузеры имеют ту или иную "панель разработки", с отладчиком, профилировщиком и другими вкусностями. Ставите точки останова (и не простые, а с определенным хитрым условием, например чтобы остановилось только на второй раз, при спадающей луне), смотрите стек вызовов, значения переменных (меняете их налету по желанию) и т.п. Для быстрого старта в хроме - жмите F12, дальше разберетесь.

Ответ 3



Если я правильно Вас понял: Вам нужно использовать IDE для написания и редактирования кода. Популярные IDE на данный момент разрабатывает компания JetBrains. Конкретно под JavaScript можете использовать WebStorm При этом, в нём присутствует дебаггер, где можно настроить построчное выполнение кода.

Ответ 4



Лично я использую бесплатную кроссплатформенную Visual Studio Code. В ней есть отличный "пошаговый" дебаггер и всё необходимое.

Ответ 5



Есть несколько вариантов: Использовать IDE (WebStorm, к примеру) Возможности браузеров (chrome dev dools, firebug, и т.д.) Дебаг с помощью console.log (так себе способ).