Может ли ptrace () в 64-битной версии Linux возвращать двойное число? - PullRequest
0 голосов
/ 25 августа 2018

Предполагая, что addr является адресом локальной переменной в стеке, существуют ли следующие правильные способы получения значений переменных (ChildPid - это идентификатор трассировки)?

double data = (double) ptrace(PTRACE_PEEKDATA, ChildPid, addr, 0);

float data = (float) ptrace(PTRACE_PEEKDATA, ChildPid, addr, 0);

Спасибо.

Ответы [ 2 ]

0 голосов
/ 25 августа 2018

Приведение long к double не даст вам желаемого результата.Приведение чисел преобразует числовое значение, оно не копирует биты.Вам нужно что-то вроде:

long pt = ptrace(PTRACE_PEEKDATA, ChildPid, addr, 0);
double result;
assert (sizeof(pt) == sizeof(result), "Oops, wrong word size!");
memcpy (&result, &pt, sizeof(result));

Чтобы получить float, вам нужно знать, какую половину слова он занимает (обычно вы не должны использовать addr, который не выровнен по отношению кграница слова).Таким образом вам нужно что-то вроде следующего:

long pt = ptrace(PTRACE_PEEKDATA, ChildPid, addr, 0);
float result;
assert (sizeof(pt) == 2*sizeof(result), "Oops, wrong word size!");
// either this (for the lower half of the word)
memcpy (&result, &pt, sizeof(result));
// or this (for the upper half of the word)
memcpy (&result, ((char*)&pt)+sizeof(result), sizeof(result));
0 голосов
/ 25 августа 2018

В документации сказано, что PTRACE_PEEKDATA возвращает слово. Там также написано

Размер слова определяется вариантом операционной системы (например, для 32-битного Linux это 32 бита).

Таким образом, вы не можете надежно использовать один вызов ptrace(), чтобы получить удвоение в 32-битной системе, только половину. Адрес другой половины, вероятно, зависит от того, увеличивается или уменьшается стек. В 64-битной системе вы должны выяснить, какая половина возвращаемого слова имеет число с плавающей запятой.

Итак ... все это очень системно зависит от того, что вы должны делать.

...