Как получить указатель стека и адрес возврата и восстановить их в предыдущее состояние

Я пытаюсь реализовать вызов бедняка с текущим продолжением для программы, написанной на C. Я могу «легко» получить доступ и записать в память соответствующую часть стека C (очевидно, это непереносимо и полно UB, но я уже укусил эту пулю).

Мне интересно, как получить фактический указатель стека и адрес возврата и как их восстановить. У меня такое впечатление, что мне, вероятно, удастся сделать это только для указателя стека (надеюсь, сам обратный адрес будет спрятан внутри фрагмента стека, который я скопировал и восстановил).

Я подозреваю, что это потребует некоторой сборки, но я надеюсь, что в идеале есть какой-нибудь умный способ избежать этого.

Я бы удалил часть «или что есть библиотека, которая делает для меня неприятные вещи, или, в худшем случае, какой-то существующий код, который я мог бы скопировать, который имеет аналогичные потребности и имеет необходимый встроенный ASM для обычно подозрительных ISA». так как это близкая приманка. Если кто-то знает о такой библиотеке, я уверен, что они все равно расскажут.

Ted Lyngmo 03.07.2024 18:06

Поскольку, как вы говорите, это непереносимо, вам следует упомянуть и пометить реализацию (реализации), на которую вы хотите ориентироваться. Если он отмечен только тегом c, предполагается, что вы полностью работаете в рамках стандарта ISO.

Nate Eldredge 03.07.2024 18:06

Нельзя ли это сделать (конечно, непереносимым способом) с помощью setjmp? Я имею в виду, что это почти то же самое, что и вызов /cc, но (и это большое но) из-за того, что вы можете идти только вниз по стеку (то есть вы можете вернуться к вызывающему абоненту или к вызывающему абоненту). , или... ; но не, в отличие от вызова /cc, возврата к ранее вызванной функции. Стек с setjmp по-прежнему остается тем же классическим стеком, просто его можно быстро разложить. "стек" с call/cc)

chrslg 03.07.2024 18:24

Но, тем не менее, setjmp хранит все необходимое (указатель стека, регистры и т. д.). Это UB, если используется с устаревшим стеком, но его можно объединить с уродливой копией стека, которую вы собираетесь сделать...

chrslg 03.07.2024 18:25

Вас интересуют протопотоки? dunkels.com/adam/pt

KamilCuk 03.07.2024 18:30

Пахнет «ху-вопросом». Какую реальную проблему вы пытаетесь здесь решить? Вы реализуете переключение контекста RTOS или что-то подобное?

Lundin 04.07.2024 12:43

@chrslg: Спасибо, спасибо, спасибо! Не стесняйтесь превратить это в ответ. Не знаю, почему я об этом не подумал, но действительно setjmp должен делать именно то, что мне нужно. После копирования старой копии стека (ранее записанной одновременно с setjmp) обратно в текущий стек я смогу использовать longjmp, чтобы «воскресить» старое состояние.

Stefan 04.07.2024 22:20

@NateEldredge: Я бы хотел, чтобы он работал на Windows, Android, macOS, GNU/Linux (для ОС) и Armhf, Arm64, riscv, i386 и amd64 (для ISA), как с GCC, так и с LLVM. Не знаю, как пометить эту «реализацию».

Stefan 04.07.2024 22:30

@ikegami: Спасибо за указатель на get/setcontext. Я не знал об этих новых альтернативах (sig)longjmp.

Stefan 04.07.2024 22:32
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
10
89
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

По запросу мои комментарии в форме ответа (правда, вы делаете что-то настолько конкретное, что я сомневаюсь, что кто-нибудь с таким же вопросом когда-нибудь это прочитает :D)

Вероятно, это можно было бы сделать (конечно, непереносимым способом) с помощью setjmp/longjmp. То есть это почти то же самое, что и call/cc, но (и это большое но) из-за того, что идти можно только вниз по стеку. Итак, вы можете вернуться к вызывающему абоненту, или к вызывающему абоненту, или... ; но не, в отличие от call/cc, возвращаться «назад» к ранее вызванной функции в столь же нелинейном стеке, как временная шкала Марти МакФлая. Стек с setjmp остается тем же классическим, линейным стеком, только его можно быстро разложить. Это не неявное дерево, которое представляет собой стек с вызовом/cc.

Но, тем не менее, setjmp хранит все необходимое (указатель стека, регистры и т. д.). Это UB, если используется с устаревшим стеком, но его можно объединить с уродливой копией стека, которую вы собираетесь сделать...

Другие вопросы по теме