در کروم 92، Memory Inspector را معرفی کردیم، ابزاری برای بازرسی بافرهای حافظه خطی. در این مقاله، نحوه بهبود Inspector برای اشکالزدایی C/C++ و چالشهای فنی که در این مسیر با آن مواجه میشوید، بحث خواهیم کرد.
اگر با اشکال زدایی C/C++ و Memory Inspector تازه کار هستید، این چند پست وبلاگ مرتبط است:
- به اشکال زدایی حافظه عمیق علاقه دارید؟ به معرفی بازرس حافظه مراجعه کنید.
- آیا می خواهید مقدمه ای برای مجموعه کامل ابزارهای اشکال زدایی C/C++ داشته باشید؟ اشکال زدایی WASM با ابزارهای مدرن و اشکال زدایی WebAssembly سریعتر را ببینید.
مقدمه
Memory Inspector گزینه های اشکال زدایی قوی تری را برای بافرهای حافظه خطی در اختیار شما قرار می دهد. در مورد C/C++، می توانید اشیاء حافظه C/C++ را در حافظه WebAssembly بررسی کنید.
تشخیص بایت های شی شما در میان حافظه WebAssembly اطراف یک نقطه دردناک بود. شما باید اندازه شی را بدانید و بایت ها را از شروع شی بشمارید. در تصویر زیر، اولین بایت از یک آرایه 10 عنصری int32
انتخاب شده است، اما بلافاصله مشخص نیست که کدام بایت های دیگر به آرایه تعلق دارند. آیا خوب نیست اگر بتوانید فوراً تمام بایت های متعلق به شی را تشخیص دهید؟
برجسته کردن شی در Memory Inspector
با شروع از Chrome 107، Memory Inspector تمام بایت های یک شی حافظه C/C++ را برجسته می کند. این به شما کمک می کند تا آنها را از حافظه اطراف جدا کنید.
برای مشاهده عملکرد Memory Inspector ویدیوی زیر را تماشا کنید. همانطور که آرایه x
در Memory Inspector آشکار می کنید، حافظه هایلایت شده در Memory Viewer به همراه یک تراشه جدید درست بالای آن ظاهر می شود. این تراشه نام و نوع حافظه هایلایت شده را به شما یادآوری می کند. روی تراشه کلیک کنید تا به حافظه شیء بروید. اگر ماوس را روی تراشه نگه دارید، یک نماد متقاطع ظاهر می شود - روی آن کلیک کنید تا هایلایت حذف شود.
وقتی بایتی را خارج از شی ای که بررسی می کنید انتخاب می کنید، هایلایت از فوکوس خارج می شود تا حواس شما را پرت نکند. برای فوکوس مجدد آن، دوباره روی هر یک از بایت های شی یا تراشه کلیک کنید.
پشتیبانی از برجسته کردن شیء به آرایه ها محدود نمی شود. همچنین می توانید ساختارها، اشیاء و اشاره گرها را بررسی کنید. این تغییرات کاوش در حافظه برنامه های C/C++ شما را آسان تر از همیشه می کند!
می خواهید آن را امتحان کنید؟ شما نیاز خواهید داشت:
- Chrome 107 یا جدیدتر داشته باشید.
- پسوند C/C++ DWARF را نصب کنید.
- فعال کردن اشکال زدایی DWARF در DevTools > تنظیمات > آزمایشها > اشکالزدایی WebAssemble: پشتیبانی از DWARF را فعال کنید .
- این صفحه نمایشی را باز کنید.
- دستورالعمل های موجود در صفحه را دنبال کنید.
نمونه اشکال زدایی
در این بخش، اجازه دهید نگاهی به یک اشکال اسباببازی بیاندازیم تا نشان دهیم چگونه میتوانید از Memory Inspector برای اشکالزدایی C/C++ استفاده کنید. در نمونه کد زیر، یک برنامه نویس یک آرایه عدد صحیح ایجاد می کند و تصمیم می گیرد از محاسبات اشاره گر برای انتخاب آخرین عنصر استفاده کند. متأسفانه برنامه نویس در محاسبه نشانگر خود اشتباه کرد و اکنون به جای چاپ عنصر آخر، برنامه مقادیر بی معنی را چاپ می کند.
#include <iostream>
int main()
{
int numbers[] = {1, 2, 3, 4};
int *ptr = numbers;
int arraySize = sizeof(numbers)/sizeof(int);
int* lastNumber = ptr + arraySize; // Can you notice the bug here?
std::cout <<../ *lastNumber <<../ '\n';
return 0;
}
برنامه نویس برای رفع اشکال به Memory Inspector مراجعه می کند. شما می توانید همراه با این نسخه ی نمایشی دنبال کنید! آنها ابتدا آرایه را در Memory Inspector بررسی می کنند و می بینند که آرایه numbers
فقط شامل اعداد صحیح 1
، 2
، 3
و 4
است، همانطور که انتظار می رود.
سپس، متغیر lastNumber
از پنجره Scope آشکار می کنند و متوجه می شوند که اشاره گر به یک عدد صحیح خارج از آرایه اشاره می کند! با تجهیز به این دانش، برنامه نویس متوجه می شود که در خط 8 به اشتباه محاسبه شده است. باید ptr + arraySize - 1
باشد.
اگرچه این یک نمونه اسباب بازی است، اما نشان می دهد که چگونه برجسته کردن شی به طور موثر اندازه و موقعیت اشیاء حافظه را منتقل می کند، که می تواند به شما در درک بهتر آنچه در حافظه برنامه C/C++ شما اتفاق می افتد کمک کند.
چگونه DevTools تشخیص می دهد که چه چیزی را برجسته کند
در این بخش، اکوسیستم ابزارهایی را بررسی خواهیم کرد که اشکال زدایی C/C++ را فعال می کنند. به طور خاص، خواهید آموخت که چگونه DevTools، V8، C/C++ DWARF Extension، و Emscripten اشکالزدایی C/C++ را در کروم ممکن میسازند.
برای باز کردن قدرت کامل اشکال زدایی C/C++ در DevTools، به دو چیز نیاز دارید:
- پسوند C/C++ DWARF نصب شده در کروم
- فایلهای منبع C/C++ با آخرین کامپایلر Emscripten در WebAssembly کامپایل شدهاند که در این پست وبلاگ آموزش داده شده است.
اما چرا؟ V8 ، موتور جاوا اسکریپت و WebAssembly کروم، نمی داند چگونه C یا C++ را اجرا کند. به لطف Emscripten ، یک کامپایلر C/C++ به WebAssembly، می توانید برنامه های ساخته شده در C یا C++ را به عنوان WebAssembly کامپایل کرده و در مرورگر اجرا کنید!
در طول کامپایل، emscripten داده های اشکال زدایی DWARF را در باینری شما جاسازی می کند. در سطح بالایی، این داده ها به برنامه افزودنی کمک می کند تا بفهمد کدام متغیر WebAssembly با متغیرهای C/C++ شما و غیره مطابقت دارد. به این ترتیب، DevTools میتواند متغیرهای C++ شما را با وجود اجرای واقعی WebAssembly V8 به شما نشان دهد. اگر کنجکاو هستید، این پست وبلاگ را برای نمونه ای از داده های اشکال زدایی DWARF بررسی کنید .
پس وقتی lastNumber
فاش میکنید واقعاً چه اتفاقی میافتد؟ به محض کلیک بر روی نماد حافظه، DevTools بررسی می کند که کدام متغیر را می خواهید بررسی کنید. سپس برنامه افزودنی را در مورد نوع داده و مکان lastNumber
پرس و جو می کند. به محض اینکه برنامه افزودنی با آن اطلاعات پاسخ داد، Memory Inspector می تواند برش مربوطه از حافظه را نمایش دهد و با دانستن نوع آن، همچنین می تواند اندازه شی را به شما نشان دهد.
اگر به lastNumber
در مثال قبلی نگاه کنید، ممکن است متوجه شوید که ما lastNumber: int *
بررسی کردیم، اما تراشه در Memory Inspector می گوید *lastNumber: int
، چه چیزی را می دهد؟ بازرس برای نشان دادن نوع شی که به شما نشان داده شده است از اشاره گر به سبک C++ استفاده می کند! اگر یک اشاره گر را بررسی کنید، بازرس به شما نشان می دهد که به چه چیزی اشاره می کند.
هایلایت های ماندگار در مراحل دیباگر
وقتی یک شی را در Memory Inspector نشان میدهید و با دیباگر قدم میگذارید، Inspector اگر فکر میکند هنوز قابل اجراست، برجستهسازی را ادامه میدهد. در ابتدا، ما این ویژگی را در نقشه راه خود نداشتیم، اما به سرعت متوجه شدیم که این تجربه اشکال زدایی شما را به خطر می اندازد. تصور کنید که پس از هر مرحله مانند ویدیوی زیر باید آرایه را دوباره بررسی کنید!
هنگامی که دیباگر به نقطه شکست جدید می رسد، بازرس حافظه دوباره V8 و پسوند متغیر مرتبط با برجسته قبلی را درخواست می کند. سپس مکان ها و انواع اشیاء را با هم مقایسه می کند. اگر مطابقت داشته باشند، برجسته باقی می ماند. در ویدیوی بالا، یک حلقه برای نوشتن روی آرایه x
وجود دارد. این عملیات نوع یا موقعیت آرایه را تغییر نمی دهد، بنابراین برجسته می ماند.
ممکن است تعجب کنید که این چگونه بر نشانگرها تأثیر می گذارد. اگر یک نشانگر برجسته داشته باشید و دوباره آن را به یک شی دیگر اختصاص دهید، موقعیت های قدیمی و جدید اشیاء برجسته شده متفاوت است و برجسته ناپدید می شود. از آنجایی که شی تازه اشاره شده می تواند در هر جایی از حافظه WebAssembly زندگی کند و احتمالاً ارتباط کمی با مکان قبلی حافظه خواهد داشت، حذف برجسته تر از پرش به یک مکان حافظه جدید است. میتوانید با کلیک کردن روی نماد حافظه آن در قسمت Scope دوباره نشانگر را برجسته کنید.
نتیجه گیری
این مقاله پیشرفت های ما را در Memory Inspector برای اشکال زدایی C/C++ توضیح داد. امیدواریم ویژگی های جدید اشکال زدایی حافظه برنامه های C/C++ شما را ساده کند! اگر پیشنهادی برای بهبود بیشتر آن دارید، با ثبت یک اشکال به ما اطلاع دهید!
بعدش چی
برای کسب اطلاعات بیشتر، نگاه کنید به: