GDB가 줄 사이를 예측할 수없이 점프하고 변수를“”?
누구든지 gdb의이 동작을 설명 할 수 있습니까?
900 memset(&new_ckpt_info,'\0',sizeof(CKPT_INFO));
(gdb)
**903 prev_offset = cp_node->offset;**
(gdb)
**905 m_CPND_CKPTINFO_READ(ckpt_info,(char *)cb->shm_addr.ckpt_addr+sizeof(CKPT_** HDR),i_offset);
(gdb)
**903 prev_offset = cp_node->offset;**
(gdb)
**905 m_CPND_CKPTINFO_READ(ckpt_info,(char *)cb->shm_addr.ckpt_addr+sizeof(CKPT_ HDR),i_offset);**
(gdb)
**908 bitmap_offset = client_hdl/32;**
(gdb)
**910 bitmap_value = cpnd_client_bitmap_set(client_hdl%32);**
(gdb)
**908 bitmap_offset = client_hdl/32;**
(gdb)
**910 bitmap_value = cpnd_client_bitmap_set(client_hdl%32);**
(gdb)
**908 bitmap_offset = client_hdl/32;**
(gdb)
**910 bitmap_value = cpnd_client_bitmap_set(client_hdl%32);**
(gdb)
913 found = cpnd_find_exact_ckptinfo(cb , &ckpt_info , bitmap_offset , &offset , &prev_offset);
(gdb)
916 if(!found)
(gdb) p found
$1 = <value optimized out>
(gdb) set found=0
Left operand of assignment is not an lvalue.
903 행을 실행 한 후 905908910에 대해 동일한 작업을 다시 실행하는 이유는 무엇입니까?
또 다른 물건은 found
A는 bool
, 타입 변수 왜 그것을 보여주고있다 value optimized out
? 의 값도 설정할 수 없습니다 found
.
이것은 컴파일러 최적화 인 것 같습니다 (이 경우에는 -O2
). 여전히 값을 found
어떻게 설정할 수 있습니까?
최적화 된 코드를 디버깅하려면 어셈블리 / 기계 언어를 배우십시오.
GDB TUI 모드를 사용하십시오. 마이너스와 Enter를 입력하면 GDB 사본이 활성화됩니다. 그런 다음 Cx 2를 입력합니다 (즉, Control을 누른 상태에서 X를 누른 다음 둘 다 놓은 다음 2를 누릅니다). 그러면 분할 소스 및 디스 어셈블리 디스플레이가됩니다. 그런 다음 및를 사용 stepi
하여 nexti
한 번에 하나의 기계 명령을 이동하십시오. Cx o를 사용하여 TUI 창 사이를 전환합니다.
CPU의 기계어 및 함수 호출 규칙에 대한 PDF를 다운로드하십시오. 함수 인수 및 반환 값으로 수행되는 작업을 빠르게 인식하는 방법을 배우게됩니다.
다음과 같은 GDB 명령을 사용하여 레지스터 값을 표시 할 수 있습니다. p $eax
최적화없이 재 컴파일합니다 (gcc의 -O0).
발견 된 것을 "휘발성"으로 선언하십시오 . 이것은 컴파일러에게 최적화하지 않도록 지시해야합니다.
volatile int found = 0;
The compiler will start doing very clever things with optimisations turned on. The debugger will show the code jumping forward and backwards alot due to the optimized way variables are stored in registers. This is probably the reason why you can't set your variable (or in some cases see its value) as it has been cleverly distributed between registers for speed, rather than having a direct memory location that the debugger can access.
Compile without optimisations?
Typically, boolean values that are used in branches immediately after they're calculated like this are never actually stored in variables. Instead, the compiler just branches directly off the condition codes that were set from the preceding comparison. For example,
int a = SomeFunction();
bool result = --a >= 0; // use subtraction as example computation
if ( result )
{
foo();
}
else
{
bar();
}
return;
Usually compiles to something like:
call .SomeFunction ; calls to SomeFunction(), which stores its return value in eax
sub eax, 1 ; subtract 1 from eax and store in eax, set S (sign) flag if result is negative
jl ELSEBLOCK ; GOTO label "ELSEBLOCK" if S flag is set
call .foo ; this is the "if" black, call foo()
j FINISH ; GOTO FINISH; skip over the "else" block
ELSEBLOCK: ; label this location to the assembler
call .bar
FINISH: ; both paths end up here
ret ; return
Notice how the "bool" is never actually stored anywhere.
You pretty much can't set the value of found. Debugging optimized programs is rarely worth the trouble, the compiler can rearrange the code in ways that it'll in no way correspond to the source code (other than producing the same result), thus confusing debuggers to no end.
When debugging optimized programs (which may be necessary if the bug doesn't show up in debug builds), you often have to understand assembly compiler generated.
In your particular case, return value of cpnd_find_exact_ckptinfo
will be stored in the register which is used on your platform for return values. On ix86
, that would be %eax
. On x86_64
: %rax
, etc. You may need to google for '[your processor] procedure calling convention' if it's none of the above.
You can examine that register in GDB
and you can set it. E.g. on ix86
:
(gdb) p $eax
(gdb) set $eax = 0
Im using QtCreator with gdb.
Adding
QMAKE_CXXFLAGS += -O0
QMAKE_CXXFLAGS -= -O1
QMAKE_CXXFLAGS -= -O2
QMAKE_CXXFLAGS -= -O3
Works well for me
'program story' 카테고리의 다른 글
배열을 N 길이의 청크로 분할 (0) | 2020.09.20 |
---|---|
ES6 구문을 사용하여 onclick 이벤트를 통해 매개 변수를 전달하는 반응 (0) | 2020.09.20 |
루비에서 send ()는 무엇을합니까? (0) | 2020.09.20 |
비어 있거나 값이없는 문자열 테스트 (0) | 2020.09.20 |
이보기는 제한되지 않습니다. (0) | 2020.09.20 |