powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Исключение в MoveTo
83 сообщений из 83, показаны все 4 страниц
Исключение в MoveTo
    #39596948
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем доброго дня. Может быть у кого-то будут мысли, почему происходит исключение в такой строке (RootNode, HistoryNode: TTreeNode) :

Код: pascal
1.
RootNode.MoveTo(HistoryNode, naAddChild)



Access violation at address 0000000000D0F2D4 in module 'Project1.exe'. Read of address FFFFFFFFFFFFFFFF.

Код выполняется в Synchronize дополнительного потока.

0000000000D0F280 488B85F0010000 MOV RAX, [RBP+$000001F0]
0000000000D0F287 488B80B8000000 MOV RAX, [RAX+$000000B8]
0000000000D0F28E 488B8838050000 MOV RCX, [RAX+$00000538]
0000000000D0F295 488B85F0010000 MOV RAX, [RBP+$000001F0]
0000000000D0F29C 488B90D0000000 MOV RDX, [RAX+$000000D0]
0000000000D0F2A3 E8C8E8A7FF CALL -$581738 ; ($000000000078DB70) Vcl.TTreeNodes.GetNode
0000000000D0F2A8 488985A0010000 MOV [RBP+$000001A0], RAX
;
; Line=705 - Offset=2703
; ----------------------
0000000000D0F2AF 4883BDA001000000 CMP QWORD PTR [RBP+$000001A0], 0
0000000000D0F2B7 74AD JZ -$53 ; ($0000000000D0F266) EPSessionManager.TEPSessionManager.ProcessEPMessages (Line=703)
;
; Line=706 - Offset=2713
; ----------------------
0000000000D0F2B9 488B85C8010000 MOV RAX, [RBP+$000001C8]
0000000000D0F2C0 488B4028 MOV RAX, [RAX+$28]
0000000000D0F2C4 4889C1 MOV RCX, RAX
0000000000D0F2C7 488B95A0010000 MOV RDX, [RBP+$000001A0]
0000000000D0F2CE 41B002 MOV AL, 2
0000000000D0F2D1 488B18 MOV RBX, [RAX]
;
; Line=706 - Offset=2740
; ----------------------
0000000000D0F2D4 FF5320 CALL QWORD PTR [RBX+$20] ; <-- EXCEPTION


Исключение происходит редко, примерно раз в 3-4 рабочих дня. Программа используется на сервере, чаще всего в удаленной сессии. Вроде бы в момент подключения к сессии проблема случается чаще.
Более глубоко эврика не заходит, несмотря на включенные debug dcu. Я так понимаю, что какая-то из нод становится невалидной. Почему происходит - не ясно.
Операционка - был WS 2003, стал WS2012, на глюк это не повлияло.
Другие части кода, скорее всего, не причастны, так как обработка идёт, в основном, в той процедуре, где случается исключение да и кода относительно немного.
Буду благодарен за идеи.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596950
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonОперационка - был WS 2003, стал WS2012

WS2003 был 64-разрядным ?
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596952
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,

32
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596953
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Начни с того что залогируй содержимое входных параметров в процедуру.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596959
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon0000000000D0F2D1 488B18 MOV RBX, [RAX]
;
; Line=706 - Offset=2740
; ----------------------
0000000000D0F2D4 FF5320 CALL QWORD PTR [RBX+$20] ; <-- EXCEPTION

Шикарный кусок.
"Если не врёшь" - явная ошибка в компиляторе.

1. Поставь все патчи.
2. Покажи полный кусок кода Дельфи на пару строк до и после
3. Попробуй в этом месте отключить ВСЕ оптимизации, {$O-} и вообще всё, что найдешь.

У тебя очень на то похоже, что RBX = @Self (указатель на VMT) и одновременно RBX = naAddChild
Со всеми вытекающими.

Но какого хрена у тебя идёт вызов Self.MoveTo вметсо RootNode.MoveTo ?...
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596961
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonОперационка - был WS 2003, стал WS2012, на глюк это не повлияло.

Перевод всей программы с 32-бит на 64-бита - не повлиял на глюк?
"Ну не наааюююю...."
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596964
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
попробуй сделать локальную процедуру вне всяких классов (прямо в implementation-секции)

