Russian Qt Forum

Qt => Qt-инструментарий => Тема начата: enumerator от Июнь 03, 2011, 17:51



Название: Отображение реального типа объекта в отладчике
Отправлено: enumerator от Июнь 03, 2011, 17:51
Доброго времени суток. Интересует такой вопрос. Пусть, например, в программе имеется интерфейс I1  и несколько его реализаций I1Impl1, I1Impl2 и т.д. Разумеется, как правило работа с объектами типов I1ImplX ведется именно через интерфейс I1, т.е. большинство функций принимают на вход ссылку или указатель на I1. При этом существует следующая проблема: фронтенд к отладчику QtCreator по умолчанию не показывает реальный тип объекта, а отображает именно задекларированный тип, т.е. I1, соответственно, внутреннее содержимое объектов не посмотреть, что очень сильно снижает удобство отладки. Существует ли какой-нибудь способ решения этой проблемы, возможно, какой-то "волшебный" инициализирующий скрипт самого gdb, который бы позволил в отладчике QtCreator (или какой-либо другой среды программирования под Linux) видеть реальный тип объекта и его содержимое?


Название: Re: Отображение реального типа объекта в отладчике
Отправлено: kambala от Июнь 03, 2011, 20:31
может в gdb прокатит что-то типа такого?
Код:
po interfaceObject->metaObject()->className()


Название: Re: Отображение реального типа объекта в отладчике
Отправлено: enumerator от Июнь 03, 2011, 21:56
даже если такое прокатит, то это не совсем то, чего хочется. Тут есть два недостатка:
1) надо наследоваться от QObject  или определять похожий метод в собственном интерфейсе
2) эту команду нужно набивать руками в консоли gdb для каждого объекта, чего делать не хочется, особенно, если есть
необходимость посмотреть содержимое какого-нибудь контейнера вида std::vector< std::shared_ptr< I1 > >, что возникает достаточно часто.
Самое интересное, что по идее отладчику не должно бы составлять труда реализовать подобную функциональность, учитывая, что всеми необходимыми сведениями он располагает (ведь он видит, куда ведет указатель на таблицу виртуальных функций, а соответственно, точно знает тип объекта), однако ни в одном графическом фронтенде к gdb я такой возможности не видел.


Название: Re: Отображение реального типа объекта в отладчике
Отправлено: kamre от Июнь 04, 2011, 20:14
Отладчик в QtCreator по сравнению с MSVC какой-то убогий.

Меня тоже раздражает, что для такого кода:
Код:
class Object {
public:
  Object(int id_) : id(id_) {}
  virtual ~Object() {}

private:
  int id;
};

class Point: public Object {
public:
  Point(double x_, double y_, int id_)
    : Object(id_), x(x_), y(y_) {}

private:
  double x, y;
};

class Circle: public Point {
public:
  Circle(double x_, double y_, double r_, int id_)
    : Point(x_, y_, id_), r(r_) {}

private:
  double r;
};

int main()
{
  Object *obj = new Circle(1.5, -2.5, 3.0, 15);
  return 0;  // <== break point here
}

