نمایش نتایج 1 تا 7 از 7

نام تاپیک: استفاده از رهنمودهای کامپایلر

  1. #1

    استفاده از رهنمودهای کامپایلر

    سلام دوستان. میخواستم ببینم از رهنمود {+D$} چطور میتوانم در برنامه استفاده کنم.
    ونتیجه دیباگ اونو کجا میتونم ببینم.

  2. #2

  3. #3
    اقای خورسندی عزیز اتفاقا همین مقاله رو خوندم و برام سوال پیش اومد. واضح توضیح نداده بودین که چطور میشه debug های مربوط به فرم رو خوند.در مورد map file توضیح داده بودین. من فعالش کردم .برنامه رو کامپایل کردم ولی در هنگام رخ دادن AV در mapfile چیزی مشاهده نکردم.اگه میشه این قسمت رو بیشتر توضیح بدین ممنون میشم.

  4. #4
    شما map file رو بر روی Detailed تنظیم کنید و آدرسی که از AV دریافت میکنید رو در mapfile جستجو کنید، در ضمن mapfile هنگام کامپایل برنامه ساخته میشه و بعد از اون در حین اجرای برنامه تغییری نمیکنه.
    سعی میکنم تو یکی-دو روز آینده بیشتر توضیح بدم.

  5. #5
    ممنون میشم .درمورد پارامتر {+D$} هم توضیحی بدین.و نحوه استفاده از اون.
    باتشکر.

  6. #6
    آقای خرسندی عزیز بی صبرانه منتظر توضیحات ارزنده شما هستم.

  7. #7
    تبدیل آدرس AV در دلفی


    این امکان وجود دارد که آدرس دریافتی از یک Access Violation که حین اجرای برنامه پیش می‌آید را به نام یونیت، نام تابع و شماره خط در سورس کد تبدیل کرد. این کار با یک Detailed map file که در زمان کامپایل برنامه ایجاد می‌شود، قابل انجام است.

    ایجاد یک map file‌:
    ابتدا لازم است که یک map file به روش زیر برای پروژه ایجاد کنیم:
    1- مطمئن باشید که سوئیچ Code Optimization که در منوی Project -> Options در تب Compiler هست، غیر فعال باشد.
    2- از منوی Project -> Options در تب Linker سوییچ map file را برروی Detailed تنظیم کنید.
    3- حالا برنامه را با Project -> Build All دوباره Build کنید. یک map file با نام پروژه ساخته می‌شود، مثلا اگر نام پروژه Project.exe باشد map fileیی با نام project.map خواهیم داشت.


    تبدیل آدرس AV :
    حالا اگر یک AV دریافت کنید، میتوانید با استفاده از روش زیر آن را تبدیل به نام یونیت، نام تابع و شماره خط در سورس کد کنید:

    1- به Project -> Options -> Linker -> Image base مقدار $1000 را اضافه کنید (هر دو مقدار هگزادسیمال‌اند)، حاصل به شکل زیر خواهد بود:
    Offset = Linker | Memory sized | Image Base value + $1000

    و چون مقدار پیش‌فرض Image base معمولاً $00400000 هست، مقدار نهایی برابر با $00401000 خواهد بود.

    حالا Offset را از آدرس دریافتی از AV کم کنید، به شکل زیر:
    Map file address = Access Violation address – offset

    برای مثال، اگر آدرس AV مقدار $00437575 را داشته باشد، پس خواهیم داشت :

    Offset = $400000 + $1000 = $401000 و
    Map file address = $00437575 - $401000 = $36575


    2- Map file را با یک ادیتور متنی(فرضاً Notepad) باز کنید، با IDE دلفی هم می‌توانید این کار را بکنید(map file یک فایل متنی است).


    3- پیدا کردن نام یونیت :
    داخل map file بخشی که شامل نام یونیتهاست تحت عنوان "Detailed map of segment" را پیدا کنید، معمولاً در بالای فایل قرار دارد. این بخش شامل لیست segment، آدرس شروع، طول و سایر اطلاعات و نام یونیت هست که براساس آدرس مرتب شده اند.
    برای پیدا کردن نام یونیت در جایی که AV روی داده، آدرس map file را با استفاده از آدرس شروع و اندازه در لیست پیدا کنید. برای مثال، اگر آدرس map file از AV برابر با $36575 باشد، نام یونیت Unit1 خواهد بود.
    مثال :

    نکته : Unit1 در محدوده‌ی آدرسی $35184 تا $365CC قرار دارد، چگونه این محدوده‌ی آدرسی بدست می‌آید:

    طول -> $00001448
    آدرس شروع -> $00035184

    اگر آدرس شروع را با طول جمع کنیم، محدوده آدرسی Unit1 بدست می‌آید، یعنی در نهایت ما دو عدد داریم که محدوده‌ی یونیت را مشخص می‌کند. سپس می‌توان با یک عملیات ریاضی ساده! متوجه شد که آیا آدرس دریافتی از خطای AV در این محدود قرار دارد یا خیر، تا از این طریق نام یونیت را پیدا کنیم.
    طول + آدرس شروع = محدوده
    4- پیدا کردن نام تابع :
    در map file در بخش مختلف فهرست توابع وجود دارد. یکی در جایی که توابع بر اساس نام آنها مرتب شده‌اند و 'Publics by name' نام دارد و دیگری که بر اساس آدرس مرتب شده است و 'Publics by value' نام دارد. هر دو لیست شامل آدرس تابع و نام تابع است. برای پیدا کردن نام تابع هنگامی که AV روی می‌دهد از بخش 'Public by name' استفاده کنید و آدرس را در آن لیست جستجو کنید. ممکن است آدرس دقیقاً مطابق با آدرسی که از AV دریافت کرده‌اید و روی آن محاسبه انجام داده‌اید در map file نباشد، دلیل آن هم این است که خطا می‌تواند در هر جایی از تابع روی داده باشد. اما شما نزدیکترین آدرس که از آدرس AV کوچکتر باشد را بیابید.

    آدرس خطای دریافتی از AV برابر است با $00437575 :
    Map file address = $00437575 - $401000 = $36575

    0001:0003642C TForm1.Button9Click
    0001:00036484 TForm1.Button10Click
    0001:00036564 TForm1.Button11Click
    0001:0003657C Finalization
    0001:000365C4 Unit1

    5- پیدا کردن شماره خط:
    در انتهای map file بخشی برای هر یونیت کامپایل شده شامل شماره خط، Segment و آدرس شروع وجود خواهد داشت که بر اساس آدرس خط مرتب شده‌اند. هر چهار شماره خط در یک خط در map file قرار دارد. در این مرحله، بخشی که مربوط به یونیت مورد نظر است را پیدا کنید(نام یونیت را در مرحله سوم پیدا کرده‌اید)، سپس برای پیدا کردن شماره خطی که AV در آن روی داده، نزدیکترین آدرس که از آدرس AV کوچکتر باشد را جستجو کنید.
    برای مثال، اگر AV آدرس $36575 را برگرداند، شماره خط با توجه به مثال زیر 367 خواهد بود:




    نکته:
    مرحله‌ی اول که تغییر مقدار Image base هست را با دلفی 5 انجام دادم، ولی متاسفانه با پیغام خطایی مانع ادامه‌ی کار شد. اگر شما هم چنین مشکلی را دارید می‌توانید مقدار Image base را تغییر ندهید و در عوض این مقدار را در مرحله‌ی 1 (تبدیل آدرس AV) جزء محاسبات بیاورید:
    Map file address = AV address - $400000 - $1000 = Result

برچسب های این تاپیک

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •