llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.76k stars 11.89k forks source link

[LLDB] lldb prints different values ​​at different optimization levels #108165

Open IOVOVHS opened 1 month ago

IOVOVHS commented 1 month ago

When printing an array variable, the value of one of the array elements is incorrect. This is somewhat similar to the previous question(https://github.com/llvm/llvm-project/issues/107977). There is an array element that is not used, so it is printed as 0, and the program does not update the variable.

compile:clang,-O2.

(lldb) b func_1
Breakpoint 1: where = random_833`main + 17 [inlined] func_1 at random_833.c:1332, address = 0x0000000000007771
(lldb) r
Process 449091 launched: '/home/hzw/experiment/csmith_prog/clang_O2/random_833' (x86_64)
Process 449091 stopped
* thread #1, name = 'random_833', stop reason = breakpoint 1.1
    frame #0: 0x000055555555b771 random_833`main [inlined] func_1 at random_833.c:227:414
   224          for (i = 0; i < 3; i++)
   225              l_2080[i] = 0xB102D357L;
   226      }
-> 227      (**g_666) = (safe_div_func_uint32_t_u_u(0x2E9D030DL,     .......

(lldb) p l_10
(uint32_t) $0 = 9
(lldb) p l_2150
(int16_t [9]) $2 = ([0] = 11894, [1] = 11894, [2] = 11894, [3] = 11894, [4] = 11894, [5] = 0, [6] = 11894, [7] = 11894, [8] = 11894)

compile:clang,-O0,line 227

.....
(lldb) p l_10
(uint32_t) $0 = 10
(lldb) p l_2150
(int16_t [9]) $1 = ([0] = 11894, [1] = 11894, [2] = 11894, [3] = 11894, [4] = 11894, [5] = 11894, [6] = 11894, [7] = 11894, [8] = 11894)

As you can see, the value of element [5] is different between -O0 and -O2. This is because element [5] is never used, so there seems to be something wrong with the debug information written during optimization.

The value of l_10 is also problematic. In the same line, the value is different under different optimization levels. Under -O2, the debug information is the constant 9, which is the initialization value of the variable l_10, but later on line 227, the value of l_10 should be 10, just as the value printed under -O0, because the value of l_10 has been updated in this line. Or is this acceptable?

source file

//about l_2150
 178     int16_t l_2150[9] = {0x2E76L,0x2E76L,0x2E76L,0x2E76L,0x2E76L,0x2E76L,0x2E76L,0x2E76L,0x2E76L};
 179     uint64_t **l_2151 = &g_574;
...
227 ...g_2149) >= (-1L)) >= l_2150[2])...
 228 int16_t c_1 = l_2150[4] - l_2150[0];
 229 int16_t c_2 = l_2150[2] * l_2150[0];
 230 int16_t c_3 = l_2150[8] - l_2150[1];
 231 int16_t c_4 = l_2150[1] - l_2150[2];
 232 int16_t c_5 = l_2150[3] + l_2150[2];
 233 int16_t c_6 = l_2150[8] + l_2150[8];

//about l_10
 175     uint32_t l_10 = 9UL;
...
 214     l_10++;
....

debug info:

0x00000a9e:       DW_TAG_variable
                    DW_AT_location  (indexed (0x2) loclist = 0x00000092: 
                       [0x000000000000114b, 0x0000000000001591): DW_OP_constu 0x2e76, DW_OP_stack_value, DW_OP_piece 0x2, DW_OP_constu 0x2e76, DW_OP_stack_value, DW_OP_piece 0x2, DW_OP_constu 0x2e76, DW_OP_stack_value, DW_OP_piece 0x2, DW_OP_constu 0x2e76, DW_OP_stack_value, DW_OP_piece 0x2, DW_OP_constu 0x2e76, DW_OP_stack_value, DW_OP_piece 0x2, DW_OP_piece 0x2, DW_OP_constu 0x2e76, DW_OP_stack_value, DW_OP_piece 0x2, DW_OP_constu 0x2e76, DW_OP_stack_value, DW_OP_piece 0x2, DW_OP_constu 0x2e76, DW_OP_stack_value, DW_OP_piece 0x2)
                    DW_AT_abstract_origin   (0x0000060d "l_2150")

0x00000a98:       DW_TAG_variable
                    DW_AT_const_value   (9)
                    DW_AT_abstract_origin   (0x00000605 "l_10")

Similar to the previous question, because only one array element was used, the debug information only had a constant for the value of an array variable, and the values ​​of the remaining elements were 0. But here, the length of the array element is 9, and in the debug information, eight values ​​are written for the variable, so the remaining one is naturally printed as 0.

For the variable l_10, the value is always the initialization value 9, even if there is an update statement later, but because l_10 has never been used anywhere else, maybe this is acceptable?

This is all I understand about debuggers. If there are any mistakes, please point them out.

