
استخدم Prolog لتحليل تفريغات الذاكرة والعمليات الحية المتوقفة في WinDbg.
امتداد WinDbg أصلي لـ x64 وARM64 مع عامل SWI-Prolog دائم. يعرض الخيوط وإطارات المكدس والرموز والوحدات المحمّلة والذاكرة من تفريغ وضع المستخدم أو من عملية أصلية متوقفة x64 أو ARM64. حمّل ملفات Prolog الخاصة بك ونفّذ الاستعلامات من نافذة أوامر المصحّح.
الإصدار: 0.2.0 (تجريبي؛ دعم أصلي لـ ARM64).
استخدم ملف DLL المبني لمعمارية المصحّح الخاص بك. يجب أن يتطابق المصحّح وملف DLL
والهدف الأصلي: x64/AMD64 معًا أو ARM64 معًا. سياقات النطاق عبر المعماريات،
وWOW64، وARM32، وأهداف ARM64EC خارج نطاق هذا الإصدار.
اجتازت بنيات x64 وARM64 الأصلية جميع الفحوصات المحمولة البالغ عددها 99 واختبارات
الدخان لتفريغ CDB والتشغيل المباشر. راجع docs/VALIDATION.md للاطلاع على التشغيل والسجلات والفحوصات اليدوية المتبقية.
لا يحتوي مستودع المصدر على ملفات ثنائية مُجمّعة. ابنِه باستخدام
تعليمات Windows أدناه لتعبئة dist/x64/ أو dist/arm64/. تُسمّى أرشيفات
الإصدار PrologWinDbg-v0.2.0-win-x64.zip و
PrologWinDbg-v0.2.0-win-arm64.zip؛ ويضع كل منهما ملفاته الثنائية المختارة في dist/.
تستخدم الأمثلة أدناه تخطيط أرشيف الإصدار هذا. بالنسبة لبناء من المصدر،
استبدل dist/arm64 أو dist/x64 في المسارات.
ثبّت نسخة وحدة التحكم في Windows من SWI-Prolog. تتوفر مثبّتات ARM64 الأصلية من تنزيلات التطوير. تستخدم مصفوفة CI إصدار SWI-Prolog 10.1.18-1 الأصلي على كلتا المعماريتين. يعمل SWI كعملية منفصلة؛ وهو غير مرتبط بملف DLL ولا مضمّن معه.
احتفظ بـ dist/prolog.dll معًا
مع الدليلين dist/prolog وdist/examples.
افتح تفريغًا أصليًا لوضع المستخدم في WinDbg المطابق x64 أو ARM64، أو أرفق بعملية أصلية من تلك المعمارية وادخل إليها. للحصول على تفريغ قابل للتكرار، نفّذ هذا في PowerShell:
.\dist\prologdbg_target.exe --dump C:\Temp\prologdbg-sample.dmp
في WinDbg، استبدل هذه المسارات بمسار مشروعك الفعلي. استخدم الشرطة المائلة للأمام في المسارات المُقتبسة: إذ يعامل المُنقِّح الشرطة المائلة للخلف كرموز هروب.
.load C:/PrologWinDbg/dist/prolog.dll
!prolog.runtime "C:/Program Files/swipl/bin/swipl.exe"
!prolog.info
!prolog.consult "C:/PrologWinDbg/dist/examples/patterns.pl"
!prolog.query wd:current_snapshot(S), wd:architecture(S,Architecture).
!prolog.query wd:current_snapshot(S), wd:thread_id(S,T,WindowsTid).
!prolog.query wd:current_snapshot(S), wd:stack_frame(S,T,Depth,IP).
!prolog.query wd:current_snapshot(S), patterns:stack_contains(S,T,Module,Function).
يستخدم الامتداد مسار وقت التشغيل الصريح، أو متغير البيئة PROLOGDBG_SWIPL، أو التثبيت القياسي Program Files\swipl\bin\swipl.exe.
يبدأ العامل عند الحاجة إليه لأول مرة. تتم جميع الاتصالات عبر أنابيب محلية.
بالنسبة للهدف المقدم، افحص العلامة المعروفة المكوّنة من ثمانية بايتات:
!prolog.query wd:current_snapshot(S), wd:lookup(S,'prologdbg_target!g_magic',ok(A)), patterns:inspect_magic(S,A,Verdict).
النتيجة المتوقعة: matched(prologdb, Address). بايتات العلامة تُهجّئ
PROLOGDB. يصدّر الهدف هذه الأسماء، لذا لا يتطلب هذا المثال
ملف PDB. ملفات PDB الخاصة مفيدة لدوال وتطبيقات أخرى.
شغّل prologdbg_target.exe --live تحت WinDbg. تابع تجاوز نقطة توقف
المحمّل الأولية. عندها يتوقف الهدف عند CapturePoint بعد بدء خيطَي
عامل. استخدم نفس الاستعلامات المستخدمة مع التفريغ.
بدلاً من ذلك، شغّل prologdbg_target.exe --wait، واربط بالمعرّف PID المطبوع،
وتوقف في التنفيذ. يخرج هذا الوضع بعد عشر دقائق إن لم يُوقف قبل ذلك.
استخدم أوامر WinDbg العادية bp وg وp وt للتحكم في التنفيذ. كل
!prolog.query يجمع لقطة جديدة. إجراءات نقاط توقف Prolog المسجّلة والاستمرار
التلقائي مخطط لها لإصدار لاحق.
| الأمر | الغرض |
|---|---|
!prolog.help | عرض مساعدة الأوامر |
!prolog.runtime "absolute path to swipl.exe" | اختيار وقت التشغيل وإيقاف أي عامل موجود |
!prolog.info | بدء العامل والإبلاغ عن إصداره |
!prolog.consult "absolute path to rules.pl" | تحميل أو إعادة تحميل مصدر Prolog |
!prolog.query Goal. | جمع الأدلة وتعداد الحلول |
!prolog.queryfile "absolute path to goal.txt" | قراءة هدف UTF-8 واحد من ملف، ثم الاستعلام |
!prolog.eval Goal. | تقييم Prolog دون أدلة من المصحّح |
!prolog.limits | عرض الحدود الحالية |
!prolog.limits 5000 100 128 10000000 | تعيين الميلي ثانية وعدد الإجابات والإطارات لكل خيط وحد الاستدلال |
!prolog.reset | إيقاف العامل؛ تُفقد القواعد المحمّلة وحالة وقت التشغيل المخصصة |
تُمرَّر الأهداف البسيطة مباشرة بعد الأمر. علامات الاقتباس المفردة القياسية في Prolog تحدّد الذرّات. يمكنك
حذف النقطة النهائية. استخدم هدفاً واحداً لكل أمر،
مع ربط الأهداف الفرعية بفواصل. بالنسبة للفصل المنطقي في Prolog (;)، ضع الهدف
بالكامل بين علامتي اقتباس مزدوجتين لحمايته من فاصل أوامر WinDbg:
!prolog.eval "(X=a;X=b), writeln(X)."
بالنسبة للاقتباس المعقد، أو النص بترميز Unicode، أو الأهداف متعددة الأسطر، ضع الهدف في ملف نصي بترميز UTF-8 واستخدم !prolog.queryfile "C:/rules/goal.txt". يذهب محتواه مباشرةً إلى Prolog، متجاوزًا تحليل نص الأوامر في WinDbg. حد الملف هو 1 MiB. بالنسبة للمنطق القابل لإعادة الاستخدام، عرّف المسندات (predicates) في ملف .pl يتم استدعاؤه (consulted).
مثال بدون هدف:
!prolog.eval member(X,[1,2,3]), Y is X*X.
تُطبع الإجابات على الشكل bindings([Name=Value, ...], ResidualGoals). تحافظ القائمة الثانية على القيود المتبقية. ويميّز الحالة النهائية بين استنفاد البحث، والفشل، وحدود الإجابات، وحدود الاستدلال، والمهلات الزمنية، والاستثناءات. ولا يعني الوصول إلى حد الإجابات تأكيد وجود المزيد من الحلول.
يُجري استشارة ملفٍ تحميل Prolog العادي وتهيئته. وتُبلَّغ أخطاء التحميل، لكن تحميل Prolog ليس معاملاتيًا: فقد تكون بعض البنود قد حُمِّلت قبل حدوث خطأ. صحّح الملف وأعد تحميله، أو أعد ضبط العامل.
:- module(my_rules, [in_function/4]).
:- use_module('C:/PrologWinDbg/dist/prolog/wd.pl').
in_function(S, T, Module, Function) :-
wd:stack_frame(S, T, _, IP),
wd:symbol(S, IP, Module, Function, _).
ثم:
!prolog.consult "C:/rules/my_rules.pl"
!prolog.query wd:current_snapshot(S), my_rules:in_function(S,T,myapp,'ProcessRequest').
راجع docs/API.md للاطلاع على أوضاع المسندات ودلالات الأدلة. توفّر القواعد الأولية مطابقة المكدس، والدوال المشتركة بين الخيوط، وأدلة المكدس الصريحة، والعناوين غير القابلة للقراءة، وتشخيصًا ببصمة الذاكرة مع نتيجة غير حاسمة.
ميزانية الاستعلام الافتراضية هي 5 ثوانٍ، و100 إجابة، و128 إطارًا لكل خيط، و10 ملايين استدلال. تتلقى عملية جمع اللقطات ميزانية زمنية خاصة بها بالحجم نفسه. قد يكون التحميل الأولي للرموز بطيئًا: قم بتسخين ذاكرة الرموز المؤقتة أو ارفع القيمة الأولى باستخدام !prolog.limits.
طلبات الذاكرة لا تتجاوز 64 KiB لكل طلب و16 MiB إجمالًا لكل استعلام. يقتصر التقاط اللقطات على 4,096 خيطًا، و4,096 وحدة نمطية محمّلة، و8 MiB من نص الحقائق. يستخدم العامل حد مكدس Prolog قدره 512 MiB وحد ذاكرة عملية Windows قدره 768 MiB. كما يحدّ الجسر الأصلي من الإخراج وعدد استدعاءات RPC ووقت انتظار IPC.
استخدم إجراء Break / Ctrl+Break في WinDbg لمقاطعة أمر ما. أثناء الانتظار على العامل أو أثناء المرور على عناصر اللقطة، يتحقق الامتداد من GetInterrupt. يؤدي قطع IPC إلى إعادة تعيين العامل؛ راجع قواعدك مرة أخرى بعد ذلك. تحافظ حدود الوقت/الاستدلال العادية في Prolog على العامل. يمكن استخدام الأمر !prolog.reset بعد عودة الأمر الحالي؛ وهو ليس أمر إلغاء متزامنًا.
استدعاءات DbgEng الفردية، وخاصة تحميل الرموز والقراءات البعيدة، متزامنة. يتحقق الامتداد من الوقت المنقضي والانقطاع بين الاستدعاءات؛ ولا يمكنه ضمان موعد نهائي صارم بينما يكون DbgEng نفسه محظورًا.
فحص الانقطاع اليدوي:
!prolog.limits 600000 100 128 1000000000
!prolog.eval sleep(300).
اضغط Ctrl+Break. تأكد من عودة موجه الأوامر، ثم شغّل !prolog.info و
!prolog.eval X is 2+2.. استعد الحدود الطبيعية بعد ذلك.
ثبّت Visual Studio 2022 (تطوير سطح المكتب باستخدام C++)، وCMake، و
Windows SDK مع Debugging Tools for Windows. بالنسبة لـ ARM64، ثبّت أدوات
بناء Visual Studio C++ ARM64. يلزم SWI-Prolog وPython 3
لتشغيل جميع الاختبارات المحمولة. أضف swipl.exe وpython.exe إلى PATH.
من Visual Studio Developer PowerShell: