Сейчас на форуме: zds (+5 невидимых)

 eXeL@B —› Программирование —› CreateThread & x64
Посл.ответ Сообщение


Ранг: 462.8 (мудрец), 468thx
Активность: 0.280
Статус: Участник
Only One!

Создано: 03 апреля 2014 18:27 · Поправил: OnLyOnE
· Личное сообщение · #1

Задача запустить несколько потоков в собственном приложении (х64).
На х86 проблем не возникает, т.к. вновь порожденный поток наследует контекст родительского потока.
Под х64 все иначе. Контекст полностью меняется.
И как следствие приложение валиться.
У меня вопрос к кодерам, кто писал подобное.
Как правильно организовать запуск нового потока с передачей контекста родительского потока?
Может есть у кого партированная структура под ассемблер?

P.S. С получением контекста удаленного потока все ясно, суспендим и получаем контекст.
А что делать с родным потоком? Суспендить не получится

-----
aLL rIGHTS rEVERSED!





Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 03 апреля 2014 19:44 · Поправил: Модератор
· Личное сообщение · #2

OnLyOnE пишет:
вновь порожденный поток наследует контекст родительского потока

Щито-щито?

Судя по описанию, там торчали какие-то махровые костыли, которые закономерно отвалились в х64. Под контекстом в данном случае понимается стандартный контекст со значениями регистров, полагаю? И для чего может понадобиться копировать их все? Судя по всему, нормально это не сделать, придётся писать на асме заполнение контекста, передавать его параметром в поток, где в нём первым делом заполнять регистры из переданного контекста.

fork для процессов, а тут вроде как плодить потоки в своём процессе. Форкать потоки сходу не вижу смысла, коль и так на любую функцию можно вызывать.



Ранг: 71.2 (постоянный), 33thx
Активность: 0.050.12
Статус: Участник

Создано: 03 апреля 2014 19:47
· Личное сообщение · #3

Может человек пытается fork() запилить под венду?




Ранг: 462.8 (мудрец), 468thx
Активность: 0.280
Статус: Участник
Only One!

Создано: 03 апреля 2014 20:12
· Личное сообщение · #4

Archer пишет:
Судя по описанию, там торчали какие-то махровые костыли, которые закономерно отвалились в х64.


Костылей вроде нет. Потоки используют глобальные ресурсы (переменные,константы и т.д.) , т.е. зависимости от стека нет никакой. Прога сыпется на АПИ Shell32 а именно на SHGetSpecialFolderPathW.
По коду ничего сверх естественного
Code:
  1. invoke SHGetSpecialFolderPathW,NULL,addr BufferW,CSIDL_SYSTEM,0

BufferW - буфер в глобале, не в стеке.

И валиться именно в недрах Shell32. Этот же код запускаю без потока, все работает.

-----
aLL rIGHTS rEVERSED!





Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 03 апреля 2014 20:18
· Личное сообщение · #5

Честно говоря, я так и не уловил, при чём тут потоки, зачем контекст, какое-то его заполнение и тд, если банально не работает функция, и надо просто брать и отлаживать, а не тыкать пальцем в небо.
И да, эта функция is not supported, а если что. А следующая, на которую скорее всего падёт взор, SHGetFolderPath deprecated.




Ранг: 462.8 (мудрец), 468thx
Активность: 0.280
Статус: Участник
Only One!

Создано: 03 апреля 2014 20:42 · Поправил: OnLyOnE
· Личное сообщение · #6

Archer пишет:
Честно говоря, я так и не уловил, при чём тут потоки, зачем контекст, какое-то его заполнение и тд, если банально не работает функция, и надо просто брать и отлаживать, а не тыкать пальцем в небо.


