Комментарии 29
2. Подливаем обновленный объектник по-живому в память (при необходимости выделяем ещё или используем пустые хвосты в конце последних страниц секций)
3. Ручками разрешаем символы как это делает динамический загрузчик в подлитом объектнике превращая его в рабочий код
4. Перекидываем на него GOT/PLT
5. Восстанавливаем работу процесса
6. Все это делается внешним относительно пациента приложением
Ну это так. Очень мазками по верхам. Когда-то давно приходилось автоматически патчить по-живому. После определенных трахов вполне работает.
Отправить им SIGSTOP?
В смысле через pthread_kill
? Вы пробовали провернуть такое? Из того, что удалось нагуглить, это не сработает, но надо пробовать
Ну типа
for pid in thread_list
kill(pid, SIGSTOP)
И еще завернуть это в цикл, пока что-то было остановлено
kill — send signal to a process
Ну я не уверен, насколько мой вариант хорош, но суть ваших претензий не совсем понимаю. В linux потоки — нечто, не слишком отличное от процесса, и запуск потока это вроде как clone(CLONE_VM|CLONE_THREAD).
Signal dispositions are process-wide: if a signal handler is
installed, the handler will be invoked in the thread thread, but if
the disposition of the signal is «stop», «continue», or «terminate»,
this action will affect the whole process.
Поэтому и сомневаюсь
Я мимокрокодил, но вроде бы нужные дырки предусмотрены:
https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html
В частности, интуиция подсказывает, что можно применить -finstrument-functions.
Generate N NOPs right at the beginning of each function, with the function entry point before the Mth NOP. If M is omitted, it defaults to 0 so the function entry points to the address just at the first NOP. The NOP instructions reserve extra space which can be used to patch in any desired instrumentation at run time, provided that the code segment is writable. The amount of space is controllable indirectly via the number of NOPs; the NOP instruction used corresponds to the instruction emitted by the internal GCC back-end interface gen_nop. This behavior is target-specific and may also depend on the architecture variant and/or other compilation options.
Собственно то, чего не хватало автору на сколько я понимаю
В статье идет речь о том, как без перезапуска приложения обновить в нем работающий машинный код
Во, все-таки обновляется машинный код, а не С++, а по заголовку кажется не так…
Ладно, это я уже придираюсь, наверное. Статья весьма интересная, плюсанул )
Библиотека, которая реализует эту функциональность, написана на c++, пользовательское приложение, к которому линкуется библиотека, должно инстанциировать экземаляр c++ класса, вызывать методы этого c++ класса, возможно реализовать обработку коллбеков от библиотеки в виде наследования от класса-делегата, который тоже является c++ классом. Конечно, при большом желании это можно делать и из не-c++ кода, и перезагружать не-c++ код, но конкретно в этой статье речь идет о c++.
Предлагаю закрыть тему с названием статьи.
Чтобы два раза не вставать — почему вы сделали все в одном приложении, а не два разных процесса? Вроде с двумя процессами часть проблем уходит.
По поводу процессов — если честно, просто не подумал об этом. Только на днях вспомнил, что автор библиотеки под windows так и делает, и задумался о том, что не спроста. В комментарии выше человек посоветовал порождать процесс из приложения, и в нем делать всю грязную работу, видимо так и придется сделать.
Напомнило gdb code injections, ещё из полезных фитч есть запись трассе и шаг назад, вроде бы это называется back in time debagger. Помню ещё давно школьник писал статью про модификацию того же gdb где программа форкалась. Из интересного но врядли имеющего отношение к делу есть обратное исполнение, вроде бы был даже коммерческий дебагер с такой возможность, заранее извиняюсь, в плане технологий я больше каталог. Точно помню что это было у меня в заметках года два три назад, пороюсь отпишусь. Конечно мало отношения к тематике стать, но вдруг кого заинтересует
Реализация горячей перезагрузки С++ кода в Linux