簡體   English   中英

回溯是如何工作的?

[英]How does backtrace work?

#include <iostream>
using namespace std;

class dummyA
{
    int x;
    public:
        dummyA ()
        {
            x = 0;
        }

        void test ()
        {
            x++;
        }
};

int main ()
{
    cout << "\nG'Morning";
    dummyA obj;
    obj.test ();
    return 0;
}

回溯輸出:

(gdb) bt
#0  main () at backtrace.cpp:21
(gdb) bt full
#0  main () at backtrace.cpp:21
        obj = {x = -8896}
(gdb) n

22              dummyA obj;
(gdb) 

問題:

  • bt據說打印整個堆棧的回溯:堆棧中所有幀每幀一行,但我只看到輸出中函數的名稱? 為什么會這樣?
  • bt full顯示內部作品,當控件不在那一行時,它如何讀取'obj'( dummyA obj; )呢?

編輯1:

Breakpoint 1, dummyA::testB (this=0x7fffffffdc50) at backtrace.cpp:20
20                              x = x + 2;
(gdb) bt 0
(More stack frames follow...)
  • 上面的輸出沒有顯示任何內容,因為被調用函數testB的局部變量為零? 那是對的嗎?
 (gdb) bt 1 #0 dummyA::testB (this=0x7fffffffdc50) at backtrace.cpp:20 (More stack frames follow...) (gdb) bt 2 #0 dummyA::testB (this=0x7fffffffdc50) at backtrace.cpp:20 #1 0x000000000040078b in main () at backtrace.cpp:31 
  • 第1幀和第2幀准確顯示了什么?

(gdb)bt full
backtrace.cpp中的#0 main():26
obj1 = {x = -8896}
obj2 = {x = 0}

  • 為什么x在這里有兩個不同的值,假設斷點在main上?

WRT以下代碼:

#include <iostream>
using namespace std;

class dummyA
{
    int x;
    public:
        dummyA ()
        {
            x = 0;
        }

        void testA ()
        {
            x = x + 1;
        }

        void testB ()
        {
            x = x + 2;
        }
};

int main ()
{
    cout << "\nG'Morning";
    dummyA obj1;
    dummyA obj2;

    obj1.testA ();
    obj1.testB ();

    obj2.testA ();
    obj2.testB ();

    return 0;
}

該對象尚未構建,但已為其分配了空間。 你看到了整個回溯 - 你處於main時期。

bt據說打印整個堆棧的回溯:堆棧中所有幀每幀一行,但我只看到輸出中函數的名稱? 為什么會這樣?

回溯顯示當前函數,然后是調用它的函數,依此類推,一直回到main() 每個“堆棧幀”是特定函數使用的堆棧部分,因此每個函數有一個幀。 由於當前函數 main() ,因此只顯示一個幀。

(也許你希望回溯允許你看到執行的每一行代碼。不幸的是,當正常運行代碼時(除了添加斷點之外,這是gdb所做的),沒有足夠的可用信息來執行;你能做的最好的就是查看函數調用的歷史。)

bt full顯示內部作品,當控件不在那一行時,它如何讀取'obj'( dummyA obj; )呢?

已為對象分配空間(在本地堆棧幀中); 它尚未初始化。 您正在看到該空間中發生的任何事情,如果您跨過初始化線,它應該變為{x = 0}

上面的輸出沒有顯示任何內容,因為被調用函數testB局部變量為零? 那是對的嗎?

它什么都沒有顯示,因為你要求它什么都不顯示; bt的參數指定要顯示的堆棧幀數,並表示為零。

第1幀和第2幀准確顯示了什么?

在第一種情況下,您要求一個堆棧幀; 當前功能的那個。 它告訴你,你在函數dummyA::testB ,它被調用的對象的地址( this )是0x7fffffffdc50 ,並且相應的源行是backtrace.cpp第20行。

在第二種情況下,您要求兩個幀,因此它還顯示調用當前函數的位置:函數main()backtrace.cpp源行31。

為什么x在這里有兩個不同的值,假設斷點在main上?

每個都是不同對象( obj1.xobj2.x )的成員,並且都沒有被初始化; 所以每個都顯示一些恰好在該內存位置的隨機值。 如果你跨過初始化者,兩者都將變為零。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM