Смущает gdb print ptr и print «%s»
-
09-06-2019 - |
Вопрос
1167 ptr = (void*)getcwd(cwd, MAX_PATH_LENGTH-1);
(gdb) n
1168 if (!ptr) {
(gdb) print ptr
$1 = 0xbff2d96c "/media/MMC-SD/partition1/aaaaaaaaaaa"
(gdb) print &cwd
$2 = (char (*)[3500]) 0xbff2d96c
(gdb) print strlen(cwd)
$3 = 36
(gdb) print "%s",cwd
$4 = "/media/MMC-SD/partition1/aaaaaaaaaaa", '\0' <repeats 912 times>, "��O�001\000\000\000\000��027\000\000\000�3����EL鷠3�000��027\000\000\000\000\000\000\000\027\000\000\000\000��/�027\000\000\000�3����N����\230���鷠3�000��027\000\000\000\000\000\000\000��000\000\000\000\001\000\000\000��M鷠3����\000\000\000\000.\231�027��w\005\b\001\000"...
(gdb) print "%s", ptr
$5 = 0xbff2d96c "/media/MMC-SD/partition1/aaaaaaaaaaa"
(gdb) Quit
Почему ptr печатает строку правильно, а cwd нет;это также влияет на программу, и она вылетает, если я пытаюсь использовать cwd...
[редактировать:оказывается, что сбой был вызван глупым переполнением буфера в этой переменной...грр... не GDB, но вопрос печати все еще актуален]
Решение
Причина того, что cwd
печатается по-другому gdb
это потому что gdb
знает это ptr
это char *
(я думаю) и это cwd
представляет собой массив длины 3500
(как показано в вашем выводе).Поэтому при печати ptr
он печатает значение указателя (а также строку, на которую он указывает), а при печати cwd
он печатает весь множество.
Я не вижу причин использовать cwd
вместо ptr
это привело бы к проблемам, но мне нужно было бы увидеть код, чтобы быть уверенным.
Другие советы
Я согласен с Мверденом.Попробовав что-то, что, по моему мнению, похоже на ваш код, я получаю:
(gdb) print cwd
$1 = "/media", '\0' <repeats 782 times>, "\016���" ...
(gdb) print (char*) cwd
$2 = 0xbfc8eb84 "/media"
из GDB, поэтому кажется, что поскольку cwd
был определен как char cwd[3500]
, gdb печатает весь массив, а если вы прикажете gdb интерпретировать его как char*
, он будет работать так, как вы ожидаете.Если ваше приложение выйдет из строя, я предполагаю, что это происходит из-за чего-то другого.
Что ptr
отображается как красиво отформатированная строка и cwd
поскольку «байтовый буфер», вероятно, специфичен для GDB.В любом случае это не должно повлиять на ваше приложение;в соответствии с man 3 getcwd
, ptr
должен указать на cwd
(или оно должно быть NULL, если произошла ошибка).Вы можете использовать ptr
без сбоя программы?
Какой тип cwd?Приведенный выше фрагмент кода не говорит нам об этом.Возможно, ptr, являющийся void*, по-разному обрабатывается GDB.