типа такой

{$O-} //и м.б. ещё какие-нибудь насйтройки, отключающие лишние куски компилятора
procedure MoveToProxy(const param1: type1; const param2:type2; ....);
var var1: type1; var2:type2; ....
begin
var1 := param1;
var2 := param2;
.....

varN.MoveTo(var1, var2, .... varN-1);
end;

Смысл - убить распихивание переменных по регистрам и навязать их хранение в оперативке на стеке.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596965
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,

вот реальный кусок кода (добавил несколько костылей, которые ограниченно помогли):

Код: pascal
1.
2.
3.
4.
5.
6.
          while not Assigned(Node) do
          begin
           FCsNodeIndex := FinHistoryNode;
           Node := FTV.Items.GetNode(FCsNodeIndex);
          end;
          Session.NodeFields.RootNode.MoveTo(Node, naAddChild);



номер последней строки - 706.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596968
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon,

Node - локальная переменная или свойство Self/with ?

заведи локальную переменную RootNodeProxy
RootNodeProxy := Session.NodeFields.RootNode;
RootNodeProxy.MoveTo(Node, naAddChild);

А еще тяжеловеснее - как я выше написал, сделай внешнюю процедуру
makhaon
Код: pascal
1.
2.
3.
          while not Assigned(Node) do
          end;
          MoveToProxy(Node, naAddChild,  Session.NodeFields.RootNode);
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596969
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,

авторПеревод всей программы с 32-бит на 64-бита - не повлиял на глюк?
"Ну не наааюююю...."

увы, но нет. валится там же. я на ws2012 32 бита тоже ставил - то же самое.

авторпопробуй сделать локальную процедуру вне всяких классов (прямо в implementation-секции)

спасибо, можно попробовать...
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596970
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Где гарантия что у тебя Node - не null?
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596971
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,

Node - локальная переменная
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596972
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat,

обращение по адресу -1 к nil плохо привязывается
если бы было -12 например или другое кратное 4 значение

вариант - он читает неинциализированную память по случайному адресуц и там кто-то зарание забил все пространство -1 чтобы не мусор
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596973
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А, не ошибся.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596974
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat,

Не знаю даже. Может она и становится null'ом между концом while'а и, собственно, MoveTo. Вопрос, как такое может случится? Насколько я вижу по коду - весь доступ к TTreeView синхронизирован.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596975
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon32 бита тоже ставил - то же самое.

сравни ассемблерный код 32-битный и 64-битный

например в отладке в View - Debug windows - CPU, чтобы вперемешку шли паскаль и ассемблер


и еще пищи обсуждение багов применительно к твоей версии компилятора
возможно это исправили в патчах или след. версиях
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596976
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon,
Попробуй Synchronize на Queue заменить
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596978
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,

В коде вроде бы откровенно-космического ничего нет. Обычное гуёвое приложение, менеджер памяти - FastMM, есть несколько потоков. Память и ресурсы потребляет без фанатизма. Ассемблерных вставок, что бы что-то запороть тоже нет. Не понятно, в общем, пока.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596980
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
white_nigger,

пробовал :) то же самое.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596982
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon0000000000D0F2CE 41B002 MOV AL, 2
0000000000D0F2D1 488B18 MOV RBX, [RAX]

вот эта хрень выглядит вызывающе, либо дизассемблер убитый в твоей неизвестноей Дельфи, либо одно из двух

перевожу на Паскаль

Код: pascal
1.
2.
3.
4.
5.
6.
var RBX: Int64; 
     RAX: ^Int64; // 64-битный указатель
       AL: byte absolute RAX // первый из 8 байтов указателя
begin
    AL := 2;
    RBX := RAX^;



Может быть это правильный код, сверх-гениальной подмешивание pезультата из "0000000000D0F2C0 488B4028 MOV RAX, [RAX+$28]" - но я сомневаюсь ,выглядит чтение по полу-члучайному полу-мусорному указателю
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596985
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonВ коде вроде бы откровенно-космического ничего нет.

ошибки компилятора никто не отменял

я в Delphi 2.0 и 4.0 например ловил всякое, хотя тоже было совсем ничего кочмического (сортировка пузырьком и вывод окна логин/пароль)
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596989
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,

XE6, апдейт стоит.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39596998
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon,

есть отличный метод: делаешь минимальный воспроизводимый пример и выкладываешь здесь.
Скорее всего, в процессе создания примера ошибку и локализуешь. :)
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597003
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
41-B0-02 MOV AL, 2
48-8B-18 MOV RBX, [RAX]

http://ref.x86asm.net/coder64.html

41 - Extension of r/m field, base field, or opcode reg field
B0-02 - B0+r MOV r8 imm8

Я не понимаю зачем тут вообще 41, в 32-битном коде должно быть просто B0-02 без левых префиксов

48 - 64 Bit Operand Size
8B-18 - 8B, r MOV r16/32/64 , r/16/32/64 Move
18 вроде бы правильная кодировка пары параметров "RBX, [RAX]" - http://ref.x86asm.net/coder64.html#modrm_byte_32_64

Т.е. дизассемблер вроде бы правилен, в основном, за исключение странного префикса 41

ВОЗМОЖНО там на самом деле команда "MOV R8B, 20" а вовсе не "MOV AL, 02", это было бы гораздо логичнее

А глюков в x64 аcсемблере и дизассемблере у Delphi полно, XE2 был вообще не применим почти

Надо по этому куску проходить в окне CPU Window и смотреть как реально изменяются регистры процессора на каждом шаге.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597006
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем вот этого монстра разрубай на составные части.

через внешнюю процедуру или локальные переменные.

в пределе - не больше одной точки на строчку.

makhaon
Код: pascal
1.
Session.NodeFields.RootNode.MoveTo(
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597014
Соколинский Борис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonБуду благодарен за идеи. Не знаю, поможет или нет.
Сравнительно недавно обнаружил, что при пересоздании окна treeview все адреса node-ов меняются. Возможно, что-то такое имеет место.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597041
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Компилятор тоже человек :) У нас до сих пор танцы с бубнами бывают при вызовах делфовых методов из билдера. Не так давно секс с nullable был. Билдер при использовании в 32-битах неправильно адреса полей генерил, в 64-битах работало нормально. Хз почему ассемблерный выхлоп по разному генерился
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597042
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
*для делфей и билдера в 32-битах
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597076
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Товарищи, там дизасм от EurekaLog, она трейсит в обратную сторону . Поэтому возможно неверное определкние границ команд.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597080
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Соколинский Борис,

Вообще то часть костылей как раз связана с изменением адресов нод. И вроде бы частично помогло, падало по-другому, с nil'ом. У меня есть подозрение, что виновата винда, меняя адреса нод 'на лету'. Сам я ни окно ни дерево не пересоздаю. Окно - главное окно программы, не нем дерево лежит. Ноды, бывает, удаляются, но только уже из History, после MoveTo.

По asm дампу: да, возможно эвкрика не совсем верный дамп показала.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597081
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пока что сделал так:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
{$O-}
          Test1 := Session.NodeFields;
          Test2 := Test1.RootNode;
          MoveToHistory(Test2, Node);
{$O+}

// + локальная процедура в модуле:

{$O-}
procedure MoveToHistory(Node, Node2: TTreeNode);
begin
 Node.MoveTo(Node2, naAddChild);
end;
{$O+}



Поставлю на тест, посмотрю, что получится.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597082
Соколинский Борис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonУ меня есть подозрение, что виновата винда, меняя адреса нод 'на лету'.Это легко проверить: сделай expect-блок и в нем сбрасывай в xml-лог все узлы с адресами.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597084
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дизасм от Delphi:

автор488B85F0010000 mov rax,[rbp+$000001f0]
488B80B8000000 mov rax,[rax+$000000b8]
488B8838050000 mov rcx,[rax+$00000538]
488B85F0010000 mov rax,[rbp+$000001f0]
488B90D0000000 mov rdx,[rax+$000000d0]
E8C8E8A7FF call $000000000012d4c0
488985A0010000 mov [rbp+$000001a0],rax
4883BDA001000000 cmp qword ptr [rbp+$000001a0],$00
74AD jz $00000000006aebb6
488B85C8010000 mov rax,[rbp+$000001c8]
488B4028 mov rax,[rax+$28]
4889C1 mov rcx,rax
488B95A0010000 mov rdx,[rbp+$000001a0]
41B002 mov r8b,$02
488B18 mov rbx,[rax]
FF5320 call qword ptr [rbx+$20]
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597119
Фотография JayDi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
То, что к моменту MoveTo данные уже испорчены и ошибка с лишним Free (или любой другой операции записи в память) была в совсем другом месте -- уже не рассматривается?
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597121
Arioch_really
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
GunSmoker,

Ух ты, в кои-то веки встроенный дизасм лучше стороних утилит!
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597122
kep-ko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
makhaon,
Другие части кода, скорее всего, не причастны,
есть подозрение, что виновата винда


Код: pascal
1.
Access violation at address 0000000000D0F2D4 in module 'Project1.exe'. Read of address FFFFFFFFFFFFFFFF.



Код: plaintext
1.
2.
3.
4.
5.
6.
mov rax,[rbp+$000001c8]  // что-то много на стеке, возможно буфер, за который кто-то вылазит, возможно в другом потоке, из-за чего фантомность ошибки - колись )
mov rax,[rax+$28]
mov rcx,rax
mov rdx,[rbp+$000001a0]
mov r8b,$02
mov rbx,[rax]
0000000000D0F2D4 call qword ptr [rbx+$20]
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597132
Arioch_Really
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
в конвенции Win64 первый четыре параметра передаются в регистрах RCX, RDX, R8, R9
https://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_x64_calling_convention

Self^ указывает на таблицу VMT
http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Internal_Data_Formats_(Delphi)#Class_Types

Session.NodeFields.RootNode.MoveTo(Node, naAddChild);
Параметры:
1) Self = RootNode = RCX
2) (Target) = Node = RDX
3) naAddChild = byte(R8)

код в обратном порядке

Код: asm
1.
2.
3.
4.
5.
6.
7.
call qword ptr [rbx+$20]    ' вызов виртуального метода, вероятно №6 (32/8+1)  из @VMT=Self^=RBX
mov rbx,[rax]                  ' загрузка адреса VMT как первого указателя по адресу Self^ ( aka Self[0] ); RAX = RootNode
mov r8b,$02                    ' загрузка константы в 3-1 аргумент метода
mov rdx,[rbp+$000001a0]  ' загрузка адреса "целевой" ноды из локальной переменной во второй аргумент
mov rcx,rax                     ' загрузка Self вызываемого объекта в первый параметр, RAX = RootNode
mov rax,[rax+$28]            ' загрузка RootNode в RAX; перед этим RAX = NodeFields и RootNode если внутренняя (member) переменная
mov rax,[rbp+$000001c8]  ' загрузка NodeFields из локальной переменной в RAX


Вангую, что Session - это какая-то развесистая локальная переменная типа record, возможно содержащая буфер или рядом с буфером.

Больше инфы в самом деле хотелось бы про процедуру, в которой сбой происходит.

Если там есть буферы - предлагаю вокруг них гарды поставить. И/или поставить гарды вокруг переменной Session.Nodefields
Если кто-то в самом деле затирает чужую память, не адресно выстрелил и попал, а размашисто разогнался и не успел остановиться, то гарды он по идее тоже должен будет снести и в memory dump стэка это будет заметно

можно предположить use after free, но тогда обычно память при освобождение забивают чем-то более забойным, чем -1

Пока мне кажется, что происходит корерктной получения указателя на VMT - а вот дальше адрес метода оказывается -1

Почему, что это значит - хз. Может быть так абстрактные методы обозначаются? Информации не нашёл сходу.
Но вот интересный момент: http://members.tripod.com/~s_mathur/Virt.html
Смотрим на второй дамп, это как раз VMT (или в терминах Visual C++, V-table).
В классе есть только одна виртуальная функция - и первые 4 байта VMT заполнены
А вот дальше идёт FF-FF-FF-FF - та самая минус единица.
То ли добивают размер VMT до кратного 8, либо после последней "легитимной" функции в качестве маркера ставят "якобы еще один метод" с адресом -1

Если так предположить, то похоже иногда в переменной Session.NodeFields.RootNode оказывается указатель не на TNode (или что там должно быть), а на объект какого-то другого класса, например предка или вообще от фонаря какого-нибудь, и у этого другого класса 5 либо меньше виртуальных методов и никакого метода №6 (MoveTo) у него вообще нет (или м.б. абстрактный????).

