צעדים לניפוי שגיאות

לכל שפת תכנות יש את הבעיות שלה כאשר זה נוגע לניפוי שגיאות. חלק גדול מבעיות אלו ניתנות למציאה ע"י שימוש נכון בהדפסה על המסך/קובץ או כל סוג פלט אחר של ערכים ומיקום.

ב FPC מגיעים 2 כלים נוספים ל writeln אשר יעזרו לנו למצוא בעיות בתוכנה שלנו הרבה לפני שניגש לתותחים הכבדים של gdb ו valgrind:

מי גרם ליצירת חריגה ?

חריגה (exception) היא צורה לעצור ריצה כי התרחשה שגיאה מספיק חמורה שצריך להתייחס אליה. הבעיה היא, שרוב המפתחים לא תופסים את כל החריגות השונות. למזלנו, FPC ממש כמו הרבה כלים מודרניים, מספקת לנו רשימה מלאה של מי ואיפה בוצעה החריגה בערימה שלנו. כך במידה שיש לנו חריגה לא מטופלת, נוכל לאתר את כל המסלול של מי שיצר אותה:

An unhandled exception occurred at $00000000004001C8 :
Exception : An Exception was raised.
$00000000004001C8 line 7 of test2.pp
$00000000004001E9 line 12 of test2.pp
$00000000004001FE line 17 of test2.pp

(כמו שניתן לראות אני על מערכת 64 ביט לפי כתובות הזכרון).

מה שאנחנו רואים כאן, הוא הדפס של חריגה שלא טיפלנו בה ושהתרחשה בשורה 7, ומי שקרא לקוד שיצר את החריגה נמצא בשורה 17 .

שימו לב שבמידה שלא הידרנו את הקוד שלנו עם מספרי שורה, אז נקבל רק את כתובות הזכרון. אני מסביר בסעיף הבא כיצד להוסיף את מספרי השורה בזמן הידור.

עכשיו בניגוד לרוב הכלים הקיימים, אני יכול להגדיר מצב בו אני מקצר את הרשימה למקום האחרון של מי שגרם לחריגה (כלומר שורה 12).

אני אעשה את זה בצורה הבאה:

raise Exception.Create('An Exception was raised.') at get_caller_addr (get_frame);

הפונקציה get_caller_addr מחזירה מצביע של המסגרת בערימה. הפונקציה get_frame מחזירה לנו את המסגרת עצמה.

איפה לסתום דליפות ?

בפסקל סדר הטעינה של דברים הוא משמאל לימין. כאשר מדובר ביחידות, היחידה הכי שמאלית, היא היחידה שתשפיע על מי שקרא לה במידה של אתחול בזמן טעינת היחידה. ההשפעה הזו, היא כמובן על הקוד שמשתמש באותה יחידה (כלומר מי שהכריז על היחידה ב uses), ולא בכל התוכנית.

בזכות הfeature הזה ניתן לנצל תכונות שמגיעות עם FPC: רישום מנהלים שונים לסוגים שונים של ביצועים. למשל לניהול זכרון של GetMem, FreeMem ושאר הפונקציות והפרוצדורות לניהול הזכרון יש מנהל שבהם הם נרשמו. בפועל מה שקורה זה, שיחידת System משתמשת במנהל בשביל לקרוא לניהול הזכרון ולא ישירות ל Getmem, מה שאומר שאם נשתמש ביחידה cmem, היא תשתמש בניהול הזכרון של libc, למרות שהשתמשנו בפונקציה GetMem.

עוד משהו מעוד מעניין משתמש ברעיון הזה של אפשרות טעינה משמאל לימין היא היחידה heaptrc. היחידה מאפשרת למפות נקודות של אתחול ושחרור זכרון של GetMem ו FreeMem וכן שימוש ב new ו dispose. איך עובדים עם היחידה ? ובכן אם רוצים לבדוק קוד מאוד ספציפי שלנו, נשתמש בה בשורת ה uses בתור היחידה הראשונה. במידה שיש עניין לבדוק את כל הפרוייקט, אז ניתן למהדר פרמטר בעת ההידור:

ppcXXX -ghl <program_to_compile>

הXXX מציין את סוג הפלטפורמה שלכם, למשל ppci386 ל32 ביט או ppcx64 ל64 ביט וכו'.

-g מדבר על תכונות לניפוי שגיאות ב fpc, כלומר כל הוראה למהדר בשביל ניפוי שגיאות תשתמש במקדם של g.

האפשרות h אומרת לו להשתמש ביחידה heaptrc בכל הפרוייקט, בלי צורך להוסיף אותה ידנית, מה שאומר שאין צורך בתנאי $IFDEF למצב ניפוי שגיאות או משהו בסגנון.

האפשרות l אומרת למהדר להוסיף מספר שורה, וכאשר יש איתור לאחור, נקבל יותר מידע כולל מספר שורות.

כיצד היחידה עובדת ?

היחידה עוקבת תוך שימוש במשתני סביבה בכל קריאה לאתחול זכרון, ובמידה ובסוף הריצה, לא היה שחרור של אותה נקודת זכרון, נקבל על כך דיווח (על המקום בו אותחל הזכרון). במידה והכל שוחרר כמו שצריך, נקבל דיווח בו נראה שהכל שוחרר כמו שצריך.

למשל במידה ושיחררנו זיכרון, נקבל את הדיווח הבא:

Heap dump by heaptrc unit
1 memory blocks allocated : 1024/1024
1 memory blocks freed : 1024/1024
0 unfreed memory blocks : 0
True heap size : 262144
True free heap : 262144

וכאשר לא שיחררנו זכרון, נקבל הודעה כזו:

Heap dump by heaptrc unit
1 memory blocks allocated : 1024/1024
0 memory blocks freed : 0/0
1 unfreed memory blocks : 1024
True heap size : 262144
True free heap : 260960
Should be : 261008
Call trace for block $00002AFD8083D0A0 size 1024
$00000000004001B8 line 7 of test2.pp
$0000000000400178

מחשבה אחת על “צעדים לניפוי שגיאות

  1. פינגבק: ניהול גמיש | לראות שונה

כתיבת תגובה

הזינו את פרטיכם בטופס, או לחצו על אחד מהאייקונים כדי להשתמש בחשבון קיים:

הלוגו של WordPress.com

אתה מגיב באמצעות חשבון WordPress.com שלך. לצאת מהמערכת / לשנות )

תמונת Twitter

אתה מגיב באמצעות חשבון Twitter שלך. לצאת מהמערכת / לשנות )

תמונת Facebook

אתה מגיב באמצעות חשבון Facebook שלך. לצאת מהמערכת / לשנות )

תמונת גוגל פלוס

אתה מגיב באמצעות חשבון Google+ שלך. לצאת מהמערכת / לשנות )

מתחבר ל-%s