DOUG LLOYD:好吧GDB。 究竟是什麼? 所以GDB,它代表 對於GNU調試器, 是一個真正真棒工具,我們就可以 用它來幫助我們調試我們的節目, 或者找出事情 在我們的計劃去錯了。 GDB令人驚訝的是強大的,但 輸出和交互與它 可以是一個有點神秘。 這通常是一個命令行工具, 它會向你扔了很多信息。 它可以一種很難 解析究竟發生了什麼。 幸運的是,我們已經採取措施 要解決這個問題為您 你通過CS50工作。 如果您沒有使用圖形 調試器,我的同事丹 Armandarse發話了相當 視頻中的一些有關這個 應該在這裡 現在,你可能需要 使用這些命令行 工具與GDB工作。 如果你工作在CS50 IDE,你並不需要這樣做。 但是,如果你不 在CS50 IDE中工作, 也許使用一個版本 CS50電器, 或其他Linux操作系統 系統GDB安裝就可以了, 您可能需要使用 這些命令行工具。 而且因為你可能 要做到這一點,它的 有用的只是為了了解 GDB工作的命令行。 但同樣,如果你 使用CS50 IDE,你 可以使用圖形化調試器 內置於在IDE。 因此,要得到的東西去與 GDB,開始調試 的一個特定的過程 程序,所有你需要做的 類型是GDB跟隨 由程序名稱。 因此,舉例來說,如果你的程序是 你好,你可以鍵入GDB打招呼。 當你這樣做,你會 拉上了GDB的環境。 您提示會發生變化, 而不是被它通常 當你輸入的東西是 在命令line-- LS, cd--所有典型的 Linux命令,你的提示 將變更為,也許事情 像括號GDB括號。 這是你的新的GDB提示,因為 你GDB的環境中。 一旦環境的內部, 有兩個主要的命令 你可能會使用 按照以下順序。 第一個是b,即 短暫的休息。 而你輸入b後,您通常 鍵入一個函數的名稱, 或者,如果你碰巧知道 圍繞什麼,行號 你的程序開始 表現得有點怪異, 你可以鍵入一行 一些有作為。 什麼B,或者休息,不 是它可以讓你的程序 運行,直到某一點, 的功能,即,名稱 您指定或線 您指定的號碼。 在這一點上,它 將凍結執行。 這是一個非常好的事情,因為 一旦執行已經被凍結, 你可以開始很慢 逐步執行程序。 通常情況下,如果你已經運行 你的程序,他們非常短。 通常情況下,你鍵入點斜線什麼 你的程序的名稱,敲回車, 之前,你可以眨眼,你 程序已經完成。 這不是一個真正的大量的時間去嘗試 並找出什麼錯誤。 因此,它真的能放緩的東西 下降設置一個破發點與B, 然後加緊研究。 然後,一旦你已經設置的斷點 一點,就可以運行該程序。 如果您有任何 命令行參數, 在此指定他們,而不是當 您鍵入GDB的程序名。 您可以指定所有的命令行 通過採取R或運行參數, 然後任何命令行參數 你需要你的程序中。 還有一些其他的真 重要的和有用的命令 內生產總值的環境。 所以,讓我迅速 去了其中的一些。 第一是n,這是短的下一個, 您可以鍵入的下一個替代N, 這兩個會的工作。 而這僅僅是速記。 正如你可能已經得到了 習慣了,能夠類型的東西 短一般是更好的。 而且它會做的是,它會 向前一步一個塊的代碼。 因此它會繼續前進 直到一個函數調用。 然後,而不是 潛入該函數 而經歷了這一切功能 代碼,它只是具備的功能。 該函數將被調用。 它會做任何的工作。 它會返回一個值, 調用它的功能。 然後你就移動到 下一行調用函數的。 如果你想一步 函數的內部, 而不是僅僅有 它執行,特別是 如果你認為問題 可能在於該函數中, 你可以,當然,設置斷點 點那個函數內。 或者,如果你已經在運行,你可以 使用s到一步向前一行代碼。 因此,這將介入 並潛入功能, 而不是只具有執行 而在功能上繼續 你是為了調試。 如果你想知道 一個變量的值, 您可以鍵入p或打印, 然後將變量名。 這將打印出來給你, GDB的環境的內部, 的變量的名稱,即你 - 原諒我 - 的變量的值 您已經命名。 如果你想知道每一個的值 從那裡局部變量訪問 你現在在你的 程序,您可以鍵入信息當地人。 它比快很多 鍵入p和再不管, 列出了所有的 你知道存在變數。 您可以輸入信息的當地人,並 將打印出你的一切。 接下來是BT,這是 短的回溯。 現在,一般地, 在CS50特別早, 你不會真的有機會 使用BT或回溯追踪, 因為你沒有的功能 調用等功能。 你可能有主呼叫 功能,但是這可能是它。 你沒有其他的功能 調用另一個函數,該函數 調用另一個函數,等等。 但隨著你的程序得到更多的 複雜,並且特別 當你開始工作 遞歸,回溯追踪 可以讓你真正有用的方法 那種得到一些上下文哪裡 我在我的計劃。 所以說,你寫你的代碼, 你知道,主調用一個函數 f,這個調用一個函數 克,它調用一個函數h。 因此,我們有幾層 嵌套回事。 如果你是內 您的GDB的環境, 你知道你的內 h的,但你忘了 關於什麼讓你到你 are--您可以鍵入BT或回溯追踪, 它會打印出H,G,F為主, 沿著一些其它的信息,這 為您提供了一個線索,確定主 所謂的F,F稱為G,G稱為H, 而這也正是我 目前我在我的計劃。 因此,它可以是真正有用的, 尤其是在神秘的煩躁GDB的 變得有點勢不可擋,以 找出到底是那裡的東西。 最後,當你的程序完成後, 或者當你完成調試它 並且要一步之遙 從GDB的環境, 它有助於了解如何擺脫它。 您可以鍵入q,或退出,讓出。 現在,今天的視頻前 我準備了一個錯誤的程序 所謂buggy1,這是我編 從被稱為buggy1.c一個文件。 如你所料,此 節目其實是在馬車。 不順心的事 當我嘗試並運行它。 現在,不幸的是,我無意間 刪除了我的buggy1.c文件, 所以為了讓我弄清楚 什麼錯這個程序, 我將不得不使用 GDB那種盲目的,想 瀏覽該程序 弄清楚到底發生了什麼錯誤。 但僅使用工具 我們已經了解了, 我們幾乎可以圖 出它到底是什麼。 因此,讓我們頭以上 CS50 IDE,看一看。 好了,我們在這裡在我 CS50 IDE環境, 我會放大一點點 所以你可以看到多一點。 在我的終端窗口中,如果我列出 我的現任董事的內容 使用ls,我們會看到,我 有幾個源文件 這裡,包括 前面討論buggy1。 究竟推移,當 我嘗試運行buggy1。 那麼讓我們來了解一下。 I型點斜線, 越野車,和我打回車鍵。 段故障。 這不是很好。 如果你還記得,一 段錯誤通常 當我們訪問內存時 我們正在不許碰。 我們已經在某種程度上達成 的範圍之外 什麼樣的程序,在 編譯器,給了我們。 因此已經,這是一個 線索保持在工具箱中 當我們開始調試過程。 一些曾在這裡得有點不對。 好吧,讓我們開始 了GDB環境 看看我們是否能想出 究竟是什麼問題。 我要明確我的屏幕, 我要去鍵入GDB 再次,進入GDB的環境, 和節目的名稱 我想調試,buggy1。 我們得到一點消息,讀 從buggy1符號,完成。 所有這一切意味著它拉 同時所有的代碼, 而現在它已經裝入 GDB,它已經準備好去。 現在,我想幹什麼? 你還記得什麼 第一個步驟通常是 我這個環境裡面之後? 但願你說的設置 一個破發點,因為 其實這就是我想做的事情。 現在,我沒有 這個源代碼 在我的面前,這可能是 不是典型的用例,順便說一句。 你可能會。 所以這是很好的。 但是,假設你不這樣做,有什麼 一個功能,你知道 在每一個C程序的存在? 無論多麼大或多麼複雜 它是,該功能肯定存在。 主,對不對? 所以沒有一切,我們可以 設置在主一個破發點。 再次,我可以只輸入 打破代替b為主。 如果你很好奇,如果你 曾經鍵入了一個長的命令 然後意識到,你 輸入了錯誤的事情, 你想擺脫 一切正如我剛才那樣, 你可以採取控制U,這將 刪除一切,帶給你回來 到光標線的開頭。 快了很多不僅僅是按住 刪除或打它一幫倍 過來。 因此,我們將設置一個破發點,在主。 正如你所看到的,它說我們已經 設置一個斷點在文件buggy1.c, 顯然在第一線 的主要代碼行七人。 再次,我們沒有 這裡源文件, 但我認為這是 告訴我真相。 然後,我只是想 並運行程序,河 啟動程序。 好了,所以這條消息 是有點神秘。 但基本上什麼 發生在這裡它只是 告訴我,我已經打了我突破 點,斷點1號。 然後,該代碼行, 沒有這樣的文件或目錄。 唯一的原因, 我看到這個信息 是因為我無意中 刪除了我的buggy.c文件。 如果我的buggy1.c文件存在 在當前的目錄中, 該行那裡實際上 告訴我的代碼行 從字面上讀。 不幸的是,我將其刪除。 我們將不得不樣的導航 通過這個有點盲目。 好了,讓我們來看看,有什麼 我想在這裡做? 好吧,我想知道是什麼地方 變量可能是提供給我。 我開始了我的計劃。 讓我們來看看可能是什麼 已經初始化我們。 I型信息當地人,沒有本地人。 好吧,使之不 給我一噸的信息。 我可以嘗試,並打印出一個變量, 但我不知道任何變量名。 我可以嘗試一回痕跡, 但我的主內, 所以我知道我沒有作 另一個函數調用現在。 所以看起來像我的唯一選項 使用N或左右,開始潛水研究。 我會用了N。 所以我N型。 噢,我的天哪,這裡究竟是怎麼回事。 程序接收到的信號, SIGSEGV段故障, 然後一大堆東西。 我已經不堪重負。 嗯,實際上是一個 很多問題需要了解。 那麼,這告訴我們什麼? 它告訴我們的是,這個計劃是 約而至,但還沒有,賽格故障。 特別是,我要去 放大甚至進一步這裡, 它是關於賽格故障有關 所謂的strcmp。 現在,我們可能還沒有討論 這一功能廣泛。 但is--,因為我們不打算 說說每個功能 存在於C標準library-- 但他們都提供給你, 特別是如果你把一個 看reference.cs50.net。 而STRCMP是一個真正強大 功能存在內 該文件string.h頭的 文件,這是一個標頭 專用於功能的文件 與工作和處理字符串。 特別是,是什麼的strcmp確實是 它比較兩個字符串的值。 所以我要段錯誤 在通話中對strcmp好像。 我打了N,而事實上我得到的消息, 方案終止信號SIGSEGV 段故障。所以,現在 其實,我賽格故障, 而我的方案有相當 很多有效的放棄。 這是程序的結束。 它打破了,它墜毀。 所以,是不是很多,但我 實際上確實學到了不少 從這一點經驗。 我學到了? 好了,我的程序崩潰 立刻漂亮多了。 我的程序崩潰的 一個打電話給strcmp,但我 沒有在任何局部變量我 計劃在它崩潰的時間。 那麼,什麼串,或字符串, 可能我可能會比較。 如果我沒有任何地方 變量,你可能 推測,我have--有可能是一個 全局變量,這可能是正確的。 但總體來說,這似乎 像我比較 到不存在的東西。 因此,讓我們探討 一個遠一點。 所以,我要明確我的屏幕。 我要離開了的 GDB環境一秒鐘。 而且我想,OK,所以有 沒有局部變量,在我的計劃。 我不知道,也許我應該傳球 在一個字符串作為命令行參數。 因此,讓我們只是測試了這一點。 我以前沒有這樣做過。 讓我們來看看,也許,如果我運行這個程序 使用命令行參數它的工作原理。 呵呵,不分段錯誤存在。 它只是告訴我,我想它了。 所以,也許這就是固定在這裡。 事實上,如果我回去看看 對於buggy1.c實際的源代碼, 它好像我在做什麼是 我在做一個呼叫而不對strcmp 檢查是否實際上的argv [1]存在。 這實際上是 源代碼buggy1.c。 所以我真的需要 在這裡做修復我的程序, 假設我有 在我面前的文件,是 只需添加一個檢查,以 確保的argc等於2。 所以這個例子中,再次,就像我說的, 是有點做作,對吧? 你一般都不會去 不小心刪除你的源代碼 然後還要嘗試 和調試程序。 但我們希望,它給了 您的說明 這樣的東西那 你可能會想 為你調試程序。 什麼是事務在這裡的狀態呢? 什麼變量做我 有接近我? 具體在哪裡我的計劃 崩潰,在哪一行, 什麼調用什麼功能? 什麼樣的線索,這是否能給我嗎? 而這也正是 一種心態,你 應該進入,當你 想著調試程序。 我是道格·勞埃德。 這是CS50。