В общем, в порядке параной перед выводом MoveTo пробуй проверить какого типа там хрень лежит, возможно иногда совсем не того, который ты ожидаешь
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597137
Arioch_Truly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
makhaon Сам я ни окно ни дерево не пересоздаю.

.RecreateWnd никто не отменял при изменении настроек контрола или окна, которые можно менят ьв VCL и нельзя в Windows GDI API

Меня в свое время СИЛЬНО ругали на Stack Overflow за передачу TForm.Handle в поток, хотя лёгкой практической альтернативы так и не предложили. Говорили, дескать, по любому чиху у главной формы поменяется Handle и будет мой поток PostMessage на деревню дедушке слать.

Предложение - вообще НЕ передавать в поток никаких указателей на объекты.
Высылать команды, например "Ноду с ID=xxxx переместить под ноду с ID=yyyy"
Что у тебя в контексте твоей задачи будет логический ID ноды - тебе виднее.

Такие команды можно высылать например через PostMessage на специально для того заведённое невидимое окно (CreateHWND).
Или использовать глобальную переменную с синглтоном TThreadList<TmyCommandRecord>
Или коллекцию из OmniThreadLibrary

В общем, рабочий поток НЕ пользуется синхронайзом, а посылает в VCL-поток команды семантические, в терминах задачи, а не контролов.
А уже сама форма, в VCL-потоке, когда до нее доберётся это сообщение, поймёт что нужно найти две ноды по ID и поместить одну внутрь другой.
Геморроя прописывать явно все виды "семантических" сообщений может быть много. Зато изоляция, потом например сможешь поменять TTreeView на TVirtualTreeview или VCL на FMX и "рабочие" потоки вообще это никак не заденет.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597140
Соколинский Борис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch_TrulyМеня в свое время СИЛЬНО ругали на Stack Overflow за передачу TForm.Handle в поток, хотя лёгкой практической альтернативы так и не предложили.

Элементарно, Ватсон.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
type
IWndHandler=interface
[какой-то гуид]
function GetHandle: hwnd; 
property Handle: hwnd read GetHandle;
end;

TWndHandler=class(TInterfacedObject, IWndHandler)
private
  FControl: TWinControl;
protected
  function GetHandle: Hwnd;
{ begin result:=FControl.Handle; end;}
public
  constructor Create(AControl: TWinControl);
end;


IWndHandler передаешь в поток.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597143
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Соколинский БорисЭлементарноЯ бы так не сказал.

Если хэндл имеет тенденцию меняться, то нужна какая-то синхронизация. Это раз.

Вызов TWinControl.GetHandle может спровоцировать HandleAllocate и создание окна в другом потоке
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597145
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подозреваю, что один из самых простых способов - это передавать в поток ThreadID главного потока, а в потоке дергать PostThreadMessage. Для синхронных сообщений пишется небольшая обвязка
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597146
fd00ch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch_TrulyМеня в свое время СИЛЬНО ругали на Stack Overflow за передачу TForm.Handle в поток, хотя лёгкой практической альтернативы так и не предложили. Говорили, дескать, по любому чиху у главной формы поменяется Handle и будет мой поток PostMessage на деревню дедушке слать.правильно ругали, AllocateHWnd же есть
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597150
kep-ko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Arioch_Truly, @offtop
Говорили, дескать, по любому чиху у главной формы поменяется Handle и будет мой поток PostMessage на деревню дедушке слать.
Ребятам по молодости сказали кушай как-тус, а теперь чтоб в седую бороду не признаваться, что подкол не поняли, так дальше муть и разливают.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
procedure TWinControl.HandleNeeded;
begin
  if WindowHandle = 0 then
  begin
    if Parent <> nil then Parent.HandleNeeded;
    CreateHandle;
  end;
end;

function TWinControl.GetHandle: HWND;
begin
  HandleNeeded;
  Result := WindowHandle;