QtCreator показывает только так:
(http://i55.tinypic.com/33ogrjr.png)

а в MSVC все что нужно показывает:
(http://i52.tinypic.com/24fiucm.png)


Название: Re: Отображение реального типа объекта в отладчике
Отправлено: Авварон от Июнь 04, 2011, 20:22
разработчикам гдб зарплату, знаете ли не платят, ога. скажите спасибо что там вообще есть отладчик.

на правах оффтопа - отладчик нужен только стектрейс получать в случае нулл поинтера. те кто лазает по структурам в дебаггере не умеют программировать (иначе откуда у них ошибки в данных)


Название: Re: Отображение реального типа объекта в отладчике
Отправлено: kamre от Июнь 04, 2011, 20:34
разработчикам гдб зарплату, знаете ли не платят, ога. скажите спасибо что там вообще есть отладчик.

Спасибо!  ;D

на правах оффтопа - отладчик нужен только стектрейс получать в случае нулл поинтера. те кто лазает по структурам в дебаггере не умеют программировать (иначе откуда у них ошибки в данных)
Конечно, если чего-то нет в любимой IDE/Editor/OS, то это просто не нужно. А как только появляется (вроде того же QtCreator с более или менее вменяемым дополнением и навигацией по исходникам), то сразу нахваливать начинают. Известное дело...


Название: Re: Отображение реального типа объекта в отладчике
Отправлено: enumerator от Июнь 04, 2011, 20:36
Я когда искал в интернете ответ на этот вопрос, наткнулся на команду самого gdb: set print object on, которая, как я понял, делает как раз то, что нужно, опираясь именно на указатель на таблицу виртуальных функций. С консольным gdb я работать не умею, так что проверить не могу, однако у меня нет поводов не доверять документации gdb. Таким образом получается, что вся проблема в графическом фронтенде к отладчику, а поэтому есть надежда, что в какой-нибудь IDE такая функциональность поддерживается. В Visual Studio и правда отладчик умеет это "из коробки" (вообще, отладчик Visual Studio является ее самым большим плюсом), однако под Linux visual studio нет, а если бы и было, то я бы не стал связываться с ее компилятором (несмотря на все прелести отладчика).


Название: Re: Отображение реального типа объекта в отладчике
Отправлено: Sancho_s_rancho от Июнь 04, 2011, 20:54
разработчикам гдб зарплату, знаете ли не платят, ога. скажите спасибо что там вообще есть отладчик.

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


Название: Re: Отображение реального типа объекта в отладчике
Отправлено: Авварон от Июнь 04, 2011, 20:54

Конечно, если чего-то нет в любимой IDE/Editor/OS, то это просто не нужно. А как только появляется (вроде того же QtCreator с более или менее вменяемым дополнением и навигацией по исходникам), то сразу нахваливать начинают. Известное дело...
Просто магическим образом мой код работает. Я следую принципу - если начинаю путаться в коде, я его выкидываю и ищу более простой вариант. Возможно, я никогда не смогу работать в энтерпрайзе, тк чисто физически не могу писать код не продумав детально и не поставив печать "варианта проще нет".
В примере с картинками - отладчик не должен знать о реальном типе Object, так как о нем не знает сам код. Более того, вы неправильно дебагаете - если у вас пришел объект с битыми данными то искать надо не в том месте, куда он пришел, а в том, где эти данные поломались (сам по себе класс не сломается, скорее всего вы накосячили ещё в процессе создания/инициализации).
Ну и напоследок - какие нафиг проперти у интерфейса? Почему класс с данными использует виртуальное наследование?
Если чего, не хочу никого обидеть, просто ратую чтобы люди думали:) Ну и смотрели примеры правильного/красивого кода.


Название: Re: Отображение реального типа объекта в отладчике
Отправлено: kamre от Июнь 04, 2011, 20:55
Я когда искал в интернете ответ на этот вопрос, наткнулся на команду самого gdb: set print object on, которая, как я понял, делает как раз то, что нужно, опираясь именно на указатель на таблицу виртуальных функций. С консольным gdb я работать не умею, так что проверить не могу, однако у меня нет поводов не доверять документации gdb.
А ведь действительно gdb умеет это показывать:
Цитировать
Reading symbols from D:\Projects\QtCreator\TestDebug-build-desktop\debug/TestDebug.exe...done.
(gdb) break 30
Breakpoint 1 at 0x4013b3: file ..\TestDebug\test.cpp, line 30.
(gdb) run
Starting program: D:\Projects\QtCreator\TestDebug-build-desktop\debug/TestDebug.exe
[New Thread 1784.0x280]

Breakpoint 1, test (obj=0x3e2bf0) at ..\TestDebug\test.cpp:30
30         return 0; // <== break point here
(gdb) print obj
$1 = (Object *) 0x3e2bf0
(gdb) print *obj
$2 = {_vptr.Object = 0x40e260, id = 15}
(gdb) set print object on
(gdb) print obj
$3 = (Circle *) 0x3e2bf0
(gdb) print *obj
$4 = (Circle) {<Point> = {<Object> = {_vptr.Object = 0x40e260, id = 15}, x = 1.5, y = -2.5}, r = 3}
Значит просто QtCreator не умеет этим пользоваться.

В Visual Studio и правда отладчик умеет это "из коробки" (вообще, отладчик Visual Studio является ее самым большим плюсом), однако под Linux visual studio нет, а если бы и было, то я бы не стал связываться с ее компилятором (несмотря на все прелести отладчика).
"Связываться с ее компилятором" намертво и не нужно, если использовать для сборки проекта CMake. Но вести основную разработку (для меня) пока гораздо удобнее в Windows на MSVC, чем в любой IDE в Linux. А потом уже собирать и тестировать отдельно под Linux.


Название: Re: Отображение реального типа объекта в отладчике
Отправлено: enumerator от Июнь 04, 2011, 21:02
Интересно, если gdb поддерживает такую фичу, то нельзя ли каким бы то ни был ообразом включить ее при отладке в QtCreator? Вроде как там в настройках предлагают выполнить некий инициализирующий скрипт gdb, возможно, если включение данной опции "вставить" в этот самый скрипт, то QtCreator подхватит нужное поведение.


Название: Re: Отображение реального типа объекта в отладчике
Отправлено: Авварон от Июнь 04, 2011, 21:05
Не на правах оффтопа - если кто-то найдет как это сделать, не поленитесь, сделайте патч к скриптам дебаггинг хелпера и выложите на багтрекере с соответствующей таской или здесь, кто-нибудь создаст таск.


Название: Re: Отображение реального типа объекта в отладчике
Отправлено: kamre от Июнь 04, 2011, 21:14
Просто магическим образом мой код работает. Я следую принципу - если начинаю путаться в коде, я его выкидываю и ищу более простой вариант. Возможно, я никогда не смогу работать в энтерпрайзе, тк чисто физически не могу писать код не продумав детально и не поставив печать "варианта проще нет".
Да все можно сделать хоть в блокноте, если компилятор уже есть. И если кода не так много, что его легко выбросить и переписать с нуля, то так и нужно делать. А если проект огромный, писался долго и людьми самой разной квалификации? И чтобы провести рефакторинг какого-то куска нужно просить выделить на это время, что очень не охотно делается вышестоящими. Здесь уже любые средства, ускоряющие работу, хороши.

В примере с картинками - отладчик не должен знать о реальном типе Object, так как о нем не знает сам код.
Вот здесь полностью не согласен. Отладчик имеет в наличии всю runtime информацию о ходе работы программы. О реальном типе не знает компилятор во время компиляции.

Более того, вы неправильно дебагаете - если у вас пришел объект с битыми данными то искать надо не в том месте, куда он пришел, а в том, где эти данные поломались (сам по себе класс не сломается, скорее всего вы накосячили ещё в процессе создания/инициализации).
Удобно сразу в отладчике при остановке в этой функции посмотреть на что на самом деле указывает указатель. А данные не обязательно поломались, может быть функция не корректно работает в некоторых случаях.

Ну и напоследок - какие нафиг проперти у интерфейса? Почему класс с данными использует виртуальное наследование?
Если чего, не хочу никого обидеть, просто ратую чтобы люди думали:) Ну и смотрели примеры правильного/красивого кода.
Это просто пример, чтобы было что на скриншоте показать.


