#c #debugging #lldb
#c #отладка #lldb
Вопрос:
В следующем коде на языке Си:
#include lt;stdio.hgt; int main(void) { unsigned i = 1; while (i) { i lt;lt;= 1; } return 0; }
Сначала я компилирую с отладочной информацией следующим образом: gcc -g single-step.c
Тогда я это делаю lldb a.out
. Я хочу видеть, что я делаю , поэтому я делаю b main
и run
, после чего я устанавливаю свою точку наблюдения для i: watchpoint set variable i
. Однако, когда я это делаю, lldb, похоже, присваивает значение переменной i, чего не должно быть
Watchpoint created: Watchpoint 1: addr = 0x16fdff498 size = 4 state = enabled type = w declare @ '/Users/d1ff1cult/Documents/KUL 2021-2022/IW/oefenzitting-c/les8-debugging/examples/single-step.c:5' watchpoint spec = 'i' new value: 53472
Это дает мне, казалось бы, совершенно случайное значение, так что же я делаю не так?
Я использую CLion для написания своего кода, но это происходит в терминале CLion, а также в моем собственном терминале macOS. Я также использую Mac M1.
Заранее спасибо!
Комментарии:
1. Вероятно, он отображает значение до
i
инициализации1
, которое является отдельной операцией.
Ответ №1:
Юджин прав.
В моей системе, когда я запускаю вашу программу, я получаю начальное значение 0 в точке наблюдения.
Я изменил программу, чтобы поместить ваш код в функцию (например) orig
.
Я создал функцию fill
, которая циклически заполняет свой кадр стека массивом int длиной 100.
От main
, я звоню fill
, а потом orig
с b orig
. Затем, выполнив команду watchpoint, я получаю значение 100.
Таким образом, ваша точка наблюдения отображает все, что происходит в кадре стека для того, что i
назначено. То есть неинициализированное значение.
Вот программа тестирования, которую я создал:
#include lt;stdio.hgt; #include lt;stdlib.hgt; int orig(void) { unsigned i = 1; while (i) { i lt;lt;= 1; } return 0; } void fill(void) { unsigned x[100]; for (int i = 0; i lt; 100; i) x[i] = rand(); } int main(void) { fill(); orig(); return 0; }
Вот отладочный вывод:
gt; lldb ./fix1 (lldb) target create "./fix1" Current executable set to './fix1' (x86_64). (lldb) b main Breakpoint 1: where = fix1`main 4 at fix1.c:29, address = 0x000000000040117b (lldb) b orig Breakpoint 2: where = fix1`orig 4 at fix1.c:7, address = 0x000000000040112a (lldb) run Process 193289 launched: '/tmp/watch/fix1' (x86_64) Process 193289 stopped * thread #1, name = 'fix1', stop reason = breakpoint 1.1 frame #0: 0x000000000040117b fix1`main at fix1.c:29 26 main(void) 27 { 28 -gt; 29 fill(); 30 orig(); 31 32 return 0; (lldb) c Process 193289 resuming Process 193289 stopped * thread #1, name = 'fix1', stop reason = breakpoint 2.1 frame #0: 0x000000000040112a fix1`orig at fix1.c:7 4 int 5 orig(void) 6 { -gt; 7 unsigned i = 1; 8 9 while (i) { 10 i lt;lt;= 1; (lldb) watchpoint set variable i Watchpoint created: Watchpoint 1: addr = 0x7fffffffdd6c size = 4 state = enabled type = w declare @ '/tmp/watch/fix1.c:7' watchpoint spec = 'i' new value: 100
Комментарии:
1. отладочная информация обычно не представляет инициализацию переменной — это может зависеть от пути и ее будет трудно представить. Он имеет тенденцию отслеживать только лексическую область переменных и их местоположение в этой области. Поскольку переменная входит в область действия, когда она определена, и отладчик не может определить, была ли она инициализирована, он будет сообщать о том, что находится в этой памяти, независимо от статуса инициализации значения.