clang --version: clang version 19.0.0git (https://github.com/llvm/llvm-project.git b4ab52c8e71e819c13606de3500043eaa701e1ea) Target: x86_64-unknown-linux-gnu Thread model: posix InstalledDir: /home/hzw/Downloads/llvm-project/build/bin Build config: +unoptimized, +assertions

IOVOVHS commented 1 month ago

random_833.zip

llvmbot commented 1 month ago

@llvm/issue-subscribers-lldb

Author: None (IOVOVHS)

When printing an array variable, the value of one of the array elements is incorrect. This is somewhat similar to the previous question(https://github.com/llvm/llvm-project/issues/107977). There is an array element that is not used, so it is printed as 0, and the program does not update the variable. compile:clang,-O2. ``` (lldb) b func_1 Breakpoint 1: where = random_833`main + 17 [inlined] func_1 at random_833.c:1332, address = 0x0000000000007771 (lldb) r Process 449091 launched: '/home/hzw/experiment/csmith_prog/clang_O2/random_833' (x86_64) Process 449091 stopped * thread #1, name = 'random_833', stop reason = breakpoint 1.1 frame #0: 0x000055555555b771 random_833`main [inlined] func_1 at random_833.c:227:414 224 for (i = 0; i < 3; i++) 225 l_2080[i] = 0xB102D357L; 226 } -> 227 (**g_666) = (safe_div_func_uint32_t_u_u(0x2E9D030DL, ....... (lldb) p l_10 (uint32_t) $0 = 9 (lldb) p l_2150 (int16_t [9]) $2 = ([0] = 11894, [1] = 11894, [2] = 11894, [3] = 11894, [4] = 11894, [5] = 0, [6] = 11894, [7] = 11894, [8] = 11894) ``` compile:clang,-O0,line 227 ``` ..... (lldb) p l_10 (uint32_t) $0 = 10 (lldb) p l_2150 (int16_t [9]) $1 = ([0] = 11894, [1] = 11894, [2] = 11894, [3] = 11894, [4] = 11894, [5] = 11894, [6] = 11894, [7] = 11894, [8] = 11894) ``` As you can see, the value of element [5] is different between -O0 and -O2. This is because element [5] is never used, so there seems to be something wrong with the debug information written during optimization. The value of l_10 is also problematic. In the same line, the value is different under different optimization levels. Under -O2, the debug information is the constant 9, which is the initialization value of the variable l_10, but later on line 227, the value of l_10 should be 10, just as the value printed under -O0, because the value of l_10 has been updated in this line. Or is this acceptable? source file ``` c //about l_2150 178 int16_t l_2150[9] = {0x2E76L,0x2E76L,0x2E76L,0x2E76L,0x2E76L,0x2E76L,0x2E76L,0x2E76L,0x2E76L}; 179 uint64_t **l_2151 = &g_574; ... 227 ...g_2149) >= (-1L)) >= l_2150[2])... 228 int16_t c_1 = l_2150[4] - l_2150[0]; 229 int16_t c_2 = l_2150[2] * l_2150[0]; 230 int16_t c_3 = l_2150[8] - l_2150[1]; 231 int16_t c_4 = l_2150[1] - l_2150[2]; 232 int16_t c_5 = l_2150[3] + l_2150[2]; 233 int16_t c_6 = l_2150[8] + l_2150[8]; //about l_10 175 uint32_t l_10 = 9UL; ... 214 l_10++; .... ``` debug info: ``` 0x00000a9e: DW_TAG_variable DW_AT_location (indexed (0x2) loclist = 0x00000092: [0x000000000000114b, 0x0000000000001591): DW_OP_constu 0x2e76, DW_OP_stack_value, DW_OP_piece 0x2, DW_OP_constu 0x2e76, DW_OP_stack_value, DW_OP_piece 0x2, DW_OP_constu 0x2e76, DW_OP_stack_value, DW_OP_piece 0x2, DW_OP_constu 0x2e76, DW_OP_stack_value, DW_OP_piece 0x2, DW_OP_constu 0x2e76, DW_OP_stack_value, DW_OP_piece 0x2, DW_OP_piece 0x2, DW_OP_constu 0x2e76, DW_OP_stack_value, DW_OP_piece 0x2, DW_OP_constu 0x2e76, DW_OP_stack_value, DW_OP_piece 0x2, DW_OP_constu 0x2e76, DW_OP_stack_value, DW_OP_piece 0x2) DW_AT_abstract_origin (0x0000060d "l_2150") 0x00000a98: DW_TAG_variable DW_AT_const_value (9) DW_AT_abstract_origin (0x00000605 "l_10") ``` Similar to the previous question, because only one array element was used, the debug information only had a constant for the value of an array variable, and the values ​​of the remaining elements were 0. But here, the length of the array element is 9, and in the debug information, eight values ​​are written for the variable, so the remaining one is naturally printed as 0. For the variable l_10, the value is always the initialization value 9, even if there is an update statement later, but because l_10 has never been used anywhere else, maybe this is acceptable? This is all I understand about debuggers. If there are any mistakes, please point them out. clang --version: clang version 19.0.0git (https://github.com/llvm/llvm-project.git b4ab52c8e71e819c13606de3500043eaa701e1ea) Target: x86_64-unknown-linux-gnu Thread model: posix InstalledDir: /home/hzw/Downloads/llvm-project/build/bin Build config: +unoptimized, +assertions