>> דאג LLOYD: כל GDB הנכון.
מה זה בדיוק?
אז GDB, העומד לDebugger של גנו,
הוא כלי מדהים באמת שאנחנו יכולים להשתמש בו כדי לעזור לנו לאתר באגים התוכניות שלנו,
או לגלות בו דברים הם השתבש בתוכניות שלנו.
GDB הוא חזק להפליא, אבל הפלט ואינטראקציה עם זה
יכול להיות קצת סתום.
זה בדרך כלל כלי שורת הפקודה, ו זה יכול לזרוק הרבה הודעות בך.
וזה יכול קצת קשה לנתח בדיוק מה קורה.
צעדים למרבה המזל, אנחנו כבר נלקחו כדי לתקן בעיה זו עבורך
כפי שאתה עובד דרך CS50.
אם אתה לא משתמש בגרפי הבאגים, העמית שלי שדן
Armandarse דיבר די קצת על בוידאו ש
צריך להיות כאן עכשיו, ייתכן שתצטרך
להשתמש שורת הפקודה הבאות כלים לעבודה עם GDB.
אם אתה עובד בCS50 IDE, אתה לא צריך לעשות את זה.
אבל אם אתה לא עובד בIDE CS50,
אולי משתמש בגרסה של CS50 Appliance,
או הפעלה אחרת לינוקס מערכת עם GDB מותקן עליה,
ייתכן שתצטרך להשתמש ב כלי שורת הפקודה הבאים.
>> ומכיוון שאולי אתה צריך לעשות את זה, זה
שימושי רק כדי להבין כיצד GDB עובד משורת הפקודה.
אבל שוב, אם אתה באמצעות IDE CS50,
יכול להשתמש הבאגים הגרפיים כי הוא מובנה בתוך IDE.
אז כדי לקבל דברים הולכים עם GDB, להתחיל באגים
תהליך מסוים תכנית, כל מה שאתה צריך לעשות
הוא סוג GDB ואחרי בשם התכנית.
כך למשל, אם התכנית שלך היא שלום, עליך להקליד שלום GDB.
>> כאשר אתה עושה את זה, אתה הולך כדי למשוך את סביבת GDB.
הפקודה שלך תשתנה, ו במקום להיות מה שהיא בדרך כלל
כאשר אתה מקליד דברים בLS line-- הפקודה,
cd-- כל הטיפוסי שלך פקודות לינוקס, הפקודה שלך
ישתנה, כנראה, משהו כמו סוגריים GDB סוגריים.
זה הפקודה GDB החדשה שלך, בגלל ש אתה בתוך סביבת GDB.
ברגע שנכנס לסביבה ש, יש שתי פקודות גדולות
כי אתה בטח להשתמש לפי הסדר הבא.
>> הראשון הוא ב, ש קצר להפסקה.
ואחרי שאתה מקליד ב, אתה בדרך כלל הקלד את השם של פונקציה,
או אם אתה יודע במקרה סביב מה קו מספר
התכנית שלך מתחילה להתנהג קצת מוזר,
באפשרותך להקליד קו מספר גם שם.
מה ב, או הפסקה, עושה זה מאפשר לך תכנית
לרוץ עד לנקודה מסוימת, כלומר, את השם של הפונקציה
שציינת או הקו מספר שציינת.
>> ובשלב זה, זה יקפיא ביצוע.
זה דבר ממש טוב, כי פעם אחת ביצוע הוקפא,
אתה יכול להתחיל לאט לאט צעד דרך התכנית שלך.
בדרך כלל, אם אתה כבר פועל התוכניות שלך, הם די קצרים.
בדרך כלל, אתה מקליד קו נטוי נקודה מה ש שמו של התכנית שלך, לוחץ על Enter,
ולפני שאתה יכול למצמץ, תכנית כבר נגמרה.
זה לא ממש הרבה זמן כדי לנסות ולהבין מה השתבש.
אז זה באמת להיות מסוגל להאט דברים על ידי הגדרת נקודת הפסקה עם ב,
ולאחר מכן דריכה ב.
>> ואז ברגע שהגדרת ההפסקה שלך נקודה, אתה יכול להפעיל את התכנית.
ואם יש לך שורת פקודת טיעונים,
אתה מציין אותם כאן, לא כש אתה מקליד GDB שם התכנית שלך.
אתה מציין את כל שורת הפקודה טיעונים על ידי לקיחת r, או לרוץ,
ולאחר מכן את טענות קו מה הפקודה אתה צריך בתוך התכנית שלך.
יש מספר אחר באמת פקודות חשובות ושימושיות
בתוך סביבת התמ"ג.
אז תן לי רק במהירות לעבור על כמה מהם.
>> הראשון הוא n, שהוא קצר עבור הבא, ואתה יכול להקליד הבא במקום n,
שני יעבדו.
וזה רק הקצרנות.
וכמו שבטח קיבל כבר משמש ל, להיות מסוגל להקליד דברים
קצר יותר הוא בדרך כלל טוב יותר.
ומה זה יעשה הוא שזה צעד קדימה אחד בלוק של קוד.
אז זה יהיה להתקדם עד קריאה לפונקציה.
ואז במקום צלילה לתוך הפונקציה ש
ועובר את כל פונקציות ש קוד, זה יהיה רק ​​צריך לתפקד.
>> הפונקציה תיקרא.
זה יעשה כל מה העבודה שלה היא.
זה יחזיר ערך ל הפונקציה שקראה לזה.
ואז אתה עובר ל השורה הבאה של פונקציה שקוראות.
אם אתה רוצה לשלב בתוך הפונקציה,
במקום רק שיש זה לבצע, במיוחד
אם אתה חושב שהבעיה עלול לשקר פנימי של פונקציה ש,
אתה יכול, כמובן, להגדיר הפסקה להצביע בתוך הפונקציה ש.
או אם אתה כבר פועל, אתה יכול להשתמש של לצעוד קדימה שורה אחת של קוד.
>> אז זה יהיה צעד ב לצלול לתוך פונקציות,
במקום רק צריכים לבצע וממשיך בפונקציה
כי אתה לניפוי.
אם אי פעם אתה רוצה לדעת הערך של משתנה,
ניתן להקליד עמ ', או הדפסה, ולאחר מכן את השם המשתנה.
ושיהיה להדפיס לך, בתוך סביבת GDB,
השם המשתנה, שאתם-- סלח me-- הערך של המשתנה
כי אתה כבר שם.
אם אתה רוצה לדעת את ערכיו של כל נגיש משתנה מקומי מהמקום שבי
אתה נמצא כרגע בך תכנית, באפשרותך להקליד המקומיים מידע.
זה הרבה יותר מהר מ הקלדת p ואז מה,
רישום את כל משתנים שאתה יודע קיים.
ניתן להקליד המקומיים מידע, וזה יהיה להדפיס את הכל בשבילך.
בשלב הבא הוא BT, אשר הוא קצר לחצר אחורית.
עכשיו, בדרך כלל, מוקדם במיוחד בCS50,
אתה לא באמת יש לי אירוע להשתמש BT, או חזרה Trace,
בגלל שאתה לא נתקלת בפונקציות כי לקרוא לפונקציות אחרות.
>> אולי יש לך שיחה העיקרית פונקציה, אבל זה כנראה זה.
אין לך שפונקציה אחרת קורא פונקציה אחרת, ש
קורא פונקציה אחרת, וכן הלאה.
אבל תוכניות שלך לקבל יותר מורכב, ובמיוחד
כאשר אתה מתחיל לעבוד עם רקורסיה, עקבות בחזרה
יכול להיות דרך שימושית באמת לתת לך סוג של לקבל קצת הקשר לשם
אני בתכנית שלי.
אז אומר לך שכתבת את הקוד שלך, ו אתה יודע שקורא עיקרי פונקציה
F, שקורא לפונקציה g, אשר קורא h פונקציה.
אז יש לנו כמה שכבות של קינון קורה כאן.
>> אם אתה בתוך סביבת GDB שלך,
ואתה יודע בתוכך של שעות, אבל אתה שוכח
על מה יש לך למקום שבך הן-- תוכל להקליד BT, או עקבות בחזרה,
והוא יודפס h, g החוצה, ו עיקרי, לצד חלק מהמידע אחר, ש
נותן לך מושג ש, עיקרי על אישור f נקראת, ו ז נקרא, גרם נקראת h,
וזה המקום שבו כרגע אני בתכנית שלי.
אז זה יכול להיות שימושי מאוד, במיוחד כסתום-נס של GDB
הופך להיות קצת מכריע, ל לברר בדיוק היכן נמצאים דברים.
לבסוף, כאשר התכנית שלך נעשה, או כשתסיים באגים זה
ואתה רוצה להתרחק מסביבת GDB,
זה עוזר לדעת איך לצאת מזה.
ניתן להקליד q, או צא, לצאת.
עכשיו, לפני שהווידאו של היום הכנתי תכנית מרכבה
buggy1 נקרא, שאני הידור מקובץ הידוע כbuggy1.c.
כפי שאפשר לצפות, זה תכנית היא בעגלת עובדה.
משהו משתבש כאשר אני מנסה ולהפעיל אותו.
עכשיו, למרבה הצער, אני לא מדעת נמחק קובץ buggy1.c,
זאת על מנת לי להבין מה השתבש עם תכנית זו,
אני הולך צריך להשתמש GDB סוג של עיוורון, מנסה
כדי לנווט בתכנית זו ב להבין בדיוק מה השתבש.
אבל רק באמצעות הכלים אנחנו כבר למדנו על,
אנחנו יכולים פחות או יותר דמות בדיוק מה שזה.
אז בואו מעל הראש יש לי CS50 IDE ומראה.
אוקיי, אז אנחנו כאן בי סביבת IDE CS50,
ואני להתקרב קצת כך שתוכל לראות קצת יותר.
בחלון המסוף שלי, אם אני ברשימה התוכן של המנהל הנוכחי שלי
עם ls, נראה לי ש יש לי כמה קבצי מקור
כאן, כולל דן בעבר buggy1.
מה בדיוק קורה כש אני מנסה ולהפעיל buggy1.
ובכן בואו לגלות.
אני מקליד קו נטוי נקודה, מרכבה, ואני מכה על Enter.
>> תקלות פילוח.
זה לא טוב.
אם אתה זוכר, אשמת פילוח בדרך כלל
מתרחש כאשר אנו ניגשים לזיכרון שאסור לגעת.
אנחנו כבר הגענו איכשהו מחוץ לגבולות
של מה בתכנית, מהדר, נתן לנו.
וכך כבר זה רמז לשמור בארגז הכלים
כפי שאנו מתחילים את תהליך הניפוי.
משהו הלך קצת לא בסדר כאן.
>> ההתחלה בסדר, אז בואו את סביבת GDB
ולראות אם אנחנו יכולים להבין מה בדיוק הבעיה.
אני הולך לנקות את המסך שלי, ואני הולך להקליד GDB
שוב, להיכנס לסביבת GDB, והשם של התכנית
שאני רוצה לאתר באגים, buggy1.
אנחנו מקבלים הודעה קטנה, קריאה סימנים מbuggy1, עשו.
כל זה אומר שזה משך יחד את כל הקוד,
ועכשיו זה כבר הועמס GDB, והוא מוכן ללכת.
>> עכשיו, מה שאני רוצה לעשות?
האם אתה זוכר מה הצעד הראשון הוא בדרך כלל
אחרי שאני בתוך סביבה זו?
יש לקוות, שאמרת שנקבע נקודת פריצה, כי
בעובדה שזה מה שאני רוצה לעשות.
עכשיו, אין לי קוד מקור לזה
מולי, שהוא כנראה לא במקרה השימוש הטיפוסי, דרך אגב.
אתה כנראה יהיה.
אז זה טוב.
אבל בהנחה שאתה לא, מה פונקציה אחת שיודע
קיים בכל אחד תכנית C?
לא משנה כמה גדול או כמה מסובך זה, בהחלט קיימת פונקציה זו.
ראשי, נכון?
>> אז אי לכל דבר אחר, אנחנו יכולים להגדיר נקודת הפסקה בעיקרית.
ושוב, אני יכול פשוט להקליד לשבור עיקרי, במקום ב.
ואם אתם סקרנים, אם אתה אי פעם להקליד את הפקודה ארוכה
ואז להבין שאתה הקליד את הדבר הלא נכון,
ואתה רוצה להיפטר כל שאני פשוט עשיתי,
אתה יכול לקחת את השליטה U, שיהיה למחוק הכל ולהביא אותך בחזרה
לתחילת קווי הסמן.
הרבה יותר מהר מאשר רק החזק את למחוק, או להכות אותו חבורת פעמים
על.
>> אז נגדיר נקודת הפסקה בעיקרית.
וכמו שאתה יכול לראות, זה אומר שיש לנו להגדיר נקודת הפסקה בbuggy1.c קובץ,
וכנראה השורה הראשונה קוד של עיקרי הוא קו שבעה.
שוב, אין לנו קובץ המקור כאן,
אבל אני מניח שזה אומר לי את האמת.
ואז, אני רק מנסה ולהפעיל את התכנית, r.
הפעלת תכנית.
בסדר, אז הודעה זו הוא קצת סתום.
אבל בעצם מה קורה כאן הוא שזה פשוט
אומר לי שאני פגע ההפסקה שלי נקודה, נקודת מספר 1 הפסקה.
>> ולאחר מכן, קו זה של קוד, אין כזה קובץ או תקייה.
הסיבה היחידה ש אני רואה שהודעה
כי אני בטעות נמחק קובץ buggy.c.
אם קובץ buggy1.c קיים במדריך הנוכחי,
כי זכות קו בעצם יש היית תגיד לי מה את שורת קוד
פשוטו כמשמעו קורא.
לרוע המזל, אני מחקתי אותו.
אנחנו הולכים צריכים לנווט סוג של באמצעות זה קצת יותר באופן עיוור.
>> אוקיי, אז בואו נראה, מה אני רוצה לעשות כאן?
ובכן, אני רוצה לדעת מה מקומי משתנים אולי הם זמינים לי.
אני כבר התחלתי התכנית שלי.
בואו לראות מה יכול להיות כבר אותחל עבורנו.
אני מקליד המקומיים מידע, לא מקומי.
בסדר, אז שלא תן לי טונות של מידע.
אני יכול לנסות ולהדפיס את משתנה, אבל אני לא יודע כל שמות משתנים.
אני יכול לנסות חצר אחורית, אבל אני בתוך עיקרי,
אז אני יודע שאני לא עשיתי קריאה לפונקציה אחרת עכשיו.
>> אז נראה כמו האפשרויות היחידה שלי הן להשתמש n או כך ולהתחיל לצלול ב.
אני הולך להשתמש n.
אז אני מקליד n.
אוי ואבוי, מה קורה כאן.
תכנית קיבלה אותות, אשמת פילוח SIGSEGV,
ולאחר מכן חבורה של דברים כולה.
אני כבר המום.
ובכן, יש למעשה הרבה מה ללמוד כאן.
אז מה זה אומר לנו?
מה זה אומר לנו הוא, תכנית זו היא עומד, אבל עדיין לא, אשמת SEG.
ובפרט, אני הולך כדי להתקרב עוד יותר כאן,
זה בערך לצינוק אשמה על משהו שנקרא strcmp.
>> עכשיו, ייתכן שלא דנו פונקציה זו בהרחבה.
אבל זה הוא-- כי אנחנו לא הולכים לדבר על כל פונקציה ש
קיים בתקן C library-- אבל הם כולם זמינים לך,
במיוחד אם אתה לוקח להסתכל reference.cs50.net.
וstrcmp הוא באמת חזק פונקציה שקיימת בתוך
של כותרת string.h קובץ, אשר היא כותרת
קובץ שמוקדש לפונקציות כי עבודה עם ולתפעל מחרוזות.
>> ובפרט, מה שעושה הוא strcmp הוא משווה את הערכים של שתי מחרוזות.
אז אני עומד פילוח אשמה בשיחה לstrcmp שזה נראה.
אני מכה n, ולמעשה אני מקבל את ההודעה, תכנית הסתיימה עם SIGSEGV אות
אשמת פילוח. אז עכשיו אני ממש פגמתי SEG,
והתכנית שלי יש די הרבה יעילות ויתר.
זה הסוף של התכנית.
זה נשבר, התרסק.
אז לא היה הרבה, אבל אני למעשה עשה ללמוד לא מעט
מהניסיון הקטן הזה.
מה למדתי?
ובכן, התכנית שלי מתרסקת פחות או יותר באופן מיידי.
התכנית שלי מתרסקת על קורא לstrcmp, אבל אני
אין לי שום משתנים מקומיים בי תכנית בזמן שהוא מתרסק.
אז מה מחרוזת, או מחרוזות, אני יכול אולי להיות השוואה.
אם אין לי שום מקומי משתנים, שאולי
לשער שנו-- יש אולי הוא משתנה גלובלי, שיכול להיות נכון.
>> אבל בדרך כלל, זה נראה כאילו אני משווה
למשהו שאינו קיימים.
אז בואו לחקור כי עוד מעט.
אז אני הולך לנקות את המסך שלי.
אני הולך להיסגר מחוץ ל סביבת GDB לשנייה.
ואני חושב, בסדר, אז יש אין משתנים מקומיים בתכנית שלי.
אני תוהה אם אולי אני אמור לעבור במחרוזת כטיעון שורת הפקודה.
אז בואו פשוט לבדוק את זה.
אני לא עשיתי את זה קודם.
>> בואו אראה אם ​​אולי אם אני מפעיל תכנית זו עם טיעון שורת הפקודה זה עובד.
הא, לא באשמת פילוח שם.
זה פשוט אמר לי שהבנתי את זה.
אז אולי זה התיקון כאן.
ואכן, אם אני חוזר ומסתכל קוד המקור הממשי לbuggy1.c,
זה נראה כאילו מה שאני עושה הוא אני עושה שיחה לstrcmp ללא
לבדוק אם אכן argv [1] קיים.
זהו למעשה קוד המקור לbuggy1.c.
אז מה אני באמת צריכה לעשות כאן כדי לתקן את התכנית שלי,
בהנחה שיש לי להגיש מולי, הוא
רק להוסיף סימון כדי להפוך את בטוח שargc הוא שווה ל 2.
אז דוגמא זו, שוב, כמו שאמרתי, זה קצת מאולץ, נכון?
אתה לא בדרך כלל הולך ל להסיר את קוד המקור שלך בטעות
ולאחר מכן יש לנסות ולאתר באגים בתכנית.
אבל אני מקווה, זה נתן לי אתה איור
של מיני דברים ש אתה יכול לחשוב על
כפי שאתה באגים התכנית שלך.
>> מה מצב עניינים כאן?
מה לעשות אני משתנים יש לי נגיש לי?
איפה בדיוק התכנית שלי מתרסק, על מה קו,
על מה קריאה לפונקציה מה?
איזה סוג של רמזים שאין לתת לי?
וזה בדיוק סוג של הלך רוח ש
יש להיכנס לכאשר אתה חושב על באגים התוכניות שלך.
>> אני דאג לויד.
זה CS50.