Форум: "Основная";
Текущий архив: 2007.10.28;
Скачать: [xml.tar.bz2];
ВнизObjAuto и Intel XEON Найти похожие ветки
← →
d_oleg © (2007-08-06 16:48) [0]Простой пример присвоения обработчика событий через ObjAuto.CreateMethodPointer. Все хорошо, на pentium/celeron работатет, а вот на финальной стадии тестирования на сервере (dual Xeon) - не работает :(
Чую, что дело в разрядности процессора (соотв. с размером регистра) но вот что делать - пока даже не представляю.
Пример тут: [href]http://qc.codegear.com/wc/AttachmentHandler.ashx?r=50097&fn=50097.zip[/href]
← →
tesseract © (2007-08-06 18:23) [1]
> Чую, что дело в разрядности процессора (соотв. с размером
> регистра) но вот что делать - пока даже не представляю.
А может пробема в SMP ?
← →
oxffff © (2007-08-06 20:28) [2]Наиболее вероятная причина здесь это DEP.
Я слегка исследовал код.
И нашел доказательство в пользу этой версии.
Интерес представляют две последние инструкции TMethodHandlerInstance.RegisterStub;
LEA ECX,[ECX].TMethodHandlerInstance.Return
// Jump to the actual return instruction since it is most likely not just a RET
JMP ECX
Таким образом происходит переход по адресу в куче (а страницы памяти должны содержать включенный бит защиты от исполнения при активированном DEP)
Так что решение твоей проблемы это отключение DEP.
← →
oxffff © (2007-08-06 20:32) [3]Таким образом статический массив TMethodHandlerInstance.Return используется для динамического формирования кода возврата с Clean-up входных параметров или без него.
← →
d_oleg © (2007-08-06 23:19) [4]
> Наиболее вероятная причина здесь это DEP.
DEP обычно сам ругается, а тут - просто вылетает AV :(
> Интерес представляют две последние инструкции
да, вылет AV происходит именно при попытке JMP
← →
d_oleg © (2007-08-06 23:21) [5]я почему про разрядность заговорил - там местами явно указывается смещение на постоянную величину, может быть в этом дело?
← →
DrPass © (2007-08-06 23:57) [6]
> я почему про разрядность заговорил - там местами явно указывается
> смещение на постоянную величину
a) Причем здесь разрядность?
б) А чем разрядность Ксеона отличается от разрядности всех остальных x86 процессоров вплоть до 386, выпущенного в 1985 году?
← →
Anatoly Podgoretsky © (2007-08-07 00:03) [7]> DrPass (06.08.2007 23:57:06) [6]
Тем что у него есть еще два дополнительных бита в адресе, на физическом уровне.
← →
oxffff © (2007-08-07 09:00) [8]
> d_oleg © (06.08.07 23:19) [4]
>
> > Наиболее вероятная причина здесь это DEP.
> DEP обычно сам ругается, а тут - просто вылетает AV :(
>
>
> > Интерес представляют две последние инструкции
> да, вылет AV происходит именно при попытке JMP
Именно на этом JMP, который я привел в [2]?
Тогда, если у тебя отключен DEP.
А он у тебя точно отключен, иначе бы ругался.
Вставь код
FlushInstructionCache(GetCurrentProcess,AExecuteMethod.Data,Tobject(AExecuteMeth od.Data).InstanceSize);
после вызова
AExecuteMethod := CreateMethodPointer(TSimpleEvent.Create, TypeData);
В итоге у тебя должно быть
procedure TForm1.FormCreate(Sender: TObject);
var
AExecuteMethod: TMethod;
PropInfo: PPropInfo;
TypeData: PTypeData;
begin
PropInfo := GetPropInfo(Button1, "OnClick", [tkMethod]);
TypeData := GetTypeData(PropInfo.PropType^);
AExecuteMethod := CreateMethodPointer(TSimpleEvent.Create, TypeData);
FlushInstructionCache(GetCurrentProcess,AExecuteMethod.Data,Tobject(AExecuteMeth od.Data).InstanceSize);
SetMethodProp(Button1, PropInfo, AExecuteMethod);
end;
Должно помочь. :)
← →
d_oleg © (2007-08-07 09:26) [9]
> Именно на этом JMP, который я привел в [2]?
да-да
> Вставь код FlushInstructionCache
> Должно помочь. :)
не помогло :(
более того, в таком варианте AV есть уже и на "обычных" процессорах...
← →
d_oleg © (2007-08-07 09:34) [10]
> более того, в таком варианте AV есть уже и на "обычных"
> процессорах...
а нет, сбрехал, на "обычных" запускается :)
← →
oxffff © (2007-08-07 09:36) [11]
> d_oleg © (07.08.07 09:26) [9]
>
> > Именно на этом JMP, который я привел в [2]?
> да-да
>
>
> > Вставь код FlushInstructionCache
> > Должно помочь. :)
> не помогло :(
> более того, в таком варианте AV есть уже и на "обычных"
> процессорах...
у тебя такая последовательность?
procedure TForm1.FormCreate(Sender: TObject);
var
AExecuteMethod: TMethod;
PropInfo: PPropInfo;
TypeData: PTypeData;
begin
PropInfo := GetPropInfo(Button1, "OnClick", [tkMethod]);
TypeData := GetTypeData(PropInfo.PropType^);
AExecuteMethod := CreateMethodPointer(TSimpleEvent.Create, TypeData);
FlushInstructionCache(GetCurrentProcess,AExecuteMethod.Data,Tobject(AExecuteMeth od.Data).InstanceSize);
SetMethodProp(Button1, PropInfo, AExecuteMethod);
end;
У меня нет AV на "обычном процессоре".
FlushInstructionCache надо добавить после
AExecuteMethod := CreateMethodPointer(TSimpleEvent.Create, TypeData);
Приведи описание AV.
← →
oxffff © (2007-08-07 10:35) [12]
> d_oleg © (07.08.07 09:34) [10]
>
> > более того, в таком варианте AV есть уже и на "обычных"
>
> > процессорах...
>
> а нет, сбрехал, на "обычных" запускается :)
Так тебе помогло или нет?
← →
d_oleg © (2007-08-07 10:40) [13]
> Так тебе помогло или нет?
на не-ксеоне все нормально, на ксеоне тот же AV
> Приведи описание AV.
Access violation at address ####. Write of address ####.
> у тебя такая последовательность?
да, последовательность именно такая.
← →
oxffff © (2007-08-07 10:54) [14]procedure TForm1.FormCreate(Sender: TObject);
var
AExecuteMethod: TMethod;
PropInfo: PPropInfo;
TypeData: PTypeData;
Pb:pbyte;
begin
PropInfo := GetPropInfo(Button1, "OnClick", [tkMethod]);
TypeData := GetTypeData(PropInfo.PropType^);
AExecuteMethod := CreateMethodPointer(TSimpleEvent.Create, TypeData);
showmessage(inttostr(Tobject(AExecuteMethod.Data).InstanceSize));
Pb:=AExecuteMethod.Data;
inc(pb,$10);
showmessage("Ret opcode C3 = "+IntToHex(pb^,0));
showmessage("Offset to Return static Buffer = "+IntToHex(DWORD(pb),0));
FlushInstructionCache(GetCurrentProcess,AExecuteMethod.Data,Tobject(AExecuteMeth od.Data).InstanceSize);
SetMethodProp(Button1, PropInfo, AExecuteMethod);
end;
Запусти на Xeon. Напиши, что пишет. И напиши полностью AV
← →
oxffff © (2007-08-07 12:16) [15]А так где ошибка?
procedure TForm1.FormCreate(Sender: TObject);
var
AExecuteMethod: TMethod;
PropInfo: PPropInfo;
TypeData: PTypeData;
begin
PropInfo := GetPropInfo(Button1, "OnClick", [tkMethod]);
TypeData := GetTypeData(PropInfo.PropType^);
AExecuteMethod := CreateMethodPointer(TSimpleEvent.Create, TypeData);
asm
mov eax,AExecuteMethod.TMethod.data;
add eax,$10;
mov cl,$c3;
xchg byte ptr [eax],cl;
call eax;
end;
FlushInstructionCache(GetCurrentProcess,AExecuteMethod.Data,Tobject(AExecuteMeth od.Data).InstanceSize);
SetMethodProp(Button1, PropInfo, AExecuteMethod);
end;
← →
oxffff © (2007-08-07 13:34) [16]Ты решил свою проблему или нет?
Попробуй использование SetProcessAffinityMask
procedure TForm1.FormCreate(Sender: TObject);
var
AExecuteMethod: TMethod;
PropInfo: PPropInfo;
TypeData: PTypeData;
begin
SetProcessAffinityMask(GetCurrentProcess,1);
PropInfo := GetPropInfo(Button1, "OnClick", [tkMethod]);
TypeData := GetTypeData(PropInfo.PropType^);
AExecuteMethod := CreateMethodPointer(TSimpleEvent.Create, TypeData);
SetMethodProp(Button1, PropInfo, AExecuteMethod);
end;
← →
oxffff © (2007-08-07 13:48) [17]Для гарантии добавим еще Sleep(0)
procedure TForm1.FormCreate(Sender: TObject);
var
AExecuteMethod: TMethod;
PropInfo: PPropInfo;
TypeData: PTypeData;
begin
SetProcessAffinityMask(GetCurrentProcess,1);
sleep(0);
PropInfo := GetPropInfo(Button1, "OnClick", [tkMethod]);
TypeData := GetTypeData(PropInfo.PropType^);
AExecuteMethod := CreateMethodPointer(TSimpleEvent.Create, TypeData);
SetMethodProp(Button1, PropInfo, AExecuteMethod);
end;
← →
d_oleg © (2007-08-07 15:54) [18]1ый вариант:
24
Ret opcode C3=C3
Offset to Return static Buffer=C8A9C0
Access violation at address 00C8A9C0. Write of address 00C8A9C0
2ой вариант - тот же самый AV, в точности, но уже сразу при запуске.
3ий вариант - тот же самый AV при обращении к событию (при нажатии кнопки)
Ну и со sleep - то же самое.
← →
oxffff © (2007-08-07 16:19) [19]
> 2ой вариант - тот же самый AV, в точности, но уже сразу
> при запуске.
На какой инструкции спотыкается?
← →
oxffff © (2007-08-07 16:38) [20]call Eax он выполняет нормально?
← →
d_oleg © (2007-08-07 17:10) [21]
> call Eax он выполняет нормально
нет, ошибка вылетает именно на этой инструкции
← →
oxffff © (2007-08-07 20:56) [22]
> d_oleg © (07.08.07 17:10) [21]
>
> > call Eax он выполняет нормально
>
> нет, ошибка вылетает именно на этой инструкции
А такой код на чем вылетает?
procedure TForm1.Button1Click(Sender: TObject);
var RetOpCode:byte;
pRetopCode:pbyte;
begin
RetOpCode:=$C3;
FlushInstructionCache(GetCurrentProcess,@RetOpCode,1);
asm
lea eax,RetOpCode;
call eax;
end;
new(pRetopCode);
pRetopCode^:=$C3;
FlushInstructionCache(GetCurrentProcess,pRetopCode,1);
asm
mov eax,pRetopCode;
call eax;
end;
Dispose(pRetopCode);
end;
← →
oxffff © (2007-08-08 13:39) [23]Ты решил свою проблему?
← →
d_oleg © (2007-08-08 16:44) [24]
> А такой код на чем вылетает?
на call eax;
← →
oxffff © (2007-08-08 16:53) [25]
> d_oleg © (08.08.07 16:44) [24]
>
> > А такой код на чем вылетает?
>
> на call eax;
Значит не дает он тебе выполнить код из области стека и кучи.
← →
oxffff © (2007-08-08 17:06) [26]Причину когерентности кешей мы устранили.
Использую выше xchg или FlushInstructionCache
Для гарантии использовали даже SetProcessAffinityMask
Значит причина не в этом.
Остается либо DEP, либо какие-то еще моменты мне не известные.
Рекомендую обратиться на WASM.ru.
Если напишешь туда, оставь пожалуйста ссылку на созданную тему.
← →
oxffff © (2007-08-08 21:39) [27]
> Причину когерентности кешей мы устранили.
не когерентности. :)
← →
d_oleg © (2007-08-13 08:53) [28]http://www.delphikingdom.com/asp/answer.asp?IDAnswer=54303
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2007.10.28;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.043 c