end;
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597152
Соколинский Борис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,
Можно проверять HandleAllocated. А в синхронизации необходимости не вижу.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597153
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Соколинский Борис_Vasilisk_,
Можно проверять HandleAllocated. А в синхронизации необходимости не вижу.Ну. И если оно = False - что дальше?
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597155
Соколинский Борис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,
Вернуть 0. В потоке - если нужна синхронная обработка - подождать, Нет - послать позже.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597427
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fd00chправильно ругали, AllocateHWnd же есть

К нему нет обвязки, сравнимой по удобству с созданием метода TMainForm.OnMySuperMessage
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597432
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kep-ko,

я знаю этот кусок :-)

Соколинский БорисМожно проверять HandleAllocated. А в синхронизации необходимости не вижу.

1) .....вот когда при напряжной работе Хэндл убьётся сразу после проверки HandleAllocated..... Хотя, конечно, можно сам объект формы поточно лочить, но в Delphi RTL TMonitor.Lock (кажется) реализован довольно медленно
2) про False уже сказали
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39597549
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AriochК нему нет обвязки,Написать обвязку - полминуты и пять строк кода
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
procedure TForm1.GetWindow: HWND;
begin
  CheckMainThread;
  if FWindow = 0 then
    FWindow := AllocateHWnd(InternalWndProc);
  Result := FWindow;
end;

procedure TForm1.InternalWndProc(var AMessage: TMessage);
begin
  Dispatch(AMessage);
end;
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39598378
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Новые данные.
Что сделал. Удалось отказаться от доп. потока и сделать выполнение процедуры в основном потоке, по событию таймера.
На баг никак не повлияло. Исключение то же. Колл-стэк завёл в процедуру MoveToHistory, то есть до этого не свалилось.

Вот ассемблерный дамп эврики (к слову - с большим трудом нашел как его скопировать из вьювера. вообще - во вьювере есть несколько неудобств):

автор; Base Address: $D0E000, Allocation Base: $400000, Region Size: 5046272
; Allocation Protect: PAGE_EXECUTE_WRITECOPY, Protect: PAGE_EXECUTE_READ
; State: MEM_COMMIT, Type: MEM_IMAGE
;
;
; EPSessionManager.MoveToHistory (Line=455 - Offset=0)
; ----------------------------------------------------
0000000000D0E760 55 PUSH RBP
0000000000D0E761 53 PUSH RBX
0000000000D0E762 4883EC28 SUB RSP, $28
0000000000D0E766 488BEC MOV RBP, RSP
0000000000D0E769 48894D40 MOV [RBP+$40], RCX
0000000000D0E76D 48895548 MOV [RBP+$48], RDX
;
; Line=456 - Offset=17
; --------------------
0000000000D0E771 488B4D40 MOV RCX, [RBP+$40]
0000000000D0E775 488B5548 MOV RDX, [RBP+$48]
0000000000D0E779 41B002 MOV AL, 2
0000000000D0E77C 488B4540 MOV RAX, [RBP+$40]
0000000000D0E780 488B18 MOV RBX, [RAX]
;
; Line=456 - Offset=35
; --------------------
0000000000D0E783 FF5320 CALL QWORD PTR [RBX+$20] ; <-- EXCEPTION
;
; Line=457 - Offset=38
; --------------------
0000000000D0E786 488D6528 LEA RSP, [RBP+$28]
0000000000D0E78A 5B POP RBX
0000000000D0E78B 5D POP RBP
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39598385
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторВысылать команды, например "Ноду с ID=xxxx переместить под ноду с ID=yyyy"

Какие конкретно ID?
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39598414
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonвыполнение процедуры в основном потоке,
На баг никак не повлияло.

Ч.Т.Д.

21168555

Ariochпохоже иногда в переменной Session.NodeFields.RootNode оказывается указатель не на TNode (или что там должно быть), а на объект какого-то другого класса
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39598415
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonКакие конкретно ID?

business domain

это уже тебе виднее, какие данные в твоей прикладной задаче позволяют уникально идентифицировать те или иные сущности
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39598473
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,

попробую пока что костыль:

автор if (Node is TTreeNode) and (Node2 is TTreeNode) then
Node.MoveTo(Node2, naAddChild);

посмотрим, как повлияет.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39598516
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon,

тогда уж и логирование вставь
Код: pascal
1.
....else OutputDebugString(PChar('Оппаньки! ' + Node.ClassName + '  /  ' + Node2.ClassName + ^M^J) );