Название: Re: Отображение реального типа объекта в отладчике
Отправлено: kamre от Июнь 04, 2011, 21:23
Вроде как там в настройках предлагают выполнить некий инициализирующий скрипт gdb, возможно, если включение данной опции "вставить" в этот самый скрипт, то QtCreator подхватит нужное поведение.
Не помогает, можно только через Debugger Log посмотреть:
(http://i55.tinypic.com/qzf8ky.png)

Это я только в .gdbinit записал строку и указал этот файл в настройках Tools->Options...->Debugger->GDB->GDB start up script.


Название: Re: Отображение реального типа объекта в отладчике
Отправлено: enumerator от Июнь 04, 2011, 21:32
Жаль. Интересно, а как же тогда работает фронтенд к отладчику в QtCreator? Ведь насколько я понимаю, он как раз и занимается тем, что шлет команды отладчику и интерпретирует ответ. Каков же тогда его способ получения того содержимого переменных, которое он отображает, неужели в Вашем случае он просто отбросил часть вывода gdb?


Название: Re: Отображение реального типа объекта в отладчике
Отправлено: Авварон от Июнь 04, 2011, 21:34
kamre
Думал написать стену текста, но потом стер:) Лениво холиварить. Соглашусь с вами, что разбирать чужой быдлокод - задача неблагодарная и любая помощь хороша. Я же имел ввиду что надо писать сразу правильный код и там таки да, таки дебуггер не нужен.


Название: Re: Отображение реального типа объекта в отладчике
Отправлено: kamre от Июнь 04, 2011, 21:48
Жаль. Интересно, а как же тогда работает фронтенд к отладчику в QtCreator? Ведь насколько я понимаю, он как раз и занимается тем, что шлет команды отладчику и интерпретирует ответ. Каков же тогда его способ получения того содержимого переменных, которое он отображает, неужели в Вашем случае он просто отбросил часть вывода gdb?
Я просто ввел команду "print *obj", а QtCreator использует какие-то другие (более эффективные?) команды для запроса информации у gdb.