Подскажите люди. Возможно это самый сложный баг с которым мне приходилось бороться. Есть некий, достаточно простой код на си который в силу внешних обстоятельств (работа с импортом и экспортом) перестал работать. Вывожу на экран содержимое странных значений. Адрес FullProjectIdent при работе не изменяется. Код (Text): unsigned char * FullProjectIdent[]; ... for( i = 0; FullProjectIdent[ i ] != NULL; i++ ) ; //i = 0x11. b = i; //b добавлена для проверки и далее не изменяется кроме места применения. &FullProjectIdent = 0x3380 ... &FullProjectIdent[i - 1] = 0x33C0 //по неведомой причине индекс (i - 1) выдает NULL. ... (i не изменяется.) &FullProjectIdent[--i] = 0x33C4 //!!!!!!!!!!!!!!!?????????????? ... FullProjectIdent[--b] = 0x3870 //!!!!!!!!!!!!!!!?????????????? ... &FullProjectIdent[0x10] = 0x3380 //!!!!!!!!!!!!!!!?????????????? Остальной код в большом проекте работает нормально. Пытаюсь понять в чем дело. FullProjectIdent импортируется из отдельной DLL. Подскажите - это ошибка при обработки связки импорта экспорта или какая-та ошибка обработки фиксапов? Как это победить? Я даже не очень понимаю что конкретно мне ловить и где. Схема получения значения для: Код (Text): ?live1@2868: ; EBX = i 1. &FullProjectIdent Код (Text): push offset _FullProjectIdent 2. i - 1 Код (Text): mov eax,ebx shl eax,2 add eax,offset _FullProjectIdent-4 push eax 3. --i Код (Text): dec ebx shl ebx,2 add ebx,offset _FullProjectIdent push ebx 4. --b Код (Text): dec dword ptr [ebp-4] mov eax,dword ptr [ebp-4] push dword ptr [_FullProjectIdent+4*eax] 5. 0x10 Код (Text): push offset _FullProjectIdent+64 Компилятор Borland 4.5. Не спрашивайте почему просто так надо.
Такое впечатление что все смещения добавляемые к offset _FullProjectIdent стираются, тогда понятно поведение в 4 случаях из 5 (кроме --b).
NoName, сабжевый проект возможно выложить в паблик, нам на отладку? Я бы дал много процентов вероятности, что просто нужно погонять это щастье со «свежей» головой, не вдаваясь в детали.
Единственные средства отладки - запреты прерываний, вывод на экран и внедрение в исходный код проверок. Код выполняется параллельно с другими задачами. Там тонны кода. Программа работает под своей ОС. Еще у меня есть предположение что дело в линковщике.
Прошу прощения, что снова лезу поперёд батьки в пекло, но всё же. Меня вот это -4 в коде [i-1] сильно смущает. У меня тот же самый код компилируется так: I-1: Код (Text): MOV RAX, QWORD PTR [RBP - 4]; <-- теперь в RAX лежит I SUB RAX, 1 SHL RAX, 3 ADD RAX, QWORD PTR [RBP - 16]; <-- складываем (I-1)*SIZEOF(int) с базой массива --I: Код (Text): SUB QWORD PTR [RBP - 4], 1 MOV RAX, QWORD PTR [RBP - 4]; <-- теперь в RAX лежит --I SHL RAX, 3 ADD RAX, QWORD PTR [RBP - 16]; <-- складываем (--I)*SIZEOF(int) с базой массива При этом между вызовами ни [RBP - 16], ни [RBP - 4] не изменяются. Откуда вдруг взялось это -4 у Вас — неясно.
размер элемента массива _FullProjectIdent = 4 Скомпилировал отдельную dll. В работе там тоже -4 есть, но все показывается правильно: Код (Text): [i-1] ?live1@1044: ; EBX = i, ESI = &FullProjectIdent, EDI = &Buff push dword ptr [esi+4*ebx-4] push edi call Такое впечатление что конструкция offset _FullProjectIdent - 4 стремная, хотя вроде ничего криминального.
Нда уж, это снова я дурак со своими 64 битами. ИЧСХ, сам же вместо RBP + 8 написал + 4. Надо больше отдыхать. А вообще, согласен с Rel: без взгляда на исходник бажной функции говорить предметно очень сложно.