....но если там и вовсе не объект а какой-то просто мусор, то оно свалится на вызове ClassName

что, впрочем, тоже будет вполне себе результат.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39598521
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а лучше еще и заложиться, что у тебя в разных модулях могут быть классы с одинаковым названием

http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.TObject.QualifiedClassName

а если такого нет, то http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.TObject.UnitName
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39598525
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon, помимо прочего, в EurekaLog есть IsValidObject в ELowLevel.

Кстати, memory-функции EurekaLog используются? А то там есть очистка удаляемой памяти. Может, у тебя ссылка где-то на удалённый объект.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39598542
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GunSmokerА то там есть очистка удаляемой памяти

и он затирает минус единицами вместо какого-нибудь наглядно-вычурного DEADBEEF ?
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39598577
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ariochи он затирает минус единицами вместо какого-нибудь наглядно-вычурного DEADBEEF ?

Нет, нулями или DEADBEEF в зависимости от настроек.

P.S. У меня стойкое ощущение, что -1 тесно связана с nil, но не могу вспомнить / сообразить, когда это бывает.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39598586
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon, под отладчиков же воспроизводится???

Можно так:
Код: pascal
1.
2.
3.
4.
5.
6.
try
  RootNode.MoveTo(HistoryNode, naAddChild);
except
  DebugBreak;
  RootNode.MoveTo(HistoryNode, naAddChild);
end;



Отладчик встанет, можно будет и аргументы проанализировать и по шагам повторить.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39598632
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GunSmoker,

авторmakhaon, под отладчиков же воспроизводится???

увы, все разумные варианты завалить под отладкой ни к чему не привели. оно то и в жизни падает нечасто. но, увы, стабильно :(

В эврике включено catch memory problem и fill freed memory with zeros.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39598643
kep-ko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
makhaon, https://blogs.msdn.microsoft.com/vijaysk/2012/10/26/tools-to-simulate-cpu-memory-disk-load/

ps. вирусы, антивирусы, спец-софт-дрова на испытуемом есть?
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39599670
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kep-ko,

вирусы - крайне маловероятно. антивирус - nod32 и на 2003-м был и сейчас, на 2012 остался. вообще - то он как-то не замечен за пакостями. не думаю я на него.

Код: pascal
1.
IsValidObject



добавил в проверки. посмотрю, спасибо.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39608434
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем, нашли закономерность, когда падает. При логине по RDP или при переключении пользователей. Пробую ловить WM_WTSSESSION_CHANGE, временно отключать обработку дерева, потом включать назад. Увы, но не помогло. При включении почти сразу же валится с AV, как обычно. В разных местах на доступе к элементам дерева.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39608469
Соколинский Борис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon,
Я бы подумал в сторону изменения архитектуры а-ля MVC.
Привязка к спонтанно изменяемым структурам не есть хорошо в любом случае.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39608489
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Врятли mvc поможет, если дерево тупо валится при смене юзера.
Удалось сделать минимальное приложение.
Воспроизведение бага: запускаем под отладкой. Сменяем пользователя на другого, обычным способом, заходим назад - получаем AV.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39608493
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Среда - XE6, как уже писал. Версия операционки, скорее всего, особо значения не имеет.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39608498
Соколинский Борис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonВрятли mvc поможет, если дерево тупо валится при смене юзера.

Валится не дерево, а твой код, который оперирует неустойчивыми параметрами вроде ItemID.
Просто работай с inmem-tree (типа XML) и пересоздавай его визуальное представление при модификациях.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39608499
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch_TrulyМеня в свое время СИЛЬНО ругали на Stack Overflow за передачу TForm.Handle в поток, хотя лёгкой практической альтернативы так и не предложили.

Если очень хочется передать TForm.Handle в поток, то это можно делать. Следует лишь понимать, что тогда в рантайме не нужно изменять некоторые свойства формы, которые приводят к RecreateWnd (например, BorderStyle).
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39608505
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonСменяем пользователя на другого, обычным способом, заходим назад - получаем AV.

Т.е. выводим пользователи из interactive desktop - все окна (GDI objects) фактически уничтожаются

Входим обратно - создаются заново.

А дальше - что угодно, от левых HWND и до потерянных дополнительных байтов информации, привязанных к внутренним структурам Windows (всякие getWindowLong)

Предположение проверял?

Ariochпохоже иногда в переменной Session.NodeFields.RootNode оказывается указатель не на TNode (или что там должно быть), а на объект какого-то другого класса
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39608506
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Квейдчто тогда в рантайме не нужно изменять некоторые свойства формы

....через 3 года они покупают нвоую версию Delphi с частично переписанным VCL и....
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39608510
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КвейдArioch_TrulyМеня в свое время СИЛЬНО ругали на Stack Overflow за передачу TForm.Handle в поток, хотя лёгкой практической альтернативы так и не предложили.

Если очень хочется передать TForm.Handle в поток, то это можно делать. Следует лишь понимать, что тогда в рантайме не нужно изменять некоторые свойства формы, которые приводят к RecreateWnd (например, BorderStyle).

кое-что проверил, уточняю:

КвейдСледует лишь понимать, что тогда в рантайме не нужно изменять некоторые свойства формы, которые приводят к RecreateWnd (например, Parent).
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39608514
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,

У меня было предположение, что винда свои деревья во время перелогина или захода на rdp полностью или частично пересоздаёт. Ну ок, если так. Но сделать то что? :)
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39608563
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1) не смешивать данные и визуальные компоненты

2) поменять компонент дерева
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39608565
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Телепаты существуют! 21167771

Соколинский БорисСравнительно недавно обнаружил, что при пересоздании окна treeview все адреса node-ов меняются. Возможно, что-то такое имеет место.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39608566
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch1) не смешивать данные и визуальные компоненты

21168599
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39608599
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,

Если бы мой код был :) Я может быть так и не писал совсем. Человека уж нет, кто делал, а проблема есть.
Есть какие-то замены кроме TVirtualTreeView?
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39608632
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а кто сказал, что VTV поможет? проверяли ?

если нельзя изменить код, то все очень грустно. Ну тогда запретите на этой машине RDP, начиная с "быстрой смены пользователей", как эта служба называлась в WinXP

кстати, идея для ещё одного эксперимента - не надо переключать пользователеЙ, просто поменяйте разрешение и глубину цветности экрана при работающей прогpамме без перезагрузки.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39608644
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,
автора кто сказал, что VTV поможет? проверяли ?
тоже не факт. пока что сделал некий костыль, уничтожаю все данные при подключении - все ветки дерева, обвязочные классы и занова отрисовываю всё. часть информации, правда, может потеряться (история). но это не критично. главное - стабильность.

авторесли нельзя изменить код, то все очень грустно.
код можно полностью переписать, только я не вижу особой целесообразности. текущему виду интерфейса у нас уже мало осталось 'жить'. всё уходит в унигуй.
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39609294
kep-ko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
makhaonArioch,У меня было предположение, что винда свои деревья во время перелогина или захода на rdp полностью или частично пересоздаёт. Ну ок, если так. Но сделать то что? :)не винда, а vcl ))
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
procedure TForm.FormCreate(Sender: TObject);
begin
 OldTv := Tv.WindowProc;
 Tv.WindowProc := NewTv;
end;

procedure TForm.NewTv(var Message: TMessage);
begin
 if Message.Msg <> CM_RECREATEWND then OldTv(Message);
end;
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39609295
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonтекущему виду интерфейса у нас уже мало осталось 'жить'. всё уходит в унигуй.

как раз наоборот, именно поэтому и надо переписывать

потом останется только кусок VCLный заменит ьна кусок UniGUIный, а остальное уже переписано заранее


AriochArioch1) не смешивать данные и визуальные компоненты

21168599
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39609296
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kep-ko,

Угу, потом оно вообще никогда не будет пересоздавтаь, даже тогда, когда надо
...
Рейтинг: 0 / 0
Исключение в MoveTo
    #39609376
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,

может и так. посмотрим. поправил, пока что нормально работает. хистори не сохраняется, но и ладно. она там почти всегда 'онлайн' нужна. в крайнем случае, можно не вылогиниваться какое-то время.
...
Рейтинг: 0 / 0
83 сообщений из 83, показаны все 4 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Исключение в MoveTo
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]