Форум: "Прочее";
Текущий архив: 2008.10.26;
Скачать: [xml.tar.bz2];
ВнизЗадачка для совсем-совсем начинающих Найти похожие ветки
← →
DiamondShark © (2008-09-04 14:38) [80]
> oxffff © (04.09.08 14:14) [76]
Гоню. За пределы ProcessMessages исключения не выпускаются. ВЦЛ -- сволочь.
> oxffff © (04.09.08 14:18) [77]
И чё? Ну вот представь, что у тебя есть код:
while AnyVar do begin
//...
AnyVar := false;
end
После присваивания произошло переключение потоков. Что страшного случилось? Почему в этом случае ты не пишешь интерлокед-функцию, а полагаешься на простое присваивание?
По твоей логике, в этом коде есть вероятность лишней итерации цикла (если AnyVar -- не в регистре, а в пямяти).
Это ж ужас какие глюки должны испытывать обычные приложения в многопроцессорной среде.
← →
Slym © (2008-09-04 14:42) [81]Slym © (04.09.08 14:33) [79]
применен способ защиты запутыванием условного перехода без применения операторов условного перехода (условности я конечно вырезал т.к. не к месту)
← →
oxffff © (2008-09-04 14:52) [82]
> Slym © (04.09.08 14:33) [79]
Что это чудеса генной инженерии?
Хто такой intercept?
Смысл однако мне понятен.
Только по условию нет возможности править pascal source код.
А твой пример тогда проще сразу переписать.
procedure Proc;
label label1;
begin
ShowMessage("Ïðîöåäóðà Proc ñòàðòîâàëà");
while True do
begin
//Sleep(1);// Ýòî ÷òîáû íå ãðóçèòü ïðîöåññîð
goto Label1;
Application.ProcessMessages;
end;
Label1: ShowMessage("Ïðîöåäóðà Proc çàâåðøèëàñü");
end;
← →
DiamondShark © (2008-09-04 14:56) [83]procedure TForm1.Button1Click(Sender: TObject);
var
SaveOnMessage: TMessageEvent;
begin
SaveOnMessage := Application.OnMessage;
Application.OnMessage := OnMessageAbort;
try
Proc;
finally
Application.OnMessage := SaveOnMessage;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
PostMessage(0, WM_USER+1, 0, 0);
end;
procedure TForm1.OnMessageAbort(var Msg: TMsg; var Handled: Boolean);
begin
if (Msg.message = WM_USER+1) and (Msg.hwnd = 0) then Abort;
end;
← →
oxffff © (2008-09-04 15:02) [84]
> DiamondShark © (04.09.08 14:38) [80]
>
> > oxffff © (04.09.08 14:14) [76]
>
> Гоню. За пределы ProcessMessages исключения не выпускаются.
> ВЦЛ -- сволочь.
За пределы ProcessMessages исключения как раз выпускаются.
А вот за пределы WndProc уже нет.
Способы решения [42], [44].
> > oxffff © (04.09.08 14:18) [77]
>
> И чё? Ну вот представь, что у тебя есть код:
>
> while AnyVar do begin
> //...
> AnyVar := false;
> end
>
> После присваивания произошло переключение потоков. Что страшного
> случилось? Почему в этом случае ты не пишешь интерлокед-
> функцию, а полагаешься на простое присваивание?
>
> По твоей логике, в этом коде есть вероятность лишней итерации
> цикла (если AnyVar -- не в регистре, а в пямяти).
> Это ж ужас какие глюки должны испытывать обычные приложения
> в многопроцессорной среде.
Да действительно, в данном конкретном случае может быть несколько лишних итерация цикла. Но для кого то это может быть смертельно, я брать ситуацию в общем.
Однако приучать стоит себя уже сейчас.
Поскольку мы в большинстве своем пока привыкли писать программы где цикл обработки сообщений использует один поток для своей работы и один процессор. Однако уже сейчас в спешном порядке нужно перестраивать свое мышление.
← →
oxffff © (2008-09-04 15:14) [85]
> DiamondShark © (04.09.08 14:56) [83]
Хитрый жук. :)
Все таки исхитрился сгенерировать исключение в ProcessMessage.
Тоже интересный вариант.
← →
Slym © (2008-09-04 15:30) [86]Intercept(Sleep,MySleep);
это сплайсинг... подмена оригинального Sleep собственным MySleep например через таблицу импорта
т.е. до сплайсинга официально спим... после сплайсинга переход
← →
Slym © (2008-09-04 15:31) [87]oxffff © (04.09.08 14:52) [82]
Только по условию нет возможности править pascal source код.
да ради бога... поставил хук, внедрился в ап жертвы, сделал сплайсинг слипа... и все из внешнего процесса
← →
DiamondShark © (2008-09-04 15:42) [88]
> oxffff © (04.09.08 15:02) [84]
> За пределы ProcessMessages исключения как раз выпускаются.
>
> А вот за пределы WndProc уже нет.
Угу.
> oxffff © (04.09.08 15:14) [85]
> > DiamondShark © (04.09.08 14:56) [83]
> Хитрый жук. :)
Да просто в исходники посмотрел.
> oxffff © (04.09.08 15:02) [84]
> Да действительно, в данном конкретном
> случае может быть несколько лишних итерация цикла.
Как страшно жить. Хорошо, что реальность не соответствует некоторым апокалиптическим представлениям о ней.
> Поскольку мы в большинстве своем пока привыкли писать программы
> где цикл обработки сообщений использует один поток для своей
> работы и один процессор.
При чём здесь цикл сообщений? В моём коде вообще нет ни намёка на сообщения, однако, по-твоему получается, что на многопроцессорной машине его может жестого сглючить. И не только этот код, но и вообще, любой код, содержащий неатомарные операции с памятью. Учитывая, что любой нормальный код из таких операций состоит чуть менее, чем полностью, работоспособных на многопроцессорных системах программ не должно существовать в природе.
Тем не менее, это не так.
> Однако уже сейчас в спешном порядке нужно перестраивать
> свое мышление.
Скажи нет операциям a:=b+c
Тут в одной строчке целых три потенциальных глюка.
← →
Slym © (2008-09-04 16:08) [89]полная версия хака:
uses TlHelp32;
procedure Proc;
begin
ShowMessage("Процедура Proc стартовала");
while True do
begin
Sleep(1); // Это чтобы не грузить процессор
Application.ProcessMessages;
end;
ShowMessage("Процедура Proc завершилась");
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Proc;
end;
type
PImageImportDescriptor = ^TImageImportDescriptor;
IMAGE_IMPORT_DESCRIPTOR = packed record
case Integer of
0: (Characteristics: DWORD);
1: (OriginalFirstThunk: DWORD;
TimeDateStamp: DWORD;
ForwarderChain: DWORD;
Name: DWORD;
FirstThunk: DWORD);
end;
TImageImportDescriptor = IMAGE_IMPORT_DESCRIPTOR;
PFARPROC = ^FARPROC;
const ImagehlpLib = "IMAGEHLP.DLL";
function ImageDirectoryEntryToData(Base: Pointer; MappedAsImage: ByteBool;
DirectoryEntry: Word; var Size: ULONG): Pointer; stdcall; external ImagehlpLib
name "ImageDirectoryEntryToData";
procedure ReplaceIATEntryInModule(pszCallerModName: Pchar; pfnCurrent, pfnNew: FarProc; hmodCaller: hModule);
var
ulSize: ULONG;
pImportDesc: PImageImportDescriptor;
ppfn: PFARPROC;
vp,written:DWORD;
begin
pImportDesc := ImageDirectoryEntryToData(Pointer(hmodCaller), TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, ulSize);
if pImportDesc = nil then exit;
while pImportDesc.Name <> 0 do
begin
if (lstrcmpiA(PChar(hmodCaller+pImportDesc.Name), pszCallerModName) = 0) then
begin
ppfn := PFARPROC(hmodCaller + pImportDesc.FirstThunk);
while ppfn^ <> nil do
begin
if ppfn^=pfnCurrent then
begin
Win32Check(VirtualProtectEx(GetCurrentProcess, ppfn, SizeOf(pointer), PAGE_EXECUTE_READWRITE, @vp));
Win32Check(WriteProcessMemory(GetCurrentProcess, ppfn, @pfnNew, sizeof(pfnNew), Written));
Win32Check(VirtualProtectEx(GetCurrentProcess, ppfn, SizeOf(pointer), vp, @vp));
end;
Inc(ppfn);
end;
end;
Inc(pImportDesc);
end;
end;
procedure ReplaceIATEntryInAllModules(pszCallerModName: Pchar; pfnCurrent, pfnNew: FarProc);
var
hSnapShot: THandle;
me32: MODULEENTRY32;
begin
hSnapShot:=CreateToolHelp32SnapShot(TH32CS_SNAPMODULE, GetCurrentProcessId);
if hSnapshot = INVALID_HANDLE_VALUE then RaiseLastOSError;
try
ZeroMemory(@me32, sizeof(MODULEENTRY32));
me32.dwSize := sizeof(MODULEENTRY32);
Module32First(hSnapShot, me32);
repeat
ReplaceIATEntryInModule(pszCallerModName, pfnCurrent, pfnNew, me32.hModule);
until not Module32Next(hSnapShot, me32);
finally
CloseHandle(hSnapShot);
end;
end;
procedure Intercept(const ModuleName,ProcName:string;const NewProc:FarProc);overload;
var OldProc:FarProc;
begin
OldProc := GetProcAddress(GetModuleHandle(PChar(ModuleName)), PChar(ProcName));
ReplaceIATEntryInAllModules(PChar(ModuleName), OldProc, NewProc);
end;
procedure MySleep;
asm
pop EAX
add EAX, 14
pop EDX
push eax
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Intercept("kernel32.dll","Sleep",@Mysleep);
end;
← →
Игорь Шевченко © (2008-09-04 16:11) [90]народ, а вот если эта...сумму чисел в массиве надо посчитать, ну или там матрицу транспонировать...?
Оно как по-правильному, ась ?
← →
oxffff © (2008-09-04 16:19) [91]
> DiamondShark © (04.09.08 15:42) [88]
>
> > oxffff © (04.09.08 15:02) [84]
> > За пределы ProcessMessages исключения как раз выпускаются.
>
> >
> > А вот за пределы WndProc уже нет.
>
> Угу.
Дык, я тебя поправил.
>
>
> > oxffff © (04.09.08 15:14) [85]
> > > DiamondShark © (04.09.08 14:56) [83]
> > Хитрый жук. :)
>
> Да просто в исходники посмотрел.
>
Вот за это молодец!!!
>
> > oxffff © (04.09.08 15:02) [84]
> > Да действительно, в данном конкретном
> > случае может быть несколько лишних итерация цикла.
>
> Как страшно жить. Хорошо, что реальность не соответствует
> некоторым апокалиптическим представлениям о ней.
>
>
> > Поскольку мы в большинстве своем пока привыкли писать
> программы
> > где цикл обработки сообщений использует один поток для
> своей
> > работы и один процессор.
>
> При чём здесь цикл сообщений? В моём коде вообще нет ни
> намёка на сообщения, однако, по-твоему получается, что на
> многопроцессорной машине его может жестого сглючить. И не
> только этот код, но и вообще, любой код, содержащий неатомарные
> операции с памятью. Учитывая, что любой нормальный код из
> таких операций состоит чуть менее, чем полностью, работоспособных
> на многопроцессорных системах программ не должно существовать
> в природе.
> Тем не менее, это не так.
>
>
> > Однако уже сейчас в спешном порядке нужно перестраивать
>
> > свое мышление.
>
> Скажи нет операциям a:=b+c
> Тут в одной строчке целых три потенциальных глюка.
А что есть гарантия, что переключении когерентность кэшей гарантирована?
Может просто SetProcessAffinityMask у процесса стоит на один процессор.
А если SetProcessAffinityMask
← →
Andy BitOff © (2008-09-04 17:02) [92]> Slym © (04.09.08 16:08) [89]
Как страшно жить.
← →
DiamondShark © (2008-09-04 17:38) [93]
> А что есть гарантия, что переключении когерентность кэшей
> гарантирована?
Вообще-то, когерентность кэшей в SMP-архитектуре обеспечивается аппаратно.
← →
Dmitry S © (2008-09-04 17:44) [94]
> oxffff ©
Ты еще синхронизацию устрой :)
Программа вообще ничего не знает о процессорах. Для нее есть потоки. А то приложение из одной формы и пары кнопок выполняется в одном потоке -> о какой синхронизации речь?
← →
Leonid Troyanovsky © (2008-09-04 18:33) [95]
> Игорь Шевченко © (04.09.08 16:11) [90]
> ну или там матрицу транспонировать...?
Ну, дай орлам хоть слегка, но парить.
--
Regards, LVT.
← →
McSimm © (2008-09-04 18:55) [96]
> McSimm © (04.09.08 09:53) [40]
> > Кстати твое решение правильнее написать так.
> > InterlockedExchange(@FFlag,0);
>
> Зачем это здесь ?
> oxffff © (04.09.08 10:01) [41]
> Во первых при работе на многопроцессорных машинах.
> При переключении кэш другого процессора может не обновиться,
> и утрируя может получится ситуация, когда вы нажали на
> кнопку, а результат не мгновенный.
>
> Однако сейчас ситуация усложняется тем, что есть тенденция
> делать обработку сообщений параллельно. Соответственно
> разные процессоры(ядра) могут не вовремя увидеть изменения.
> И будут задержки.
>
> P.S. Готовь мозг к параллельным вычислениям с молоду.
>
Что-то ерунда какая-то.
Каким образом ваш InterlockedExchange повлияет на обработку сообщения, если он уже в обработчике ? Нажали на кнопку, результат не мгновенный, обработалась очередь и поменялось значение переменной. В том же потоке, в каком и проверяется условие выхода из цикла.
Или я правда пропустил так много изменений за два года отлучения от программирования под Win32 ?
← →
Slym © (2008-09-05 05:22) [97]oxffff © (04.09.08 10:01) [41]
P.S. Готовь мозг к параллельным вычислениям с молоду.
с этим согласен... не согласен с тем что нужно извращаться в полностью линейном вычислении... Это плодит ошибки и неразбериху
Код должен быть простым и без оглядки на многопоточность/процессорность... а вот доступ к шареным объектам - это отдельная проблема и решаться она должна локально и желательно самим объектом согласно ООП
← →
MemoryLeak (2008-09-05 07:34) [98]oxffff © (03.09.08 23:35) [12]
Практическое применение, пример ?
P.S. Это тебе встречная задачка.
← →
Slym © (2008-09-05 07:37) [99]MemoryLeak (05.09.08 7:34) [98]
например яма в ветке защиты ПО... и вылезти из ямы - обойти эту ветку защиты
← →
oxffff © (2008-09-05 09:19) [100]
> MemoryLeak (05.09.08 07:34) [98]
> oxffff © (03.09.08 23:35) [12]
> Практическое применение, пример ?
>
> P.S. Это тебе встречная задачка
А если подумать?
← →
Slym © (2008-09-05 09:26) [101]oxffff © (05.09.08 9:19) [100]
так ты не ответил про мое решение... канает?
← →
oxffff © (2008-09-05 09:56) [102]
> DiamondShark © (04.09.08 17:38) [93]
>
> > А что есть гарантия, что переключении когерентность кэшей
>
> > гарантирована?
>
> Вообще-то, когерентность кэшей в SMP-архитектуре обеспечивается
> аппаратно
Но ведь есть же маленькая глава в MSDN.
Synchronization and Multiprocessor Issues.
Сейчас перечитаю
CHAPTER 18 CACHING, PIPELINING AND BUFFERING
Description
Writes back all modified cache lines in the processor’s internal cache to main memory and invalidates
(flushes) the internal caches. The instruction then issues a special-function bus cycle that
directs external caches to also write back modified data and another bus cycle to indicate that
the external caches should be invalidated.
P.S. Есть подозрение, что возможно планировщик на многопроцессорном тачке, использует WBINVD—Write Back and Invalidate Cache.
Поэтому при переключении данного потока на другой проц все будет зашибись
Чую, что здесь прогнал я. :)
← →
oxffff © (2008-09-05 10:12) [103]
> Slym © (05.09.08 09:26) [101]
> oxffff © (05.09.08 9:19) [100]
> так ты не ответил про мое решение... канает?
Конечно канает, ведь работает же. :)
Страницы: 1 2 3 вся ветка
Форум: "Прочее";
Текущий архив: 2008.10.26;
Скачать: [xml.tar.bz2];
Память: 0.66 MB
Время: 0.011 c