2009-02-13 2 views
2

Я отлаживаю некоторый код Linux C в обработчике сигналов для исключений с плавающей запятой. Цель состоит в том, чтобы проверить регистры с плавающей запятой, распечатать некоторую информацию, а затем прервать. При попытке распечатать результат (char)('0' + phyreg) я получаю ошибку сегментации.Segfault при использовании printf

struct ucontext * uc = (struct ucontext *) data; 
fpregset_t  fp = uc -> uc_mcontext.fpregs; 

int top = (fp -> sw >> 11) & 0x07; 
int i,j,k; 
for (i = 0; i < 8; i++) { 
    static const char * tags [] = { 
     "valid", "zero", "invalid/infin", "empty" 
    }; 
    int phyreg = (top + i) & 0x07; 
    struct _libc_fpreg* r = &(fp -> _st [phyreg]); 
    const char* regExp = (((r->exponent & 0x8000) != 0) ? "-" : "+"); 
    printf (" FP %s: Mantissa= %s", 
      (char) ('0' + phyreg), // reg stack (SIGSEGV here) 
      regExp); // register exponent sign 
    j = (r->significand[3] >> 15) & 0x01; 
    printf ("%s.",(char) ('0' + j)); // mantissa (Also SIGSEGV here when 
            // previous SIGSEGV is commented out) 
    ... 
} 

Это не расчет (char)('0' + phyreg), что это проблема, потому что когда я переместить его в отдельную строку и сохранить результат в переменном темпе, я не получаю Segfault, пока Printf не пытается отобразить темп переменная. Итак, где ошибка, вызывающая segfault?

ответ

7

Вы печатаете с% s. Должна быть «FP% c: Mantissa =% s».

+0

Duh! Это было так давно, как я использовал printf. Я знал, что это, наверное, что-то очевидное, но я просто этого не видел. –

3

% s означает строку, вы даете ей характер. Это значение символа интерпретируется printf как указатель на первый символ строки для печати, что, конечно же, будет неустойчивым.

Поместите символ в массив символов с 2 элементами, второй - '\ 0' или посмотрите, имеет ли printf что-то, что оценивает символ.

3

Используйте %cformat specifier для одного символа, вместо того, чтобы %s (который должен быть использован для null -завершённых строк).

Смежные вопросы