Russian Qt Forum

Компиляторы и платформы => Mac OS X => Тема начата: Igors от Октябрь 01, 2021, 10:24



Название: Xcode Guard Malloc
Отправлено: Igors от Октябрь 01, 2021, 10:24
Добрый день

Падает в главном событийном цикле. Нужно проверять кучу, включил Guard Malloc (Edit Schene > Options). Он ловит exception на совершенно безобидной ф-ции qstrlen. Как это понимать? Адрес подаваемый в ф-цию нормальный, отладчик показывает строку по этому адресу, она как и должна быть. Пробовал др опции диагностики памяти, краш тот же, ничего не находят

Спасибо


Название: Re: Xcode Guard Malloc
Отправлено: tux от Октябрь 01, 2021, 10:38
А какое именно исключение?


Название: Re: Xcode Guard Malloc
Отправлено: ssoft от Октябрь 01, 2021, 11:04
А строка нулем заканчивается? Предусмотрен для нулевого символа дополнительное поле в конце при выделении памяти под строку? Как правило из-за этого strlen и подобные падают.


Название: Re: Xcode Guard Malloc
Отправлено: Igors от Октябрь 01, 2021, 16:04
Ну ладно, давайте "со всеми остановками". Вот собсно сам вылет с которого все началось

Цитировать
static inline void qt_mac_waitForMoreEvents(NSString *runLoopMode = NSDefaultRunLoopMode)
{
    // If no event exist in the cocoa event que, wait (and free up cpu time) until
    // at least one event occur. Setting 'dequeuing' to 'no' in the following call
    // causes it to hang under certain circumstances (QTBUG-28283), so we tell it
    // to dequeue instead, just to repost the event again:
    NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny   // Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
        untilDate:[NSDate distantFuture]
        inMode:runLoopMode
        dequeue:YES];
    if (event)
        [NSApp postEvent:event atStart:YES];
}

// Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
Приложение запускается и работает, летит при загрузке большого файла данных (сегодня утром осчастливили)

Ладно, пробую Guard Malloc, теперь летит уже на инициализации приложения
Цитировать
inline uint qstrlen(const char *str)
{ return str ? uint(strlen(str)) : 0; }

Thread 1: EXC_BAD_ACCESS (code=1, address=0x600096c32000)
А вот место откуда зовется qstrlen
Цитировать
       // Append rest of shader code
        sourceChunks.append(source + versionDirectivePosition.position);
        sourceChunkLengths.append(GLint(qstrlen(source + versionDirectivePosition.position)));

// scurce = 0x0000600096c31f08
// versionDirectivePosition.position = 248
Вот дамп строки source, да, она заканчивается нулем
Цитировать
23 76 65 72 73 69 6F 6E 20 33 33 30 0D 0D 69 6E 20 76 65 63 33 20 74 65 78 43 6F 6F 72 64 30 5F 76 73 68 3B 0D 0D 75 6E 69 66 6F 72 6D 20 73 61 6D 70 6C 65 72 32 44 20 74 65 78 74 75 72 65 30 3B 0D 0D 6F 75 74 20 76 65 63 34 20 67 6C 46 72 61 67 43 6F 6C 6F 72 3B 0D 0D 76 6F 69 64 20 6D 61 69 6E 20 28 76 6F 69 64 29 0D 7B 0D 09 67 6C 46 72 61 67 43 6F 6C 6F 72 20 3D 20 74 65 78 74 75 72 65 28 74 65 78 74 75 72 65 30 2C 20 74 65 78 43 6F 6F 72 64 30 5F 76 73 68 2E 78 79 29 3B 0D 2F 2F 09 76 65 63 34 20 74 78 20 3D 20 74 65 78 74 75 72 65 28 74 65 78 74 75 72 65 30 2C 20 74 65 78 43 6F 6F 72 64 30 5F 76 73 68 2E 78 79 29 3B 0D 2F 2F 09 67 6C 46 72 61 67 43 6F 6C 6F 72 20 3D 20 76 65 63 34 28 74 78 2E 78 79 7A 2C 20 31 29 3B 0D 7D 0D 00
И вот сама строка source
Цитировать
#version 330

