stacktrace ן backtrace_symbol

mandymo

New member
stacktrace ן backtrace_symbol

נניח ואני רוצה למצא את הbacktrace שלי. בהנחה ואני תחת אינטל, ומקמפל עם g++ (בלי פלאגים מיותרים), אני יכול לקרא את הערך של ebp, כדי לקבל את ה return address הראשון, לקפוץ אליו, לקרא את ה return address הבא וכן הלאה. אז יש לי רשימת כתובות, על ה stack שהם ה return address שלי.
מה שלא ברור לי זה איך, מהכתובות האלה אני מגיע לפונקציות שקראו להן (או, לשורה שמהן הן נקראו).
ז.א איך, לדוגמה addr2line יודע לבצע את ההמרה הזו, מכתובת על ה stack, לפונקציה, שמוגדרת בקוד סיגמנט .
שאלה נוספת, האים יש דרך "זולה" לבצע את ההמרה הזו, כשהפרוסס עדיין חיי.
אני מניח ש addr2line משתמש ב dlopem, dladdr וכד. ז.א לרקא לו בזמן ריצה, זה דיי יקר. יש משהו "זול" יותר??
 

vinney

Well-known member
אתה צריך את הmap file

זה קובץ (שנכלל בגרסת debug של exe לעתים) שכולל מיפוי של כל הפונקציות (ה"ציבוריות").

אתה יכול לדעת לאיזו פונקציה שייכת הכתובת לפי הפרשים, ואם יש מידע נוסף - אתה אף יכול להתאים את זה לשורה בקוד מקור (תלוי בדגלים שהעברת לGCC בקומפילציה, לא זוכר בדיוק את האופציות שיש).

אם יש לך גישה לMAP בזמן ריצה - אתה יכול לעשות בדיוק אותו דבר כבר בזמן ריצה. זה מה שהGDB עושה.
 

mandymo

New member
זה מה שאני מנסה לכתוב...

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

selalerer

New member
מצורף הקובץ עצמו.

אין צורך לעשות dlopen היות וכל כתובת ב-stack שלך היא של קוד שכבר טענת לזיכרון.
 

mandymo

New member
האמת -צודק.

עכשיו,כשהסתכלתי על הקוד באמת, אתה צודק.
תודה!
 
למעלה