Nice programing

GDB에서 이전 줄로 이동하는 방법은 무엇입니까?

nicepro 2020. 11. 30. 19:55
반응형

GDB에서 이전 줄로 이동하는 방법은 무엇입니까?


gdb에서 현재 실행중인 줄 앞의 줄로 이동할 수 있습니까? 예 :


void my_fun( somePtrType** arr,int start,int end)
{
 // arr is an array of pointers to somePtrType
  //line a
 ... some assignments
 swap(&arr[ind1] , &arr[ind2] ) ;
 //line b (current line )
}

나는 현재 라인 b에 arr있고 거기 에서 값을 조사 할 수 있지만 라인 a로 돌아가서 arr그 당시 의 내용을 조사하고 싶습니다 .

디버거가 느린 동작으로 코드를 실행할 수 있기 때문에 가능하지 않을 수 있다고 생각하지만 역방향으로 실행할 수는 없습니다.
더 많은 통찰력 ..


예! 새 버전 7.0 gdb를 사용하면 정확하게 수행 할 수 있습니다!

명령은 " reverse-step"또는 " reverse-next"입니다.

ftp.gnu.org:/pub/gnu/gdb에서 gdb-7.0을 얻을 수 있습니다.

오류가 발생 하면을 시작한 후 실행을 시작할 Target child does not support this command.때 추가해보십시오 .target recordrun

편집 : GDB 7.6 target record은 더 이상 사용되지 않으므로 target record-full대신 사용하십시오.


예, 가능하고 간단합니다. 이제 실제 하드웨어를 사용하면 가능합니다 (즉, VM뿐 아니라). GDB-7.0은 기본 Linux x86 시스템에서 역방향 및 역방향 연속과 같은 명령으로 역 디버깅을 지원합니다.

여기에 튜토리얼이 있습니다 : http://www.sourceware.org/gdb/wiki/ProcessRecord/Tutorial


모질라 rr

https://github.com/mozilla/rr

GDB의 내장 레코드 및 재생에는 심각한 제한이 있습니다. 예를 들어 AVX 명령을 지원하지 않습니다 . gdb 역 디버깅이 "프로세스 레코드가 주소에서 명령 0xf0d를 지원하지 않습니다"와 함께 실패합니다.

rr의 장점 :

  • 현재 훨씬 더 안정적
  • 또한 gdbserver 프로토콜을 사용하는 GDB 인터페이스를 제공하므로이를 대체 할 수 있습니다.
  • 많은 프로그램에 대한 작은 성능 저하

다음 예는 reverse-next, reverse-stepreverse-continue명령 같은 일부 기능을 보여줍니다 .

Ubuntu 16.04에 설치합니다.

sudo apt-get install rr linux-tools-common linux-tools-generic linux-cloud-tools-generic
sudo cpupower frequency-set -g performance

그러나 최신 업데이트를 얻기 위해 소스에서 컴파일하는 것도 고려해보십시오. 어렵지 않았습니다.

reverse.c

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int f() {
    int i;
    i = 0;
    i = 1;
    i = 2;
    return i;
}

int main(void) {
    int i;

    i = 0;
    i = 1;
    i = 2;

    /* Local call. */
    f();

    printf("i = %d\n", i);

    /* Is randomness completely removed?
     * Recently fixed: https://github.com/mozilla/rr/issues/2088 */
    i = time(NULL);
    printf("time(NULL) = %d\n", i);

    return EXIT_SUCCESS;
}

컴파일 및 실행 :

gcc -O0 -ggdb3 -o reverse.out -std=c89 -Wextra reverse.c
rr record ./reverse.out
rr replay

이제 GDB 세션에 남아 있으며 올바르게 역 디버그 할 수 있습니다.

(rr) break main
Breakpoint 1 at 0x55da250e96b0: file a.c, line 16.
(rr) continue
Continuing.

Breakpoint 1, main () at a.c:16
16          i = 0;
(rr) next
17          i = 1;
(rr) print i
$1 = 0
(rr) next
18          i = 2;
(rr) print i
$2 = 1
(rr) reverse-next
17          i = 1;
(rr) print i
$3 = 0
(rr) next
18          i = 2;
(rr) print i
$4 = 1
(rr) next
21          f();
(rr) step
f () at a.c:7
7           i = 0;
(rr) reverse-step
main () at a.c:21
21          f();
(rr) next
23          printf("i = %d\n", i);
(rr) next
i = 2
27          i = time(NULL);
(rr) reverse-next
23          printf("i = %d\n", i);
(rr) next
i = 2
27          i = time(NULL);
(rr) next
28          printf("time(NULL) = %d\n", i);
(rr) print i
$5 = 1509245372
(rr) reverse-next
27          i = time(NULL);
(rr) next
28          printf("time(NULL) = %d\n", i);
(rr) print i
$6 = 1509245372
(rr) reverse-continue
Continuing.

Breakpoint 1, main () at a.c:16
16          i = 0;

짧은 대답 : 아니요.

대한 해결 방법 아래를 참조.

라인 b에서는 라인 a의 값을 결정할 수 없지만 a, b 및 다른 위치에서 arr의 값을 기록 할 수 있습니다.

  • Use the "display" command (display variable_name where variable_name is to be replaced with arr, *arr, **arr depending on what you are looking for) so that when any breakpoint is hit, the contents of the variable_name will be dumped on to the screen. Note that you can add to the display list when the variabe_name is in scope so that may require you to wait for your first breakpoint.
  • Create breakpoints at various locations of code where you are interested to log the value of variable_name. One such breakpoint would be at line a.
  • For each breakpoint, use command (command breakpoint_number) and instruct your breakpoint to not halt the execution of the program. The command that you need to use is continue followed by end. See example below.

(gdb) command 1

Type commands for when breakpoint 1 is hit, one per line. End with a line saying just "end".

continue

end

  • Put a breakpoint on line b.

Now when all other logging breakpoints are hit, the value of arr will be dumped on the screen but the breakpoint won't wait for user interaction and will auto-continue. When you hit a breakpoint at line b, you can see the past values of arr which would be logged in gdb itself.

Depending on the situation you can also dump (and display) a lot of useful information. For example you may also want to dump a loop counter (say i) if the above function is called 10000 times in a loop. That really depends on what you are trying to achieve.


according to http://sourceware.org/gdb/current/onlinedocs/gdb.html#SEC51 , and "if the target environment supports it", yes.


If your program is short, the usual trick is,

  1. Place a new breakpoint at the previous line
    • fire r to restart the debug

GDB was made to do that!


Not gdb but you can go back in history easily using a debugger called qira. You can use the up and down arrows to go back and forth, it also highlights which registers have changed.

enter image description here


Everyone wishes for a Omniscient Debugger like this one: http://www.lambdacs.com/debugger/, but they are (depending on the language/machine) difficult to make and have a lot of bookkeeping to do.

At the moment on real hardware and not in a VM, it is close to impossible to do it.


If your setup code for arr is just above "line a" (a very commonly scenario), you can do it like this:

tbreak myfilename.c:123 (line 123 is the start of setup code for arr) then

jump 123

The "tbreak" prevents gdb from continuing (resuming) the program after the jump.

then you can step through the setup code or just set a breakpoint at "line a" and continue

참고URL : https://stackoverflow.com/questions/1206872/how-to-go-to-the-previous-line-in-gdb

반응형