AIMP Forum
AIMP for PC => Дополнения / Addons => Разработка / Development => Topic started by: DarkDrawKill on March 28, 2026, 23:49:29
-
Как дебагать скомпилированную библиотеку на линукс через gdb
хоть оно скомпилированно с метками но когда падает просто пишет ошибку (не факт что библиотека падает с такой ошибкой) и всё
-
Не подскажу, GDB не использую
-
чёто там разобрался
плагин падает в функции RegisterExtension но от чего я не понял (расширение создаётся без ошибок и все методы перегружены)
добавил архив с исходниками и сошкой (дебаг метки прилагаются)
-
плагин падает в функции RegisterExtension но от чего я не понял
у frame RefCount = 0, вот он и прибился раньше времени. Вам надо сделать ему ._addRef сразу после создания
-
у frame RefCount = 0, вот он и прибился раньше времени. Вам надо сделать ему ._addRef сразу после создания
пробывал делать но тоже самое
я его потом убрал (в плагине wgmstream также сделано)
-
На сколько я вижу, вместо frame как IUnknown приходит что-то другое. Плеер падает при попытке вызвать _AddRef.
В VgmStream у меня там нет auto, плюс я собирал на VC++, может есть какие-то разночтения между компиляторами.
-
В VgmStream у меня там нет auto
изначально у меня был как в vgmstream тоесть объект создавался и сразу передавался но изза ошибки я уже сделал отдельную переменную чтобы вызвать AddRef но не исправить ошибку не вышло
На сколько я вижу, вместо frame как IUnknown приходит что-то другое. Плеер падает при попытке вызвать _AddRef.
догадывался
думаю проблема возможно стоит либо в виртуальной таблице либо стек перевёрнут попробую потестить
гзв проблему так не решил но заметил что у IUnknown и IUnknownImpl разные атрибуты у функций (у IUnknown используется cdecl а IUnknownImpl реализует их уже stdcall)
-
calling convention для 64битного кода не применяется
-
calling convention для 64битного кода не применяется
теперь понятно почему компилятор предупреждениями сыпит
решил пока отойти от расширений и хотя бы реализовать чтото простое
IAIMPServiceVersionInfo* versionService = nullptr;
auto success = core->QueryInterface(IID_IAIMPServiceVersionInfo, reinterpret_cast<void**>(&versionService));
if (Failed(success))
return E_FAIL;
auto version = versionService->GetVersionID();
versionService->Release();
return S_OK;
ядро не возвращает сервис с ошибкой E_FAIL даже версию не узнать >:(
-
Корень проблемы нашел: неправильное выравнивание в структурах.
Единственное, пока что-то не получается заставить GCC упаковывать структуры должным образом - ни через pragma, ни через атрибуты что-то не хочет.
Маркер правильной упаковки такой:
if (sizeof(GUID) != 16)
return E_FAIL;
-
Единственное, пока что-то не получается заставить GCC упаковывать структуры должным образом - ни через pragma, ни через атрибуты что-то не хочет.
проблема была не в выравнивании а в типах
(gdb) ptype IID_IUnknown
type = const struct GUID {
DWORD Data1;
WORD Data2;
WORD Data3;
BYTE Data4[8];
}
(gdb) print sizeof(DWORD)
$3 = 8
(gdb) print sizeof(WORD)
$4 = 2
(gdb) print sizeof(BYTE)
$5 = 1
DWORD занимал 8 байт вместо 4 изза typedef unsigned long DWORD; (в линукс x86 long и long long занимают 8 байт почемуто) поэтому структура увеличилась в размере до 20 байт а компилятор выравнял её до 24
я добавил #include <cstdint> и заменил на typedef uing32_t DWORD и ядро мне вернуло сервис :))
гзв или использовать unsigned int
-
Да, что-то я не проверил размерность базовых типов, хотя идея такая была...
Боюсь мне надо многое пройти по SDK и перепроверить. long и unsigned long у меня довольно много...
-
Вот подправленная версия
-
да теперь всё точно работает но первая проблема так и не решилась :'(
я и регистры смотрел и втаблицу парсил всё в порядке должно работать но падает с ошибкой (даже перегруз _AddRef добавлял всё бестолку)
upd вопрос будет ли плеер падать если на регистрацию передать нулевой указатель?
-
если на регистрацию передать нулевой указатель?
да.
но первая проблема так и не решилась :'(
Вечером поисследую
-
Нашёл причину, придётся подождать обновления плеера.
-
Хотя можно и не ждать:
-
из изменений я вижу теперь guid передаётся напрямую а не через ссылку
но плагин всё равно падает
-
из изменений я вижу теперь guid передаётся напрямую а не через ссылку
Да, но не везде.
но плагин всё равно падает
У меня не падает, но я собирал на g++, а не на mingw. Вот команда:
g++ -g3 -gdwarf-3 -c -fPIC -I"/usr/include/cairo" -I"../aimp_sdk" -Wno-attributes ./subsonicOptionsDialogFrame.cpp ./subsonicPlugin.cpp ./../aimp_sdk/apiTypes.cpp
g++ -shared -lstdc++ -lgcc ./../aimp_sdk/apiTypes.o ./subsonicPlugin.o ./subsonicOptionsDialogFrame.o -o ./aimp_subsonic.so
-
У меня не падает, но я собирал на g++, а не на mingw. Вот команда:
попробовал как у вас и у меня он всё равно упал
попробую переустановить аимп
гзв проблема была не в аимпе а в дебаггере в нём аимп падает а если просто запустить без дебаггера то всё регистрирует
гзв2 нет проблема ещё тривиальней
плеер не падает а дебаггер просто останавливает программу на ошибке сегментации если продолжить (continue или c) то плагин продолжит работать
проблема в том что вкладка плагина не появляется в разделе плагины
видимо плеер ловит ошибку сегментации но просто с ней ничего не делает возвращая S_OK и плагин удачно инициализируется но вкладка не появляется
-
скиньте собранный плагин, на котором вываливается ошибка сигментации
-
скиньте собранный плагин, на котором вываливается ошибка сигментации
архив в закрепе
-
Ошибка здесь:
if (Succeeded(p_plugin->getCore()->QueryInterface(IID_IAIMPServiceUI, reinterpret_cast<void**>(uiService)))) {
Должно быть так:
if (Succeeded(p_plugin->getCore()->QueryInterface(IID_IAIMPServiceUI, reinterpret_cast<void**>(&uiService)))) {
-
Должно быть так:
ой блин видимо случайно стёр в емаксе когда команду прожимал и забыл
спасибо
гзв нормально если при E_FAIL я верну HWND = 0?
-
а там вариантов других нет...
-
забавно что компилятор предупреждает что идёт преобразование константы в переменную в строках типа
static const PChar string = TEXT("...");
предполагаю он думает что константа именно ссылка а строка изменяемая
решается заменой на
static const TChar string[] = TEXT("...");
-
Конечно, можно и переделать на значения.
А разве не так должно быть:
static const TChar[] string = TEXT("...");
?
-
А разве не так должно быть:
незнаю у меня компилятор есть мой вариант который я использую для статических строк для InfoGet
гзв погуглил все пишут [] после названия переменной
-
незнаю у меня компилятор есть мой вариант который я использую для статических строк для InfoGet
гзв погуглил все пишут [] после названия переменной
Да, это я с Java спутал.
В SDK заменил объявление констант на TChar Name[]
-
какой алгоритм используется для генерации хеш кодов для строк?
-
Bob Jenkin, а что?
-
Bob Jenkin, а что?
придётся гдето ковырять реализацию md5 для utf8 и преобразовывать с utf16 в utf8 для виндовс
-
придётся гдето ковырять реализацию md5 для utf8 и преобразовывать с utf16 в utf8 для виндовс
Md5 16 байт, а хеш встроенный всего 4. Туда он никак не влезет