310 likes | 545 Views
עבודה ב- T2. מבוא לתכנות מערכות. מה נראה היום?. נלמד עבודה בסיסית בטרמינל. נלמד כיצד לכתוב תוכנית ב- Eclipse . נכיר כלים שימושיים ל- Debugging. התכנית. נכתוב תכנית שמנהלת חשבונות בנק מקבלת כפרמטר קובץ שמכיל את נתוני הלקוחות מחכה לפקודות מהמשתמש
E N D
עבודה ב-T2 מבוא לתכנות מערכות
מה נראה היום? • נלמד עבודה בסיסית בטרמינל. • נלמד כיצד לכתוב תוכנית ב-Eclipse. • נכיר כלים שימושיים ל-Debugging. מבוא לתכנות מערכות
התכנית • נכתוב תכנית שמנהלת חשבונות בנק • מקבלת כפרמטר קובץ שמכיל את נתוני הלקוחות • מחכה לפקודות מהמשתמש • בסיום הריצה שומרת את נתוני הלקוחות בקובץ פלט שמתקבל כפרמטר מבוא לתכנות מערכות
התכנית database.txt [Business Yaron Levi 6000.00] [Regular Dani Din 600.00] myuser@t2 > bank database.txt database2.txt add Moshe Cohen Premium 50000.00 deposit Moshe Cohen Premium 4000.00 withdraw Dani Din Regular 300.00 exit myuser@t2 > database2.txt [Business Yaron Levi 6000.00] [Regular Dani Din 300.00] [Premium Moshe Cohen 54000.00] מבוא לתכנות מערכות
התכנית • התכנית תורכב משני מודולים: • מודול לניהול חשבונות • יורכב מהקבצים account.c, account.h • מודול לקליטת פקודות מהמשתמש • יורכב מהקובץ main.c מבוא לתכנות מערכות
שלב 1: התחברות ל-T2 • נשתמש ב-SSH כדי להתחבר ל-T2. • SSH ניתנת להורדה עבור Windows מהכתובת: ftp://ftp.cs.technion.ac.il/pub/ssh-client/sshclient.exe • עבור לינוקס (או OSX) ניתן פשוט לפתוח חלון טרמינל ולהשתמש בפקודה “ssh”. • קדימה לעבודה... מבוא לתכנות מערכות
שלב 1: התחברות ל-T2 • ניצור את מבנה התיקיות הבא תחת תיקית הבית: • mtm • aux_tut מבוא לתכנות מערכות
שלב 2: קידוד • ישנם מספר עורכי טקסט על ה-T2: • nano • נראה בהמשך... • Emacs • עורך טקסט מתקדם • מומלץ לנסות • קראו עליו בשקפי הסדנאות המקוריים שבאתר הקורס • זה בסה"כ כמה שקפים... מבוא לתכנות מערכות
שלב 2: קידוד • כעת נוותר על הקידוד ונעתיק את קבצי התכנית מהתיקייה ~mtm/public/1314b/aux_tut/bank • אמורה להווצר לנו תיקיית bank תחת aux_tut מבוא לתכנות מערכות
שלב 3: קומפילציה • לאחר כתיבת הקוד, אנו רוצים להריץ את התכנית. • לפני כן, יש לקמפל את הקוד. • ברוב מערכות ה-Unix מותקן קומפיילר C הקרוי GCC. • קיצור עבור GNU Compiler Collection. • לא להתבלבל בין קומפיילר לסביבת פיתוח (IDE). • הקומפיילר הוא תכנית שממירה קבצי קוד (למשל ב-C) לקובץ המכיל קוד אסמבלי, אותו ניתן להריץ. • סביבת פיתוח מכילה קומפיילר, דיבאגר ועוד כלים נוספים. מבוא לתכנות מערכות
שלב 3: קומפילציה • נריץ את הקומפיילר עם קבצי הקוד כפרמטרים. • התקבל קובץ ההרצה a.out. • דומה לקובץ EXE של Windows. מבוא לתכנות מערכות
דגלים של GCC • בקורס זה נקמפל את התכניות שלנו עם שורת הפקודה הבאה: • -o <exefile>מורה לקומפיילר לכתוב את קובץ הפלט לקובץ ששמו exefile במקום לברירת המחדל a.out. • -std=c99 קובע את סטנדרט השפה לפיו הקומפיילר יעבוד. הסטדרנט בקורס הוא C99. • ב-C99 ניתן להגדיר משתנים לא רק בתחילת בלוק, ואף בתחילת לולאת for: • -pedantic-errorsמכריח את הקומפיילר להקפיד על הסטנדרט הנבחר ולפלוט שגיאות על הפרות שלו. myuser@t2 > gcc -o <exefile> -std=c99 -pedantic-errors -Wall -Werror<.c files> for (int i = 0; i < n; ++i) { printf("%d\n", i); } מבוא לתכנות מערכות
דגלים של GCC • בקורס זה נקמפל את התכניות שלנו עם שורת הפקודה הבאה: • -Wall גורם לקומפיילר להציג את כל האזהרות בזמן קומפילציה. • אזהרות קומפילציה דומות לשגיאות. • שגיאות (errors) מפסיקות את הקומפילציה, בעוד אזהרות (warnings) לא. • בד"כ מצביעות על טעויות מתכנת או על קוד שנכתב בצורה לא טובה. • נעדיף לראות את אזהרות אלו ולחסוך לנו טעויות בהמשך. • -Werrorמורה לקומפיילר להתייחס לאזהרה כאל שגיאה. • כלומר הקוד שלכם בקורס חייב להתקמפל גם ללא אזהרות. • בד"כ (ובקורס הזה תמיד) אין סיבה שהקוד שלכם יכיל אזהרות. myuser@t2 > gcc -o <exefile> -std=c99 -pedantic-errors -Wall -Werror <.c files> מבוא לתכנות מערכות
שלב 3: קומפילציה • כעת נקמפל את התכנית מחדש בעזרת כל הדגלים הדרושים. • נחזיק אצבעות שלא נקבל אזהרות מהקומפיילר... מבוא לתכנות מערכות
שלב 4: הרצת ובדיקת התכנית • כעת נרצה לבדוק האם התכנית שלנו נכונה: • נריץ את התכנית עם קובץ נתונים מוכן מראש. • נכניס מספר פקודות לתכנית. • נוודא שקובץ הפלט זהה למה שאנו מצפים. • זוהי השיטה הידנית, והיא אינה יעילה כאשר מבצעים שינוי קטן בקוד. מבוא לתכנות מערכות
שלב 4: הרצת ובדיקת התכנית • נרצה לפתח שיטה אוטומטית לבדיקת התכנית: • נכתוב קבצי קלט וקובץ פלט צפוי. • נריץ את התכנית עם קבצי הקלט. • נבדוק בצורה אוטומטית האם קובץ הפלט זהה לקובץ הפלט הצפוי. • שיטה זו חוסכת הכנסת קלט ידנית לתכנית בשלב הבדיקה. איך עושים את זה?! מבוא לתכנות מערכות
השוואת טקסט: diff • הפקודה diff משמשת להשוואת שני קבצי טקסט. • אם הקבצים זהים לא יודפס כלום. • אם הם שונים יודפסו השינויים שיש לבצע על הקובץ הראשון כדי להפכו לשני. myuser@t2 > cat file1.txt [Business Yaron Levi 6000.00] [Regular Dani Din 600.00] myuser@t2 > cat file2.txt [Premium Moshe Cohen 54000.00] [Business Yaron Levi 6000.00] [Regular Dani Din 300.00] myuser@t2 > diff file1.txt file2.txt 0a1 > [Premium Moshe Cohen 54000.00] 2c3 < [Regular Dani Din 600.00] --- > [Regular Dani Din 300.00] • בדוגמה: • 0a1: בשורה 0 (לפני השורה הראשונה) יש להוסיף את שורה 1 (מהקובץ השני) • :2c3 את שורה 2 יש להחליף בשורה 3 מהקובץ השני. • אכן, הפלט אינו נוח לקריאה. מבוא לתכנות מערכות
השוואת טקסט: diff • אם יש פלט – הקבצים שונים! • אם אין פלט – הקבצים זהים! מבוא לתכנות מערכות
השוואת טקסט: sdiff • sdiff מאפשרת צורה נוחה יותר להבנת ההבדלים בין קבצים כאשר הם אכן קיימים. shiroko2@t2 > diff file1.txt file2.txt > [Premium Moshe Cohen 54000.00] [Business Yaron Levi 6000.00] [Business Yaron Levi 6000.00] [Regular Dani Din 600.00] | [Regular Dani Din 300.00] מבוא לתכנות מערכות
שלב 4: הרצת ובדיקת התכנית • נרצה לפתח שיטה אוטומטית לבדיקת התכנית: • נכתוב קבצי קלט וקובץ פלט צפוי. • נריץ את התכנית עם קבצי הקלט. • נבדוק בעזרת diffהאם קובץ הפלט זהה לקובץ הפלט הצפוי. מבוא לתכנות מערכות
שלב 4: הרצת ובדיקת התכנית • נכתוב תרחישים קצרים הבודקים את התכנית • קובץ נתונים התחלתי • קובץ קלט לפקודות • קובץ הפלט הצפוי • למזלנו כבר כתבו עבורנו כמה כאלה, בתיקייה test. • כדי לבדוק את התכנית נריץ את הפקודות הבאות: • אם לא מודפס כלום התכנית עובדת כמתוכנן. • אחרת ננתח את הפלט ונבדוק מהי ההתנהגות הלא נכונה. • אפשר גם שהתכנית תתרסק ולא נגיע לפקודה השנייה. myuser@t2 > ./bank test/test1.data out.txt < test/test1.in myuser@t2 > diff out.txt test/test1.out מבוא לתכנות מערכות
תכונות ה-Shell • ה-Shell היא הסביבה הטקסטואלית בה מורצות הפקודות בשימוש בטרמינל. • בהתחברות ל-T2 מופעלת ה-Shell הקרויה Bash. • כל Shell מכילה קיצורים ע"מ להקל על המשתמש. • קיצורים בסיסיים המקלים על העבודה: • TAB: משלים את המילה הנוכחית לשם קובץ או פקודה. • ניתן להשתמש בחצים ↑/↓ כדי לעבור על הפקודות האחרונות שבוצעו. מבוא לתכנות מערכות
Scripts • ניתן לכתוב מספר פקודות בקובץ טקסט ולהריץ אותן ע"י הפקודה source. • קבצים אלו נקראים תסריטים (scripts). • כרגע נכיר בצורה בסיסית, ובהמשך הקורס נעמיק בחומר. • לדוגמה, ניתן לכתוב Script שמגבה את הקוד שלנו על השרת. מבוא לתכנות מערכות
שלב 5: בדיקות אוטומטיות • אנו יודעים כיצד לבדוק את התכנית בצורה אוטומטית. • אנו יודעים לכתוב תסריטים. • נאחד את השיטות כדי לאפשר בדיקה אוטומטית משופרת. • הקפידו על יצירת בדיקות ותסריט להרצתן כבר בתחילת העבודה • הריצו לאחר כל שינוי בקוד • הרצה קבועה של הבדיקות תמנע בזבוז זמן בבדיקות ו"פאדיחות" ברגע האחרון. run_tests.csh gcc -o bank -std=c99 -pedantic-errors -Wall -Werrormain.caccount.c echo “Test no.1 (Adding accounts)” ./bank test/test1.data out.txt < test/test1.in diff out.txt test/test1.out echo “Test no.2 (Depositing)” ./bank test/test2.data out.txt < test/test2.in diff out.txt test/test2.out echo Test no.3 (Withdraw) ./bank test/test3.data out.txt < test/test3.in diff out.txt test/test3.out myuser@t2 > source run_tests.csh Test no.1 (Adding accounts) Test no.2 (Depositing) Test no.3 (Withdraw) myuser@t2 > מבוא לתכנות מערכות
שלב 6: דיבוג • כלי אחרון וחשוב לעבודה במנשק טקסט הוא GDB. • GDB הוא דיבאגר בסיסי המגיע בד"כ עם GCC. • "דיבאגר" מאפשר להריץ את התכנית שלנו בצורה מבוקרת ולבדוק את מצב התכנית. • איתור נקודות התרסקות • הדפסת ערכי משתנים • כאשר מקמפלים את התכנית לצרכי "דיבוג" חשוב להוסיף את הדגל -g. • עוזר ל-GDB לספק לנו מידע מקיף יותר. myuser@t2 > gcc -o bank -g -std=c99 -pedantic-errors -Wall -Werrormain.caccount.c מבוא לתכנות מערכות
GDB vs. Segmentation Fault #include<stdio.h> int twice(int* ptr) { int result = *ptr + *ptr; return result; } int main() { int a = 5; printf("%d\n",twice(&a)); int* ptr = NULL; printf("%d\n",twice(ptr)); return 0; } • נביט בתכנית הנתונה משמאל • הקוד נמצא בתיקייה ~mtm/public/1314b/aux_tut/crash מבוא לתכנות מערכות
GDB vs. Segmentation Fault #include<stdio.h> int twice(int* ptr) { int result = *ptr + *ptr; return result; } int main() { int a = 5; printf("%d\n",twice(&a)); int* ptr = NULL; printf("%d\n",twice(ptr)); return 0; } • קריאת מצביע שערכו NULL תגרום לקריסת התכנית • בתכנית הנתונה הקריאה השנייה ל-f תגרום לקריאת הערך ממצביע NULL. • הרצה רגילה של התכנית ללא דיבאגר אינה מספקת מידע על הסיבה להתרסקות. myuser@t2 > gcccrash.c myuser@t2 > ./a.out 10 Segmentation fault myuser@t2 > מבוא לתכנות מערכות
GDB vs. Segmentation Fault • נריץ את GDB עם קובץ ההרצה שנרצה לדבג • GDB עובדת בעזרת מנשק טקסטואלי. כאשר התכנית הנבדקת אינה רצה תופיע שורת פקודה בה ניתן להכניס פקודות שונות של GDB, למשל: • run - מריצה את התכנית • continue - ממשיכה את ריצת התכנית לאחר הפסקה • step מריץ שורת קוד אחת בדיוק (נכנס לפונקציה) • print - מקבל שם משתנה או ביטוי כפרמטר ומדפיס את ערכו • ניתן לעצור זמנית את ריצת התכנית ע"י Ctrl+z. • ניתן להפסיק את ריצת התכנית לחלוטין ע"י Ctrl+C. myuser@t2 > gdb <binary file> מבוא לתכנות מערכות
GDB vs. Segmentation Fault • הדגל -q חוסך הדפסה של הודעת הפתיחה. • הפקודה run יכולה לקבל פרמטרים להרצת התכנית • ע"י backtrace ניתן להדפיס את מחסנית הקריאות. • במקרה שלנו הפונקציה twice נקראת מ-main. myuser@t2 > gcc -g crash.c myuser@t2 > gdb -q a.out (gdb) run Using host libthread_db library "/lib64/tls/libthread_db.so.1". Starting program: /u1/115/myuser/a.out 10 Program received signal SIGSEGV, Segmentation fault. 0x00000000004004b4 in twice (ptr=0x0) at crash.c:4 4 int result = *ptr + *ptr; (gdb) backtrace #0 0x00000000004004b4 in twice (ptr=0x0) at crash.c:4 #1 0x00000000004004fa in main () at crash.c:12 (gdb) מבוא לתכנות מערכות
Breakpoints • חלק גדול מהבאגים הם שגיאות התנהגותיות של התכנית. • כדי לבדוק אותן נרצה לעצור את התכנית, לבדוק את ערכי המשתנים ולהתקדם צעד צעד. • כדי לעצור את התכנית בשורת קוד מסוימת נוסיף נקודת עצירה (breakpoint) ע"י הפקודה break ושם הפונקציה שיש לעצור בתחילתה • נוכל לבדוק את ערכי המשתנים בעזרת הפקודה print. • כדי להמשיך בריצת התכנית נשתמש ב-continue (המשך עד נקודת העצירה הבאה) • כדי להתקדם בצורה מבוקרת נשתמש בפקודה step. מבוא לתכנות מערכות
GDB: סיכום • העבודה עם GDB אינה פשוטה בהתחלה. • עדיין עדיפה על עבודה ללא דיבאגר. • התחילו בשימוש בפקודות הפשוטות שמוצגות כאן. • ניתן לקבל את רשימת הפקודות המלאה ע"י הפקודה help ולקבל מידע מפורט יותר. מבוא לתכנות מערכות