Я же объяснил, что одна и таже функция не работает в отдельно запущенном потоке, в обычном
варианте все работает. Единственное что меняется при вызове функции это контекст.
Ибо в своем коде было уже грешить не на что.
Кстати, SHGetFolderPathW падает на том же месте (смещении), что и SHGetSpecialFolderPathW.
Code:
  1. Сигнатура проблемы:
  2.   Имя события проблемы:    APPCRASH
  3.   Имя приложения: 123X64.exe
  4.   Версия приложения:       6.1.7601.17514
  5.   Отметка времени приложения:       533d8cda
  6.   Имя модуля с ошибкой:    SHELL32.DLL
  7.   Версия модуля с ошибкой: 6.1.7600.16385
  8.   Отметка времени модуля с ошибкой: 4a5be054
  9.   Код исключения: c0000005
  10.   Смещение исключения:     000000000007a38c
  11.   Версия ОС:      6.1.7600.2.0.0.256.48


Archer пишет:
надо просто брать и отлаживать, а не тыкать пальцем в небо

И что здесь отлаживать,Shell32?

P.S. Кстати, по ходу написания кода х64 наткнулся еще на один артефакт.
В Win8.1 x64 пытаюсь загрузить тот же пресловутый Shell32.dll LoadLibraryW (LoadLibraryA)
В приложении загружает, из DLL нет. Тут нет никаких потоков, замете.
Начал отлаживать, выясняется, что адрес строки с названием либы по непонятным причинам просто перезаписывается левым... Причем с kernel32.dll все отлично! Грузит и в проге и в ДЛЛ.
Так вот.. все проблемы крутятся вокруг Shell32 и х.з. почему.

-----
aLL rIGHTS rEVERSED!




Ранг: 112.9 (ветеран), 186thx
Активность: 0.090.01
Статус: Участник

Создано: 03 апреля 2014 21:06 · Поправил: vden
· Личное сообщение · #7

А есть тестовый бинарник?

Я попробовал вызвать SHGetSpecialFolderPath из созданного потока в exe x64, вроде ничего не валится. win 8.1

PS вполне может быть что нужен align 16 для параметров




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 03 апреля 2014 21:18
· Личное сообщение · #8

И в чём проблема отладить shell32? Вроде, форум ревёрсеров, брать ольку/виндбг, подгружать символы да отлаживать. А проблем может быть овер 9000, каких я только неочевидных проблем и на первый взгляд невозможных вещей ни видел, когда отлаживал. Уж всяко лучше, чем тыкать пальцем в небо. Но если так хочется потыкать, вангую, что контекст совершенно не при чём, а что не выровнено что-то где-то, стек или какие переменные.




Ранг: 462.8 (мудрец), 468thx
Активность: 0.280
Статус: Участник
Only One!

Создано: 03 апреля 2014 21:25 · Поправил: OnLyOnE
· Личное сообщение · #9

vden пишет:
А есть тестовый бинарник?


Вот элементарно это не работает даже под 7 х64

Archer пишет:
не выровнено что-то где-то, стек или какие переменные

Я ехешник приаттачил.. там выравнивать нечего..

Еще один артефакт. Если туже SHGetSpecialFolderPathW вызвать вначале в основном потоке а потом в новом то все работает.
Но мне ее 2 раза вызывать не надо...
И как это можно объяснить?

aefc_03.04.2014_EXELAB.rU.tgz - testX64.exe

-----
aLL rIGHTS rEVERSED!





Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 03 апреля 2014 21:57 · Поправил: Модератор
· Личное сообщение · #10

Это называется: я не хочу отлаживать, поотлаживайте вы за меня. А глядя на файл, ещё хочется добавить: я не читаю спеку по х64 и не хочу слушать других.
OnLyOnE пишет:
там выравнивать нечего

А теперь прочитай внимательно про х64 стек. Изменишь на sub rsp,28 по 40106B-и всё будет работать.
З.Ы. Писал бы на нормальном языке-и не было бы таких проблем.

| Сообщение посчитали полезным: OnLyOnE


Ранг: 462.8 (мудрец), 468thx
Активность: 0.280
Статус: Участник
Only One!

Создано: 03 апреля 2014 22:11
· Личное сообщение · #11

Archer пишет:
А теперь прочитай внимательно про х64 стек. Изменишь на sub rsp,28 по 40106B-и всё будет работать.


Так компилирует фасм.
Спасибо.

-----
aLL rIGHTS rEVERSED!



 eXeL@B —› Программирование —› CreateThread & x64
Эта тема закрыта. Ответы больше не принимаются.
   Для печати Для печати