in vec3 texCoord0_vsh;

uniform sampler2D texture0;

out vec4 glFragColor;

void main (void)
{
   glFragColor = texture(texture0, texCoord0_vsh.xy);
//   vec4 tx = texture(texture0, texCoord0_vsh.xy);
//   glFragColor = vec4(tx.xyz, 1);
}

И шо? Впечатление что типовая хренотень с тулзами диагностики - ему "все не нравится"


Название: Re: Xcode Guard Malloc
Отправлено: ssoft от Октябрь 01, 2021, 23:11
Так вопрос остался открытым. Указатель source указывает на достаточное количество байт, чтобы хранить весь этот текст и нулевой символ в конце? И занулен ли последний символ принудительно?


Название: Re: Xcode Guard Malloc
Отправлено: Igors от Октябрь 02, 2021, 10:07
Так вопрос остался открытым. Указатель source указывает на достаточное количество байт, чтобы хранить весь этот текст и нулевой символ в конце?
Да, это видно из дампа и переменных отладки

И занулен ли последний символ принудительно?
Ну как "принудительно". Конечно кто-то этот ноль писал, но точно не я  :) У меня и возможности такой не было, весь код выше - либы Qt

Адрес вылета (0x600096c32000) какой-то "слишком круглый", но правильный (0x0000600096c31f08 + 0xf8). Ну и смущает что до загрузки файла (где летит) еще очень далеко. Понятно что и такое "возможно", но все же..

Попробовал с др проектом, вылета нет, только вякает
Цитировать
GuardMalloc[MyApp-2259]: Allocations will be placed on 16 byte boundaries.
GuardMalloc[MyApp-2259]:  - Some buffer overruns may not be noticed.
GuardMalloc[MyApp-2259]:  - Applications using vector instructions (e.g., SSE) should work.
GuardMalloc[MyApp-2259]: version 109
GuardMalloc[MyApp-2259]: Attempting excessively large memory allocation:  134217732 bytes
GuardMalloc[MyApp-2259]: If you really wanted to allocate so much memory, launch your executable with the environment variable MALLOC_PERMIT_INSANE_REQUESTS set to any value to circumvent this check.
GuardMalloc[MyApp-2259]: Explicitly trapping into debugger!!!
Блок 128 метров - это кошкины слезы, чего ото понты колотить ?


Название: Re: Xcode Guard Malloc
Отправлено: Авварон от Октябрь 03, 2021, 11:57
Думаю, если соберете с санитайзером (-fsanitize=address) то помощи будет больше.
В целом, макось вроде бы делает memory overcommitment, поэтому bad_alloc вы не получите, а получите краш при использовании памяти, но вряд ли тут она закончилась


Название: Re: Xcode Guard Malloc
Отправлено: Igors от Октябрь 03, 2021, 13:47
Да, краш нашел, псевдокод
Код
C++ (Qt)
void Loader::LoadMaps( const CKey & key )
{
 auto & dst = m_map[key];
 ...
 texture.LoadImage(..);
 UpdateProgress();
 ...
 dst.push_back(..);
}
UpdateProgress вызывает processEvents, и опять дело доходит до LoadMaps (re-enter). В рез-те ссылка dst оказывается битой, но каким-то чудесным образом push_back не крашит, а гадит намного позже

Ну это повезло, по-хорошему нужны тулзы

Думаю, если соберете с санитайзером (-fsanitize=address) то помощи будет больше.
"Пробывал", с тем же эффектом

В целом, макось вроде бы делает memory overcommitment, поэтому bad_alloc вы не получите, а получите краш при использовании памяти, но вряд ли тут она закончилась
Ну тут хоть бы что-то получить чтобы зацепиться