| STAP(1) | General Commands Manual | STAP(1) |
نام (NAME)
stap - مترجم و راهانداز اسکریپت systemtap
خلاصه دستور (SYNOPSIS)
stap [ OPTIONS ] FILENAME [ ARGUMENTS
]
stap [ OPTIONS ] - [ ARGUMENTS ]
stap [ OPTIONS ] -e SCRIPT [ ARGUMENTS ]
stap [ OPTIONS ] -l PROBE [ ARGUMENTS ]
stap [ OPTIONS ] -L PROBE [ ARGUMENTS ]
stap [ OPTIONS ] --dump-probe-types
stap [ OPTIONS ] --dump-probe-aliases
stap [ OPTIONS ] --dump-functions
توضیحات (DESCRIPTION)
برنامه stap رابط کاربری اصلی ابزار Systemtap است. این برنامه دستورالعملهای کاوش نوشتهشده به یک زبان دامنه-خاص ساده را دریافت کرده، آنها را به کد C ترجمه میکند، این کد C را کامپایل کرده و ماژول حاصل را در یک هسته لینوکس در حال اجرا یا تغییردهنده فضای کاربری Dyninst بارگذاری میکند تا توابع ردیابی/کاوش درخواستی سیستم را انجام دهد. شما میتوانید اسکریپت را در یک فایل مشخص (FILENAME)، از ورودی استاندارد (استفاده از - بهجای FILENAME)، یا از خط فرمان (با استفاده از -e SCRIPT) ارائه دهید. برنامه تا زمانی اجرا میشود که توسط کاربر متوقف شود، یا اسکریپت به صورت داوطلبانه تابع exit() را فراخوانی کند، یا به تعداد کافی خطای نرم رخ دهد.
این زبان که در بخش زبان اسکریپتنویسی (SCRIPT LANGUAGE) در ادامه شرح داده شده است، دارای نوعبندی قوی، رسا، بدون نیاز به اعلان متغیرها، رویهای، مناسب برای نمونهسازی اولیه، و الهامگرفته از awk و C است. این زبان امکان پیوند دادن نقاطی از کد منبع یا رویدادهای سیستم را با گردانندهها (handlers) فراهم میکند؛ گردانندهها زیرروالهایی هستند که بهصورت همگام اجرا میشوند. این مفهوم تا حدودی شبیه به «فهرست دستورات نقطه توقف» در دیباگر gdb است.
بررسی اجمالی مستندات (DOCUMENTATION OVERVIEW)
ابزار systemtap همراه با انواع منابع آموزشی، مستندات و منابع مرجع عرضه میشود. این منابع بهصورت آنلاین و/یا در قالب بستههایی برای استفاده آفلاین در دسترس هستند. برخی از پیامهای هشدار/خطای تشخیصی systemtap با گنجاندن رشتهای مانند [man error::pass5] صریحاً مطالعه یک صفحه راهنما را پیشنهاد میکنند. برای دسترسی به مستندات آنلاین، وبسایت پروژه را ببینید: https://sourceware.org/systemtap
| صفحات راهنما (man pages) | |
| stap (این صفحه) | نحو زبان، مفاهیم، عملیات، گزینهها |
| error::* | توضیحات تکمیلی درباره شرایط خطا |
| warning::* | توضیحات تکمیلی درباره شرایط هشدار |
| stapprobes | نقاط کاوش و متغیرهای زمینه $context آنها |
| stapref | مرجع سریع نحو زبان |
| stappaths | فهرست دایرکتوریها، شامل کتابها و مراجع |
| stap-prep | برنامه نصب وابستگیهای کمکی مانند debuginfo هسته |
| tapset::* | فهرست تولیدشده تپستها |
| probe::* | فهرست تولیدشده نامهای مستعار کاوشگر تپست |
| function::* | فهرست تولیدشده توابع تپست |
| macro::* | فهرست تولیدشده ماکروهای تپست |
| stapvars | برخی از متغیرهای سراسری تپست |
| staprun, stapdyn, stapbpf | برنامههای اجرای اسکریپتهای کامپایلشده systemtap |
| systemtap | اسکریپت مقداردهی اولیه (initscript)، کاوش در زمان بوت |
| stap-server | سرور کامپایل |
| stapex | چند مثال اسکریپتی بسیار پایه |
| کتابها (books) | |
| راهنمای مبتدیان (Beginner's Guide) | کتاب آموزشی، مبانی زبان، مثالها |
| آموزش (Tutorial) | آموزش کوتاهتر، تمرینها |
| مرجع زبان (Language Reference) | دفترچه راهنمای تفصیلی زبان، پوششدهنده آمار/تحلیل |
| مرجع تپست (Tapset Reference) | صفحات راهنمای تپست که در قالب یک کتاب بازآرایی شدهاند |
| مراجع (references) | |
| اسکریپتهای نمونه | بیش از صد ابزار مستقیماً قابل استفاده برای مدیران سیستم، ابزارهای کوچک و ترفندهایی برای یادگیری |
گزینهها (OPTIONS)
مترجم systemtap از گزینههای زیر پشتیبانی میکند. هر گزینه دیگری فهرستی از گزینههای پشتیبانیشده را چاپ میکند. گزینهها معمولاً در خط فرمان مشخص میشوند. اگر فایل $SYSTEMTAP_DIR/rc وجود داشته باشد، گزینهها از آنجا نیز بارگذاری شده و ابتدا تفسیر میشوند. (در صورت عدم تعیین، مقدار پیشفرض $SYSTEMTAP_DIR برابر با $HOME/.systemtap خواهد بود.)
در برخی موارد، مقدار پیشفرض یک گزینه به پیکربندی سیستم خاص بستگی دارد و بنابراین نمیتوان مستقیماً در اینجا ذکر کرد. در برخی از این موارد اجرای «stap --help» ممکن است مقدار پیشفرض را نمایش دهد.
- -
- استفاده از ورودی استاندارد بهجای FILENAME مشخصشده به عنوان ورودی زبان کاوش، مگر اینکه -e SCRIPT ارائه شده باشد.
- -h --help
- نمایش پیام راهنما.
- -V --version
- نمایش پیام نسخه.
- -p NUM
- توقف پس از گذر (pass) شماره NUM. گذرها از ۱ تا ۵ شمارهگذاری شدهاند: تجزیه (parse)، بسط (elaborate)، ترجمه (translate)، کامپایل (compile)، اجرا (run). برای جزئیات بخش پردازش (PROCESSING) را ببینید.
- -v
- افزایش سطح پرگویی برای همه گذرها. با هر بار تکرار گزینه، خروجیهای اطلاعاتی بیشتری تولید میشود.
- --vp ABCDE
- افزایش سطح پرگویی بر مبنای هر گذر. به عنوان مثال، «--vp 002» ۲ واحد پرگویی تنها به گذر ۳ اضافه میکند. ترکیب «-v --vp 00004» ۱ واحد پرگویی برای همه گذرها و ۴ واحد اضافی برای گذر ۵ اضافه میکند.
- -k
- نگهداشتن دایرکتوری موقت پس از اتمام تمامی پردازشها. این کار ممکن است جهت بررسی کد C تولیدشده یا استفاده مجدد از شیء کامپایلشده هسته مفید باشد.
- -g
- حالت گورو (Guru). فعالسازی تجزیه ساختارهای ناامن در سطح متخصص مانند کد C جاسازیشده.
- -P
- حالت جستجوی مقدمه (Prologue-searching). این گزینه معادل --prologue-searching=always است. فعالسازی روشهای اکتشافی جهت دور زدن اطلاعات اشکالزدایی نادرست برای متغیرهای زمینه $context پارامتر تابع.
- -u
- حالت بهینهسازینشده. غیرفعال کردن حذف کدهای بلااستفاده و بسیاری از بهینهسازیهای دیگر در طول بسط / ترجمه.
- -w
- حالت سرکوب هشدارها. تمام پیامهای هشدار را غیرفعال میکند.
- -W
- در نظر گرفتن تمامی هشدارها به عنوان خطا.
- -b
- استفاده از حالت فلهای (bulk mode، فایلهای percpu اختصاصی هر پردازنده) برای انتقال داده از هسته به فضای کاربری. برای ترکیب مجدد آنها در آینده از برنامه stap-merge استفاده کنید.
- -i --interactive
- حالت تعاملی. رابطی را جهت ساخت گامبهگام و تعاملی اسکریپت systemtap فعال میکند.
- -t
- جمعآوری اطلاعات زمانبندی درباره تعداد دفعات اجرای کاوشگر و میانگین زمان صرفشده در هر نقطه کاوش. همچنین مشتقگیری (derivation) را برای هر نقطه کاوش نمایش میدهد.
- -s NUM
- استفاده از بافرهای NUM مگابایتی برای انتقال دادهها از هسته به فضای کاربری به ازای هر پردازنده. مقدار پیشفرض ۱۶ مگابایت است، یا در سیستمهایی با حافظه کمتر، مقداری کمتر خواهد بود.
- -I DIR
- افزودن دایرکتوری دادهشده به دایرکتوری جستجوی تپست (tapset). برای جزئیات، شرح گذر ۲ را ببینید.
- -D NAME=VALUE
- افزودن دستورالعمل پیشپردازنده C به Makefile ماژول. این موارد را میتوان برای لغو پارامترهای محدودیت شرح داده شده در ادامه استفاده کرد.
- -B NAME=VALUE
- در حالت زمان اجرای هسته (kernel-runtime)، افزودن دستورالعمل make دادهشده به فراخوانی make برای ساخت ماژول هسته. از این موارد میتوان برای افزودن یا لغو گزینههای kconfig استفاده کرد. به عنوان مثال، از
-B CONFIG_DEBUG_INFO=y
برای افزودن اطلاعات اشکالزدایی استفاده کنید.
- -B FLAG
- در حالت زمان اجرای dyninst، افزودن پارامتر دادهشده به CFLAGS کامپایلر که برای ساخت کتابخانه مشترک dyninst استفاده میشود. به عنوان مثال، از
-B -g
برای افزودن اطلاعات اشکالزدایی استفاده کنید.
- -a ARCH
- استفاده از حالت کامپایل چندسکویی (cross-compilation) برای معماری هدف دادهشده. این مورد نیازمند دسترسی به کامپایلر چندسکویی و درخت ساخت هسته است و همراه با گزینههای
-B CROSS_COMPILE=arch-tool-prefix- و -r /build/tree
به کار میرود.
- --modinfo NAME=VALUE
- افزودن جفت نام/مقدار به عنوان فراخوانی ماکروی MODULE_INFO به ماژول تولیدشده. این کار ممکن است برای اطلاعرسانی یا لغو بررسیهای مختلف مرتبط با ماژول در هسته مفید باشد.
- -G NAME=VALUE
- هنگام فراخوانی staprun، مقدار متغیر سراسری NAME را به VALUE تنظیم میکند. این مورد برای متغیرهای اسکالر اعلانشده بهصورت سراسری در اسکریپت/تپست اعمال میشود.
- -R DIR
- جستجوی منابع زمان اجرای systemtap در دایرکتوری مشخصشده. مقدار پیشفرض DIR را میتوان با استفاده از «stap --help» مشاهده کرد.
- -r /DIR
- ساخت برای هسته در درخت ساخت مشخصشده. همچنین میتواند با متغیر محیطی SYSTEMTAP_RELEASE تنظیم شود.
- -r RELEASE
- ساخت برای هسته در درخت ساخت /lib/modules/RELEASE/build. همچنین میتواند با متغیر محیطی SYSTEMTAP_RELEASE تنظیم شود.
- -m MODULE
- استفاده از نام دادهشده برای ماژول شیء هسته تولیدشده، بهجای یک نام تصادفی منحصربهفرد. ماژول شیء هسته تولیدشده در دایرکتوری جاری کپی میشود.
- -d MODULE
- افزودن اطلاعات نماد/بازگشت پشته (symbol/unwind) برای ماژول دادهشده به ماژول شیء هسته. این کار ممکن است امکان ردیابی نمادین را از آن ماژولها/برنامهها فراهم کند، حتی اگر کاوشگر صریحی درون آنها قرار داده نشده باشد.
- --ldd
- افزودن اطلاعات نماد/بازگشت پشته برای تمام کتابخانههای مشترک فضای کاربری که توسط ldd تشخیص داده شده برای باینریهای فضای کاربری کاوششده یا فهرستشده با گزینه -d ضروری هستند. هشدار: این کار میتواند حجم ماژولهای کاوشگر را به میزان قابل توجهی افزایش دهد. توجه داشته باشید که این گزینه با ماژولهای فضای هسته سروکار ندارد؛ در عوض به --all-modules در ادامه مراجعه کنید.
- --all-modules
- معادل مشخص کردن «-dkernel» و یک «-d» برای هر ماژول هستهای که در حال حاضر بارگذاری شده است. هشدار: این کار میتواند حجم ماژولهای کاوشگر را به میزان قابل توجهی افزایش دهد.
- -o FILE
- ارسال خروجی استاندارد به فایل مشخصشده. در حالت فلهای (bulk mode)، فایلهای percpu با FILE_ (یا با -F با FILE_cpu) و به دنبال آن شماره پردازنده آغاز میشوند. این گزینه از قالبهای strftime(3) برای FILE پشتیبانی میکند.
- -c CMD
- شروع کاوشگرها، اجرای CMD، و خروج هنگام پایان CMD. این کار همچنین تأثیر تنظیم target() روی pid آن فرایند را دارد. توجه داشته باشید که بسیاری از انواع کاوشگرها مستقل از این تنظیم فعال میشوند. برای تمرکز روی اسکریپت خود، اضافه کردن چیزی شبیه به این را در نظر بگیرید:
probe FOO { if (pid() != target()) next; .... }
- -x PID
- تنظیم target() روی PID. اسکریپت مستقل از چرخه حیات PID اجرا میشود.
- -e SCRIPT
- اجرای SCRIPT مشخصشده در خط فرمان.
- -E SCRIPT
- اجرای SCRIPT مشخصشده. این SCRIPT علاوه بر اسکریپت اصلی مشخصشده، از طریق -e یا به عنوان یک فایل اسکریپت اجرا میشود. این گزینه را میتوان برای اجرای چندین اسکریپت تکرار کرد، و میتوان از آن در حالت فهرستبندی (-l/-L) استفاده کرد.
- -l PROBE
- بهجای اجرای یک اسکریپت کاوش، صرفاً تمامی نقاط کاوش موجود منطبق با نقطه کاوش تکی دادهشده را فهرست میکند. الگو ممکن است شامل حروف عام (wildcards) و نامهای مستعار باشد، اما نه چند نقطه کاوش جداشده با کاما. در صورتی که تطابقی وجود نداشته باشد، کد وضعیت فرآیند نشاندهنده شکست خواهد بود.
% stap -e 'probe syscall.* { }'
[...]
% stap -l 'syscall.*'
syscall.accept
[...]
syscall.writev
- -L PROBE
- مشابه «-l»، اما نقاط کاوش منطبق بههمراه متغیرهای زمینه موجود آنها را فهرست میکند. وقتی -v همراه با -L تنظیم شود، خروجی شامل نقاط کاوش تکراری است که بر اساس آدرس شمارنده برنامه (PC) خود متمایز میشوند.
% stap -L 'process("/lib64/libpython*.so.*").mark("*")'
process("/usr/lib64/libpython2.7.so.1.0").mark("function__entry") $arg1:long $arg2:long $arg3:long
process("/usr/lib64/libpython2.7.so.1.0").mark("function__return") $arg1:long $arg2:long $arg3:long
process("/usr/lib64/libpython3.6m.so.1.0").mark("function__entry") $arg1:long $arg2:long $arg3:long
process("/usr/lib64/libpython3.6m.so.1.0").mark("function__return") $arg1:long $arg2:long $arg3:long
process("/usr/lib64/libpython3.6m.so.1.0").mark("gc__done") $arg1:long
process("/usr/lib64/libpython3.6m.so.1.0").mark("gc__start") $arg1:long
process("/usr/lib64/libpython3.6m.so.1.0").mark("line") $arg1:long $arg2:long $arg3:long
- -F
- بدون گزینه -o، ماژول را بارگذاری کرده و کاوشگرها را شروع میکند، سپس از ماژول جدا میشود و اجازه میدهد کاوشگرها در حال اجرا باقی بمانند. با گزینه -o، دستور staprun را در پسزمینه به عنوان یک دیمون اجرا کرده و pid آن را نمایش میدهد.
- -S size[,N]
- حداکثر اندازه فایل خروجی و حداکثر تعداد فایلهای خروجی را تنظیم میکند. اگر اندازه فایل خروجی از size مگابایت تجاوز کند، systemtap فایل خروجی را به فایل بعدی تغییر میدهد. و اگر تعداد فایلهای خروجی از N بیشتر شود، systemtap قدیمیترین فایل خروجی را حذف میکند. میتوانید آرگومان دوم را حذف کنید.
- -T TIMEOUT
- خروج از اسکریپت پس از TIMEOUT ثانیه.
- --skip-badvars
- نادیده گرفتن متغیرهای زمینهای که قابل حل نیستند یا در زمان اجرا در دسترس نیستند و جایگزینی آنها با 0، بدون ایجاد خطا.
- --prologue-searching[=WHEN]
- حالت جستجوی مقدمه. فعالسازی روشهای اکتشافی برای دور زدن اطلاعات اشکالزدایی نادرست برای متغیرهای زمینه $context پارامتر تابع. مقدار WHEN میتواند یکی از «never»، «always» یا «auto» (یعنی فعال بر اساس اکتشاف) باشد. اگر WHEN ذکر نشود، «always» فرض میشود. اگر گزینه ذکر نشود، «auto» فرض میشود.
- --suppress-handler-errors
- محصور کردن تمامی گردانندههای کاوش در بلوکی شبیه به این:
try { ... } catch { next }
که باعث میشود هرگونه خطای زمان اجرا بدون صدا نادیده گرفته شود. خطاهای نادیدهگرفتهشده در محدودیتهای MAXERRORS شمارش نمیشوند. در این حالت، محدودیتهای MAXSKIPPED نیز نادیده گرفته میشوند، بهطوری که خطاهای بسیار و کاوشهای ردشده متعددی ممکن است در طول اجرای اسکریپت جمع شوند. هرگونه شمارش کلی همچنان در هنگام خاموش شدن گزارش خواهد شد.
- --compatible VERSION
- سرکوب تغییرات اخیر زبان اسکریپت یا تپست که با نسخه قدیمیتر مشخصشده systemtap ناسازگار هستند. این کار ممکن است در صورتی مفید باشد که یک اسکریپت بسیار قدیمیتر systemtap در اجرا با شکست مواجه شود. برای جزئیات بیشتر به بخش «منسوخشدگی (DEPRECATION)» مراجعه کنید.
- --check-version
- این گزینه برای بررسی این است که آیا اسکریپت فعال دارای ساختارهایی است که ممکن است مختص نسخه خاصی از systemtap باشند یا خیر. برای جزئیات بیشتر به بخش «منسوخشدگی (DEPRECATION)» مراجعه کنید.
- --clean-cache
- این گزینه ورودیهای کهنه را از دایرکتوری حافظه موقت (cache) پاکسازی میکند. این کار معمولاً پس از اجراهای موفقیتآمیز به طور خودکار انجام میشود، اما این گزینه پاکسازی را به صورت دستی فعال کرده و سپس خارج میشود. برای جزئیات بیشتر درباره محدودیتهای حافظه موقت به بخش «حافظه موقت (CACHING)» مراجعه کنید.
- --color[=WHEN], --colour[=WHEN]
- این گزینه
رنگآمیزی
پیامهای
خطا را
کنترل
میکند.
مقدار WHEN
میتواند
یکی از «never»،
«always» یا «auto»
(یعنی فعال
فقط در صورت
اتصال به
ترمینال)
باشد. اگر WHEN
ذکر نشود،
«always» فرض
میشود. اگر
گزینه ذکر
نشود، «auto»
فرض میشود.
رنگها را میتوان با استفاده از متغیر محیطی SYSTEMTAP_COLORS اصلاح کرد. قالب باید به شکل زیر باشد: key1=val1:key2=val2:key3=val3 ...etc. کلیدهای معتبر عبارتند از: "error", "warning", "source", "caret", and "token". مقادیر، پارامتر(های) Select Graphic Rendition (SGR) را تشکیل میدهند. برای SGRهایی که ترمینال شما پشتیبانی میکند به مستندات آن مراجعه کنید. به عنوان مثال، رنگهای پیشفرض به این صورت بیان میشوند: error=01;31:warning=00;33:source=00;34:caret=01:token=01. اگر SYSTEMTAP_COLORS وجود نداشته باشد، رنگهای پیشفرض استفاده خواهند شد. اگر خالی یا نامعتبر باشد، رنگآمیزی خاموش میشود.
- --disable-cache
- این گزینه هرگونه استفاده از دایرکتوری حافظه موقت را غیرفعال میکند. هیچ فایلی از حافظه موقت خوانده یا در آن نوشته نخواهد شد.
- --poison-cache
- این گزینه با فایلهای موجود در دایرکتوری حافظه موقت به عنوان فایلهای نامعتبر رفتار میکند. هیچ فایلی از حافظه موقت خوانده نمیشود، اما فایلهای حاصل از این اجرا همچنان در حافظه موقت نوشته خواهند شد. این گزینه به عنوان یک ابزار عیبیابی در زمانی که رفتار کش stap نادرست به نظر میرسد در نظر گرفته شده است. اگر این کار کمکی کرد، احتمالاً اشکالی در systemtap وجود دارد که توسعهدهندگان مایلند آن را گزارش کنید.
- --privilege[=stapusr | =stapsys | =stapdev]
- این گزینه
به stap دستور
میدهد تا
اسکریپت را
برای یافتن
ساختارهایی
که برای سطح
دسترسی
مشخصشده
مجاز
نیستند
بررسی کند
(بخش
کاربران
غیرممتاز
(UNPRIVILEGED USERS) را
ببینید).
اگر چنین
ساختارهایی
استفاده
شوند،
کامپایل با
شکست مواجه
میشود. اگر
stapusr یا stapsys
هنگام
استفاده از
سرور
کامپایل
(گزینه --use-server
را ببینید)
مشخص شوند،
سرور
اسکریپت را
بررسی کرده
و در صورت
موفقیتآمیز
بودن
کامپایل،
سرور ماژول
هسته حاصل
را به صورت
رمزنگاریشده
امضا
میکند و
تأیید
میکند که
استفاده از
آن برای
کاربران در
سطح دسترسی
مشخصشده
ایمن است.
اگر --privilege مشخص نشده باشد، -pN با N < 5 مشخص نشده باشد، و کاربر فراخواننده root نباشد و عضو گروه stapdev نباشد، آنگاه stap به طور خودکار گزینه مناسب --privilege را به گزینههایی که قبلاً مشخص شدهاند اضافه میکند.
- --unprivileged
- این گزینه معادل --privilege=stapusr است.
- --use-server[=HOSTNAME[:PORT] | =IP_ADDRESS[:PORT] | =CERT_SERIAL]
- مشخص کردن
سرور(های)
کامپایل
جهت
استفاده
برای
کامپایل
و/یا در
ترکیب با
--list-servers و --trust-servers (در
ادامه) برای
فهرستبندی.
اگر هیچ
آرگومانی
ارائه
نشود،
مقدار
پیشفرض در
حالت
غیرممتاز
(به --privilege
مراجعه
کنید)
انتخاب
سرورهای
سازگار است
که به عنوان
همتایان SSL و
امضاکنندگان
ماژول مورد
اعتماد
بوده و در
حال حاضر
آنلاین
هستند. در
غیر این
صورت،
مقدار
پیشفرض
انتخاب
سرورهای
سازگار است
که به عنوان
همتایان SSL
مورد
اعتماد
بوده و
آنلاین
هستند.
گزینه --use-server
را میتوان
بیش از یک
بار مشخص
کرد که در
این حالت
فهرستی از
سرورها به
ترتیب
مشخصشده
جمعآوری
میشود.
سرورها را
میتوان با
نام
میزبان،
آدرس IP یا
شماره
سریال
گواهی (به
دست آمده با
استفاده از
--list-servers) مشخص
کرد. مورد
اخیر
معمولاً
هنگام اعطا
یا لغو
اعتماد به
یک سرور
استفاده
میشود (به
--trust-servers در
ادامه
مراجعه
کنید). اگر
سروری با
نام میزبان
یا آدرس IP
مشخص شده
باشد،
میتوان یک
شماره پورت
اختیاری را
نیز تعیین
کرد. این
برای
دسترسی به
سرورهایی
که در شبکه
محلی
نیستند یا
برای تعیین
یک سرور خاص
مفید است.
آدرسهای IP میتوانند آدرسهای IPv4 یا IPv6 باشند.
اگر یک آدرس IPv6 مشخص از نوع پیوند-محلی (link local) باشد و روی بیش از یک رابط وجود داشته باشد، رابط مورد نظر را میتوان با افزودن علامت درصد (%) و به دنبال آن نام رابط مورد نظر به انتهای آدرس مشخص کرد؛ برای مثال «fe80::5eff:35ff:fe07:55ca%eth0».
به منظور تعیین شماره پورت همراه با آدرس IPv6، لازم است آدرس IPv6 را در قلابهای مربع ([]) قرار داد تا شماره پورت از بقیه آدرس جدا شود؛ برای مثال «[fe80::5eff:35ff:fe07:55ca]:5000» یا «[fe80::5eff:35ff:fe07:55ca%eth0]:5000».
اگر --use-server مشخص نشده باشد، -pN با N < 5 مشخص نشده باشد، و کاربر فراخواننده root نبوده و عضو گروه stapdev نباشد، اما عضو گروه stapusr باشد، آنگاه stap به طور خودکار --use-server را به گزینههایی که قبلاً مشخص شدهاند اضافه میکند.
- --use-server-on-error[=yes|=no]
- به stap دستور میدهد در صورتی که کامپایل در میزبان محلی به نحوی با شکست مواجه شود که نشان دهد ممکن است با استفاده از سرور موفق شود، کامپایل اسکریپت را با استفاده از یک سرور کامپایل مجدداً امتحان کند. اگر این گزینه مشخص نشود، پیشفرض no است. اگر هیچ آرگومانی ارائه نشود، پیشفرض yes است. کامپایل مجدد برای انواع خاصی از خطاها (مانند کمبود داده یا منابع) که ممکن است در طول کامپایل مجدد توسط سرور رخ ندهند، تلاش مجدد خواهد شد. سرورهای کامپایل به طور خودکار برای تلاش کامپایل مجدد انتخاب میشوند، گویی --use-server بدون آرگومان مشخص شده باشد.
- --list-servers[=SERVERS]
- نمایش وضعیت SERVERS درخواستی، که در آن SERVERS فهرستی از ویژگیهای سرور است که با کاما جدا شدهاند. فهرست ویژگیها برای فیلتر کردن فهرست سرورهای نمایشی ترکیب میشود. ویژگیهای پشتیبانیشده عبارتند از:
- all
- تمام سرورهای شناختهشده را مشخص میکند (همتایان معتمد SSL، امضاکنندگان معتمد ماژول، سرورهای آنلاین).
- specified
- سرورهای مشخصشده با استفاده از --use-server را تعیین میکند.
- online
- خروجی را با حفظ اطلاعات سرورهایی که در حال حاضر آنلاین هستند فیلتر میکند.
- trusted
- خروجی را با حفظ اطلاعات سرورهایی که به عنوان همتایان SSL مورد اعتماد هستند فیلتر میکند.
- signer
- خروجی را با حفظ اطلاعات سرورهایی که به عنوان امضاکنندگان ماژول مورد اعتماد هستند فیلتر میکند (به --privilege مراجعه کنید).
- compatible
- خروجی را با حفظ اطلاعات سرورهایی که با انتشار و معماری فعلی هسته سازگار هستند فیلتر میکند.
- اگر هیچ
آرگومانی
ارائه
نشود،
پیشفرض specified
است. اگر
هیچ سروری
با استفاده
از --use-server مشخص
نشده باشد،
سرورهای
پیشفرض
برای --use-server
فهرست
میشوند.
توجه داشته باشید که --list-servers از سرویس avahi-daemon برای شناسایی سرورهای آنلاین استفاده میکند. اگر این سرویس در دسترس نباشد، --list-servers در شناسایی سرورهای online ناموفق خواهد بود. برای اینکه --list-servers بتواند سرورهایی را که به آدرسهای IPv6 گوش میدهند شناسایی کند، فایل پیکربندی /etc/avahi/avahi-daemon.conf مربوط به avahi-daemon باید شامل یک خط فعال «use-ipv6=yes» باشد. پس از افزودن این خط، سرویس باید ریاستارت شود تا IPv6 فعال گردد.
- --trust-servers[=TRUST_SPEC]
- اعطا یا لغو اعتماد به سرورهای کامپایل مشخصشده با --use-server بر اساس TRUST_SPEC، که در آن TRUST_SPEC فهرستی جداشده با کاما است که نوع اعتماد مورد نظر برای اعطا یا لغو را تعیین میکند. عناصر پشتیبانیشده عبارتند از:
- ssl
- اعتماد به سرورهای مشخصشده به عنوان همتایان SSL.
- signer
- اعتماد به سرورهای مشخصشده به عنوان امضاکنندگان ماژول (به --privilege مراجعه کنید). فقط کاربر ریشه (root) میتواند signer را مشخص کند.
- all-users
- اعطای اعتماد به عنوان همتای SSL برای همه کاربران در میزبان محلی. پیشفرض این است که اعتماد به عنوان همتای SSL فقط برای کاربر جاری اعطا شود. اعتماد به عنوان امضاکننده ماژول همیشه برای همه کاربران اعطا میشود. فقط کاربر ریشه میتواند all-users را مشخص کند.
- revoke
- لغو اعتماد مشخصشده. پیشفرض اعطای آن است.
- no-prompt
- عدم درخواست تأیید از کاربر قبل از انجام عمل درخواستی. پیشفرض درخواست تأیید از کاربر است.
- اگر هیچ آرگومانی ارائه نشود، پیشفرض ssl است. اگر هیچ سروری با استفاده از --use-server مشخص نشده باشد، هیچ اعتمادی اعطا یا لغو نخواهد شد.
- مگر اینکه no-prompt مشخص شده باشد، قبل از انجام عملیات از کاربر خواسته میشود تا اعطا یا لغو اعتماد را تأیید کند.
- --sign-module
- امضای ماژول با MOK (کلید مالک دستگاه - Machine Owner Key) در سیستمهای UEFI/SecureBoot. برای جزئیات بیشتر بخش «بوت امن (SECUREBOOT)» را ببینید.
- --dump-probe-types
- فهرستی از انواع کاوشگرهای پشتیبانیشده را تخلیه کرده و خارج میشود. اگر --privilege=stapusr نیز مشخص شده باشد، فهرست به انواع کاوشگرهای در دسترس برای کاربران غیرممتاز محدود خواهد شد.
- --dump-probe-aliases
- فهرستی از تمام نامهای مستعار کاوشگر موجود در فایلهای کتابخانه را تخلیه کرده و خارج میشود.
- --dump-functions
- فهرستی از تمام توابع عمومی موجود در فایلهای کتابخانه را به همراه پارامترها و انواع آنها تخلیه کرده و خارج میشود. یک تابع از نوع «unknown» نشاندهنده تابعی است که مقداری برنمیگرداند. توجه داشته باشید که ممکن است همه انواع توابع/پارامترها قابل حل نباشند (اینها نیز با «unknown» نشان داده میشوند). این ویژگی بسیار نیازمند حافظه است و بنابراین ممکن است در صورت اعمال محدودیت rlimit بر حافظه فرایند توسط سرور هدف (مثلاً از طریق فایل پیکربندی ~stap-server/.systemtap/rc، به stap-server(8) مراجعه کنید)، همراه با --use-server به درستی کار نکند.
- --remote URL
- تنظیم هدف اجرا روی میزبان دادهشده. این گزینه ممکن است برای تعیین چندین هدف اجرا تکرار شود. گذرهای ۱ تا ۴ به صورت محلی و عادی برای ساخت اسکریپت تکمیل میشوند، و سپس گذر ۵ ماژول را در هدف کپی کرده و آن را اجرا میکند. قالبهای قابل قبول URL عبارتند از:
- [USER@]HOSTNAME, ssh://[USER@]HOSTNAME
- این حالت از ssh استفاده میکند، با امکان استفاده اختیاری از نام کاربری متفاوتی نسبت به نام کاربری شما. اگر فایل ssh_config سفارشی در حال استفاده است، عبارت SendEnv LANG را اضافه کنید تا قابلیت بینالمللیسازی حفظ شود.
- libvirt://DOMAIN, libvirt://DOMAIN/LIBVIRT_URI
- این حالت از stapvirt برای اجرای اسکریپت روی دامنهای که توسط libvirt مدیریت میشود استفاده میکند. به صورت اختیاری، LIBVIRT_URI را میتوان برای اتصال به یک درایور خاص و/یا میزبان راه دور مشخص کرد. برای مثال، برای اتصال به درایور ممتاز محلی QEMU، از:
--remote libvirt://MyDomain/qemu:///system
استفاده کنید. صفحه http://libvirt.org/uri.html را برای URIهای پشتیبانیشده ببینید. همچنین برای اطلاعات بیشتر درباره نحوه آمادهسازی دامنه برای کاوش stap به stapvirt(1) مراجعه کنید.
- --remote-prefix
- افزودن پیشوند «N: » به هر خط خروجی راه دور، که در آن N شاخص هدف اجرای راه دوری است که خط دادهشده از آن سرچشمه گرفته است.
- --download-debuginfo[=OPTION]
- فعالسازی، غیرفعالسازی یا تنظیم مهلت زمانی برای ویژگی دانلود خودکار debuginfo ارائهشده توسط abrt بر اساس OPTION، که در آن OPTION یکی از موارد زیر است:
- yes
- فعالسازی دانلود خودکار debuginfo بدون مهلت زمانی. این معادل عدم ارائه مقدار OPTION به --download-debuginfo است.
- no
- صریحاً دانلود خودکار debuginfo را غیرفعال میکند. این معادل عدم استفاده از این گزینه است.
- ask
- نمایش خروجی abrt و درخواست تأیید قبل از ادامه دانلود. هیچ مهلت زمانی تنظیم نخواهد شد.
- <timeout>
- تعیین مهلت زمانی به عنوان یک عدد مثبت برای توقف دانلود در صورتی که بیش از <timeout> ثانیه طول بکشد.
- --rlimit-as=NUM
- تعیین حداکثر اندازه حافظه مجازی (فضای آدرسدهی) فرایند، به بایت.
- --rlimit-cpu=NUM
- تعیین محدودیت زمان پردازنده (CPU time)، به ثانیه.
- --rlimit-nproc=NUM
- تعیین حداکثر تعداد فرایندهایی که میتوان ایجاد کرد.
- --rlimit-stack=NUM
- تعیین حداکثر اندازه پشته فرایند، به بایت.
- --rlimit-fsize=NUM
- تعیین حداکثر اندازه فایلهایی که فرایند میتواند ایجاد کند، به بایت.
- --sysroot=DIR
- تعیین دایرکتوری sysroot که فایلهای هدف (فایلهای اجرایی، کتابخانهها و غیره) در آن قرار دارند. با -r RELEASE، دایرکتوری sysroot برای یافتن دایرکتوری مناسب ساخت هسته جستجو میشود. با این حال، با -r /DIR، از sysroot برای یافتن دایرکتوری ساخت هسته استفاده نخواهد شد.
- --sysenv=VAR=VALUE
- ارائه یک مقدار جایگزین برای یک متغیر محیطی در مواردی که مقدار آن در یک سیستم راه دور متفاوت است. متغیرهای مسیر (مانند PATH، LD_LIBRARY_PATH) در صورت مشخص شدن، به عنوان مسیرهای نسبی به دایرکتوری ارائهشده توسط --sysroot در نظر گرفته میشوند.
- --suppress-time-limits
- غیرفعال کردن گزینههای مرتبط با -DSTP_OVERLOAD و همچنین -DMAXACTION و -DMAXTRYLOCK. این گزینه نیازمند حالت گورو (guru mode) است.
- --runtime=MODE
- تنظیم حالت زمان اجرای گذر ۵. گزینههای معتبر عبارتند از kernel (پیشفرض)، dyninst و bpf. برای اطلاعات بیشتر بخش زمانهای اجرای جایگزین (ALTERNATE RUNTIMES) در ادامه را ببینید.
- --dyninst
- حالت خلاصه برای --runtime=dyninst.
- --bpf
- حالت خلاصه برای --runtime=bpf.
- --save-uprobes
- در ماشینهایی که نیاز دارند SystemTap ماژول uprobes خود را بسازد (هستههای پیش از نسخه ۳.۵)، این گزینه به SystemTap دستور میدهد که یک نسخه از ماژول را در دایرکتوری جاری نیز ذخیره کند (ابتدا یک دایرکتوری جدید به نام «uprobes» ایجاد میکند).
- --target-namespaces=PID
- امکان تنظیم مجموعهای از فضاهای نام هدف را بر اساس فضاهای نامی که PID دادهشده در آن قرار دارد فراهم میکند. این برای توابع تپست آگاه از فضای نام است. اگر فضاهای نام هدف تنظیم نشده باشند، هدف به صورت پیشفرض فضاهای نام فرایند stap خواهد بود.
- --monitor=INTERVAL
- رابطی را برای نمایش اطلاعات وضعیت ماژول (زمان بالا بودن یا uptime، نام ماژول، شناسه کاربر فراخواننده یا uid، اندازههای حافظه، متغیرهای سراسری، فهرست کاوشگرها به همراه آمار آنها) فعال میکند. یک آرگومان اختیاری INTERVAL را میتوان برای تنظیم نرخ نوسازی پنجره وضعیت به ثانیه ارائه کرد. ماژول را میتوان با فهرستی از دستورات با استفاده از کلیدهای زیر نیز کنترل کرد:
- c
- تمام متغیرهای سراسری را به مقادیر اولیه خود بازنشانی میکند یا اگر مقدار اولیه نداشتند آنها را صفر میکند.
- s
- ویژگی استفادهشده برای مرتبسازی فهرست کاوشگرها را میچرخاند.
- t
- اعلانی را باز میکند تا امکان روشن/خاموش کردن کاوشگرها بر اساس شاخص فراهم شود. نقاط کاوش همچنان تحت تأثیر شرایط خود هستند.
- r
- اسکریپت را با روشن کردن تمام کاوشگرها از سر میگیرد.
- p
- اسکریپت را با خاموش کردن تمام کاوشگرها متوقف میکند (pause).
- x
- پنجره وضعیت را پنهان/نمایان میکند. این امکان مشاهده خروجی بیشتری را فراهم میکند.
- کلیدهای ناوبری را میتوان برای پیمایش به بالا و پایین پنجرهها استفاده کرد.
- Tab
- تغییر پیمایش میان پنجرههای وضعیت و خروجی.
- --example
- این گزینه برای اجرای اسکریپتهای نمونه بدون نیاز به وارد کردن مسیر کامل اسکریپت استفاده میشود. اسکریپتهای نمونه را میتوان در دایرکتوری مشخصشده در صفحه راهنمای stappaths(7) یافت.
- --no-global-var-display
- این گزینه برای غیرفعال کردن ثبت خودکار متغیرهای سراسری بدون استفاده در پایان نشست stap استفاده میشود.
- --language-server
- حالت کارساز زبان (Language server). راهاندازی یک سرور زبان که از طریق stdio ارتباط برقرار میکند. سرور زبان به سطح پرگویی stap احترام میگذارد.
- --build-as
- اجرای گذرهای ۱ تا ۴ تحت کاربر مشخصشده برای افزایش ایمنی. این رویکرد ممکن است محدودیتهایی داشته باشد. کاربران غیرممتاز ممکن است به kallsyms یا /proc دسترسی نداشته باشند. در زمان نصب RPM، کاربر stapunpriv ایجاد میشود، بنابراین میتوان stap را با --build-as=stapunpriv فراخوانی کرد.
آرگومانها (ARGUMENTS)
هرگونه آرگومان اضافی در خط فرمان برای جایگزینی به تجزیهکننده اسکریپت منتقل میشود. به ادامه مراجعه کنید.
زبان اسکریپتنویسی (SCRIPT LANGUAGE)
زبان اسکریپتنویسی systemtap شبیه به awk و C است. دو ساختار بیرونی اصلی وجود دارد: کاوشگرها و توابع. در درون اینها، دستورات و عبارات از نحو و اولویت عملگرهای مشابه C استفاده میکنند.
نحو عمومی (GENERAL SYNTAX)
فاصلههای خالی نادیده گرفته میشوند. سه شکل از توضیحات پشتیبانی میشوند:
# ... سبک شل، تا پایان خط، به جز $# و @#
// ... سبک ++C، تا پایان خط
/* ... سبک C ... */
علاوه بر این، آرگومانهای اسکریپت که در انتهای خط فرمان داده شدهاند را میتوان درج کرد. از $1 ... $<NN> برای درج بدون نقلقول، و از @1 ... @<NN> برای درج به عنوان رشته متنی استفاده کنید. تعداد آرگومانها از طریق $# (به عنوان عدد بدون نقلقول) یا از طریق @# (به عنوان عدد با نقلقول) قابل دسترسی است. اینها ممکن است در هر جایی که یک نشانه میتواند آغاز شود، از جمله در مرحله پیشپردازش، استفاده شوند. ارجاع به شماره آرگومانی فراتر از آنچه در واقع ارائه شده است یک خطا است.
پیشپردازش (PREPROCESSING)
یک مرحله پیشپردازش شرطی ساده به عنوان بخشی از تجزیه اجرا میشود. شکل کلی آن مشابه عملگر سهتایی cond ? exp1 : exp2 است:
%( CONDITION %? TRUE-TOKENS %) %( CONDITION %? TRUE-TOKENS %: FALSE-TOKENS %)
شرط (CONDITION) یا عبارتی است که قالب آن توسط اولین کلیدواژه آن تعیین میشود، یا مقایسهای از رشتههای متنی یا مقایسهای از مقادیر عددی ثابت است. همچنین میتواند از چندین حالت جایگزین و عطفهای مختلف از CONDITIONها (به همان معنای جمله قبل) با استفاده از || و && تشکیل شود. با این حال، پرانتزها هنوز پشتیبانی نمیشوند، بنابراین به خاطر سپردن این نکته که عطف (&&) بر فصل (||) اولویت دارد، اهمیت دارد.
اگر بخش اول شناسه kernel_vr یا kernel_v برای اشاره به شماره نسخه هسته باشد، همراه با پسوند کد انتشار ("2.6.13-1.322FC3smp") یا بدون آن ("2.6.13")، آنگاه بخش دوم یکی از شش عملگر مقایسه عددی استاندارد است: <, <=, ==, !=, >, و >=, و بخش سوم یک مقدار رشتهای است که حاوی مقدار نسخه-انتشار به سبک RPM است. شرط در صورتی برآورده تلقی میشود که نسخه هسته هدف (که به صورت اختیاری توسط گزینه -r لغو شده است) با رشته نسخه دادهشده مقایسه شود. این مقایسه توسط تابع glibc به نام strverscmp انجام میشود. به عنوان یک حالت خاص، اگر عملگر برای برابری ساده (==), یا نابرابری (!=), باشد و بخش سوم حاوی هرگونه نویسه عمومی مانند (* یا ? یا [), باشد، عبارت به عنوان تطبیق عمومی ارزیابیشده توسط fnmatch در نظر گرفته میشود.
اگر از سوی دیگر، بخش اول شناسه arch برای اشاره به معماری پردازنده باشد (همانطور که توسط سیستم ساخت هسته ARCH/SUBARCH نامگذاری شده است)، آنگاه بخش دوم یکی از دو عملگر مقایسه رشتهای == یا != است، و بخش سوم یک رشته متنی برای تطبیق با آن است. این مقایسه یک تطبیق عمومی است.
به همین ترتیب، اگر بخش اول شناسهای مانند CONFIG_something برای اشاره به یک گزینه پیکربندی هسته باشد، بخش دوم == یا != است و بخش سوم یک رشته متنی برای تطبیق با مقدار آن است (معمولاً "y" یا "m"). گزینههای پیکربندی هسته ناموجود یا تنظیمنشده با رشته خالی نمایش داده میشوند. این مقایسه نیز یک تطبیق عمومی است.
اگر بخش اول شناسه systemtap_v باشد، آزمون به نسخه سازگاری systemtap اشاره دارد که ممکن است برای اسکریپتهای قدیمی با فلگ --compatible لغو شود. عملگر مقایسه همانند kernel_v است و عملوند راست یک رشته نسخه است. همچنین بخش «منسوخشدگی (DEPRECATION)» در ادامه را ببینید.
اگر بخش اول شناسه systemtap_privilege باشد، آزمون به سطح دسترسیای اشاره دارد که اسکریپت systemtap با آن کامپایل شده است. در اینجا بخش دوم == یا != است و بخش سوم یک رشته متنی است که یکی از مقادیر "stapusr"، "stapsys" یا "stapdev" خواهد بود.
اگر بخش اول شناسه guru_mode باشد، آزمون بررسی میکند که آیا اسکریپت systemtap با guru_mode کامپایل شده است یا خیر. در اینجا بخش دوم == یا != است و بخش سوم یک عدد است، یا 1 یا 0.
اگر بخش اول شناسه runtime باشد، آزمون به حالت زمان اجرای systemtap اشاره دارد. برای اطلاعات بیشتر درباره زمانهای اجرا، بخش زمانهای اجرای جایگزین (ALTERNATE RUNTIMES) در ادامه را ببینید. بخش دوم یکی از دو عملگر مقایسه رشتهای == یا != است و بخش سوم یک رشته متنی برای تطبیق با آن است. این مقایسه یک تطبیق عمومی است.
در غیر این صورت، انتظار میرود که CONDITION مقایسهای بین دو رشته متنی یا دو مقدار عددی باشد. در این حالت، آرگومانها تنها متغیرهای قابل استفاده هستند.
نشانههای TRUE-TOKENS و FALSE-TOKENS صفر یا چند نشانه عمومی تجزیهکننده هستند (احتمالاً شامل پیشپردازندههای شرطی تو در تو)، و بسته به درستی یا نادرستی شرط به جریان ورودی ارسال میشوند. برای مثال، کد زیر موجب خطای تجزیه میشود مگر اینکه نسخه هسته هدف جدیدتر از 2.6.5 باشد:
%( kernel_v <= "2.6.5" %? **ERROR** %) # توالی نامعتبر نشانه
کد زیر ممکن است با تغییرات فرضی نسخه هسته سازگار شود:
probe kernel.function (
%( kernel_v <= "2.6.12" %? "__mm_do_fault" %:
%( kernel_vr == "2.6.13*smp" %? "do_page_fault" %:
UNSUPPORTED %) %)
) { /* ... */ }
%( arch == "ia64" %?
probe syscall.vliw = kernel.function("vliw_widget") {}
%)
ماکروهای پیشپردازنده (PREPROCESSOR MACROS)
پیشپردازنده همچنین از یک امکان ماکروی ساده پشتیبانی میکند که به عنوان یک گذر مجزا پیش از پیشپردازش شرطی اجرا میشود.
ماکروها با استفاده از ساختار زیر تعریف میشوند:
@define NAME %( BODY %) @define NAME(PARAM_1, PARAM_2, ...) %( BODY %)
ماکروها و پارامترهای داخل بدنه ماکرو هر دو با قرار دادن نماد @ در ابتدای نام ماکرو فراخوانی میشوند:
@define foo %( x %) @define add(a,b) %( ((@a)+(@b)) %) @foo = @add(2,2)
بسط ماکروها در حال حاضر در یک گذر مجزا قبل از کامپایل شرطی انجام میشود. بنابراین، نشانههای TRUE و FALSE در عبارات شرطی صرفنظر از نحوه ارزیابی شرط، بسط داده میشوند. این گاهی اوقات میتواند منجر به بروز خطا شود:
// مورد زیر منجر به تداخل میشود:
%( CONFIG_UPROBE == "y" %?
@define foo %( process.syscall %)
%:
@define foo %( **ERROR** %)
%)
// مورد زیر مطابق انتظار به درستی کار میکند:
@define foo %(
%( CONFIG_UPROBE == "y" %? process.syscall %: **ERROR** %)
%)
مثال اول نادرست است زیرا هر دو @define در گذری پیش از ارزیابی شرط ارزیابی میشوند.
به طور معمول، تعریف یک ماکرو محلی برای فایلی است که در آن رخ میدهد. بنابراین، تعریف یک ماکرو در یک تپست آن را در دسترس کاربر آن تپست قرار نمیدهد. ماکروهای کتابخانهای در دسترس عمومی را میتوان با گنجاندن فایلهای .stpm در مسیر جستجوی تپست تعریف کرد. این فایلها فقط میتوانند حاوی ساختارهای @define باشند که در سراسر تمام تپستها و اسکریپتهای کاربر قابل مشاهده خواهند بود. به صورت اختیاری، درون فایلهای .stpm، یک تعریف ماکروی عمومی میتواند توسط یک پیشپردازنده شرطی احاطه شود، همانطور که در بالا شرح داده شد.
ثابتها (CONSTANTS)
تپستها یا اسکریپتهای کاربر در حالت guru میتوانند با استفاده از عملگر داخلی @const() به نشانههای ثابت فایل سرآیند، که معمولاً ماکروها هستند، دسترسی پیدا کنند. گنجاندن فایل سرآیند مربوطه از طریق کتابخانه تپست یا با استفاده از یک ساختار C جاسازیشده سطح بالا در حالت guru امکانپذیر است. این منجر به تنظیم توضیحات پراگمای مناسب کد C جاسازیشده میشود.
@const("STP_SKIP_BADVARS")
ثابتهای شمارشی برنامههای اشکالزداییشده را میتوان با استفاده از عملگر داخلی @enum() در دسترس قرار داد. این عملگر نام ثابت شمارشی را در اطلاعات اشکالزدایی DWARF جستجو کرده و آن را با مقدار صحیح آن جایگزین میکند.
@enum("MY_ENUM_CONSTANT")
متغیرها (VARIABLES)
شناسههای متغیرها و توابع یک دنباله حرفی-عددی هستند و ممکن است شامل نویسههای _ و $ باشند. آنها نمیتوانند با یک رقم ساده شروع شوند، همانند C. هر متغیر به صورت پیشفرض محلی برای بلوک دستورات کاوشگر یا تابعی است که در آن ذکر شده است، و بنابراین دامنه و طول عمر آن به یک فراخوانی کاوشگر یا تابع خاص محدود است.
متغیرهای اسکالر به طور ضمنی دارای نوع رشتهای یا عدد صحیح هستند. آرایههای انجمنی نیز دارای مقدار رشتهای یا عددی بوده و یک چندتایی از رشتهها و/یا اعداد صحیح به عنوان کلید آنها عمل میکند. در اینجا چند عبارت پایه آورده شده است:
var1 = 5
var2 = "bar"
array1 [pid()] = "name" # کلید عددی تکی
array2 ["foo",4,i++] += 5 # برداری از کلیدهای رشته/عدد/عدد
if (["hello",5,4] in array2) println ("yes") # آزمون عضویت
مترجم استنتاج نوع را روی تمام شناسهها، از جمله شاخصهای آرایه و پارامترهای توابع انجام میدهد. استفاده ناسازگار مرتبط با نوع از شناسهها نشاندهنده خطا است.
متغیرها ممکن است سراسری اعلان شوند، به طوری که بین تمام کاوشگرها و توابع به اشتراک گذاشته شوند و تا پایان کل نشست systemtap زنده بمانند. یک فضای نام برای تمام متغیرهای سراسری وجود دارد، صرفنظر از اینکه در کدام فایل اسکریپت قرار داشته باشند. دسترسی همزمان به متغیرهای سراسری به طور خودکار با قفلها محافظت میشود؛ برای جزئیات بیشتر بخش ایمنی و امنیت (SAFETY AND SECURITY) را ببینید. یک اعلان سراسری را میتوان در بیرونیترین سطح در هر جایی نوشت، نه در داخل یک بلوک کد. متغیرهای سراسری که نوشته شده اما هرگز خوانده نشدهاند، در هنگام خاتمه نشست به طور خودکار نمایش داده میشوند. مترجم برای هر یک از آنها نوع مقدار آن، و در صورت استفاده به عنوان آرایه، انواع کلیدهای آن را استنتاج میکند. به صورت اختیاری، متغیرهای سراسری اسکالر ممکن است با یک مقدار رشتهای یا عددی مقداردهی اولیه شوند. اعلان زیر متغیرها را سراسری تعیین میکند:
global var1, var2, var3=4
متغیرهای سراسری را میتوان به عنوان گزینههای ماژول نیز تنظیم کرد. این کار را میتوان با استفاده از گزینه -G انجام داد، یا ماژول ابتدا باید با استفاده از stap -p4 کامپایل شود. سپس میتوان متغیرهای سراسری را در خط فرمان هنگام فراخوانی staprun روی ماژول تولیدشده توسط stap -p4 تنظیم کرد. برای اطلاعات بیشتر به staprun(8) مراجعه کنید.
دامنه یک متغیر سراسری را میتوان با استفاده از کلیدواژه private به یک تپست یا فایل اسکریپت کاربر محدود کرد. کلیدواژه global هنگام تعریف یک متغیر سراسری خصوصی اختیاری است. اعلان زیر var1 و var2 را به عنوان سراسریهای خصوصی تعیین میکند:
private global var1=2 private var2
اندازه آرایهها توسط متغیر MAXMAPENTRIES محدود میشود -- برای جزئیات به بخش ایمنی و امنیت (SAFETY AND SECURITY) مراجعه کنید. به صورت اختیاری، آرایههای سراسری ممکن است با حداکثر اندازه در قلابها اعلان شوند، که MAXMAPENTRIES را فقط برای آن آرایه لغو میکند. توجه داشته باشید که این نشاندهنده نوع کلیدهای آرایه نیست، بلکه فقط اندازه را مشخص میکند.
global tiny_array[10], normal_array, big_array[50000]
آرایهها را میتوان با استفاده از پسوند '%' برای چرخش پیکربندی کرد. این امر باعث میشود در صورتی که عناصر بیشتری نسبت به گنجایش آرایه درج شوند، عناصر قدیمیتر بازنویسی شوند. این هم برای آرایههای انجمنی و هم برای آرایههای با نوع آماری کار میکند.
global wrapped_array1%[10], wrapped_array2%
بسیاری از انواع نقاط کاوش متغیرهای زمینه را فراهم میکنند، که مقادیر زمان اجرا هستند و به طور ایمن از هسته یا برنامه فضای کاربری تحت کاوش استخراج میشوند. اینها با نویسه $ پیشوندگذاری میشوند. بخش CONTEXT VARIABLES در stapprobes(3stap) آنچه برای هر نوع نقطه کاوش در دسترس است را فهرست میکند. این متغیرهای زمینه پس از ذخیره شدن در متغیرهای عادی اسکریپت، به مقادیر اسکالر رشتهای یا عددی عادی تبدیل میشوند. برای نحوه تبدیل مجدد آنها به اشارهگرهای دارای نوع برای پردازش بیشتر به عنوان متغیرهای زمینه، بخش «تبدیل نوع (TYPECASTING)» را در ادامه ببینید. برای کمک به این امر خودکارسازیهایی وجود دارد!
دستورات (STATEMENTS)
دستورات جریان کنترل رویهای را امکانپذیر میسازند. آنها ممکن است در توابع و گردانندههای کاوشگر رخ دهند. تعداد کل دستورات اجراشده در پاسخ به هر رویداد کاوش تکی به عددی محدود میشود که توسط ماکروی MAXACTION در کد C ترجمهشده تعریف شده است و در حدود ۱۰۰۰ دستور است.
- EXP
- عبارت با مقدار رشتهای یا عددی را اجرا کرده و مقدار را دور میریزد.
- { STMT1 STMT2 ... }
- هر دستور را به ترتیب در این بلوک اجرا میکند. توجه داشته باشید که جداکنندهها یا پایاندهندهها معمولاً بین دستورات ضروری نیستند.
- ;
- دستور خالی، کاری انجام نمیدهد. این به عنوان یک جداکننده اختیاری بین دستورات برای بهبود تشخیص خطاهای نحوی و مدیریت برخی ابهامات گرامری مفید است.
- if (EXP) STMT1 [ else STMT2 ]
- عبارت عددی EXP را با صفر مقایسه میکند. اولین STMT (غیر صفر) یا دومین STMT (صفر) را اجرا میکند.
- while (EXP) STMT
- تا زمانی که مقدار عددی EXP غیر صفر ارزیابی شود، STMT را اجرا میکند.
- for (EXP1; EXP2; EXP3) STMT
- عبارت EXP1 را به عنوان مقداردهی اولیه اجرا میکند. تا زمانی که EXP2 غیر صفر است، STMT و سپس عبارت تکرار EXP3 را اجرا میکند.
- foreach (VAR in ARRAY [ limit EXP ]) STMT
- روی هر عنصر از آرایه سراسری نامگذاریشده حلقه میزند و کلید فعلی را به VAR تخصیص میدهد. آرایه ممکن است در طول دستور اصلاح نشود. با افزودن یک عملگر تکی + یا - بعد از شناسه VAR یا ARRAY، تکرار به ترتیب مرتبشده، بر اساس شاخص یا مقدار صعودی یا نزولی پیش میرود. اگر آرایه حاوی مقادیر تجمیعی آماری باشد، افزودن عملگر @operator مورد نظر بین شناسه ARRAY و + یا - تابع تجمیع مرتبسازی را مشخص میکند. برای موارد موجود، بخش «آمار (STATISTICS)» را در ادامه ببینید. پیشفرض @count است. استفاده از کلیدواژه اختیاری limit تعداد تکرارهای حلقه را به EXP بار محدود میکند. EXP یک بار در ابتدای حلقه ارزیابی میشود.
- foreach ([VAR1, VAR2, ...] in ARRAY [ limit EXP ]) STMT
- همانند بالا، در زمانی استفاده میشود که آرایه با یک چندتایی از کلیدها شاخصگذاری شده باشد. پسوند مرتبسازی ممکن است حداکثر روی یک شناسه VAR یا ARRAY استفاده شود.
- foreach ([VAR1, VAR2, ...] in ARRAY [INDEX1, INDEX2, ...] [ limit EXP ]) STMT
- همانند بالا، که در آن تکرارها به عناصری از آرایه محدود میشوند که کلیدهای آنها با مقادیر شاخص مشخصشده مطابقت داشته باشد. نماد * میتواند برای تعیین یک شاخص استفاده شود و به عنوان نویسه عمومی رفتار خواهد کرد.
- foreach (VAR0 = VAR in ARRAY [ limit EXP ]) STMT
- این نوع foreach مقدار فعلی را در هر تکرار در VAR0 ذخیره میکند، بنابراین مشابه ARRAY[VAR] است. این همچنین با چندتایی از کلیدها کار میکند. پسوندهای مرتبسازی روی VAR0 همان تأثیر روی ARRAY را دارند.
- foreach (VAR0 = VAR in ARRAY [INDEX1, INDEX2, ...] [ limit EXP ]) STMT
- همانند بالا، که در آن تکرارها به عناصری در آرایه محدود میشوند که کلیدها با مقادیر شاخص مشخصشده تطابق داشته باشند. نماد * میتواند برای تعیین یک شاخص استفاده شود و به عنوان نویسه عمومی رفتار خواهد کرد.
- break, continue
- خروج یا تکرار درونیترین حلقه تو در تو (while یا for یا foreach).
- return EXP
- بازگرداندن مقدار EXP از تابع محصورکننده. اگر مقدار تابع در جایی دریافت نشود، به دستور return نیازی نیست و تابع دارای نوع ویژه «unknown» بدون مقدار بازگشتی خواهد بود.
- next
- بازگشت فوری از گرداننده کاوشگر محصورکننده. این به ویژه در نامهای مستعار کاوشگر که گزارههای فیلتر رویداد را اعمال میکنند مفید است. هنگام استفاده در توابع، اجرا بلافاصله به تابع اورلودشده بعدی منتقل میشود.
- try { STMT1 } catch { STMT2 }
- اجرای دستورات در بلوک اول. هنگام بروز هرگونه خطای زمان اجرا، STMT1 را متوقف کرده و شروع به اجرای STMT2 میکند. هرگونه خطا در STMT2 به بلوکهای بیرونی try/catch (در صورت وجود) انتشار مییابد.
- try { STMT1 } catch(VAR) { STMT2 }
- همانند بالا، به علاوه تخصیص پیام خطا به متغیر اسکالر رشتهای VAR.
- delete ARRAY[INDEX1, INDEX2, ...]
- حذف عنصر مشخصشده توسط چندتایی شاخص از ARRAY. اگر چندتایی شاخص شامل یک * بهجای یک شاخص باشد، * به عنوان نویسه عمومی در نظر گرفته میشود و تمام عناصری که کلیدهایشان با چندتایی شاخص مطابقت داشته باشد از ARRAY حذف خواهند شد. مقدار دیگر در دسترس نخواهد بود و تکرارهای بعدی عنصر را گزارش نخواهند کرد. حذف عنصری که وجود ندارد خطا محسوب نمیشود.
- delete ARRAY
- حذف تمام عناصر از ARRAY.
- delete SCALAR
- مقدار SCALAR را حذف میکند. اعداد صحیح و رشتهها به ترتیب به 0 و "" پاک میشوند، در حالی که مقادیر آماری به حالت خالی اولیه بازنشانی میشوند.
عبارات (EXPRESSIONS)
سیستمتپ از تعدادی عملگر پشتیبانی میکند که دارای نحو عمومی، معنایی و اولویت مشابه با C و awk هستند. محاسبات بر اساس قواعد معمولی C برای اعداد صحیح علامتدار انجام میشود. تقسیم بر صفر یا سرریز تشخیص داده شده و منجر به خطا میشود.
- عملگرهای عددی دودویی
- * / % + - >> << & ^ | && ||
- عملگرهای رشتهای دودویی
- . (الحاق رشته)
- عملگرهای انتساب عددی
- = *= /= %= += -= >>= <<= &= ^= |=
- عملگرهای انتساب رشتهای
- = .=
- عملگرهای عددی یکانی
- + - ! ~ ++ --
- عملگرهای مقایسه عددی، رشتهای یا تطبیق عبارات باقاعده دودویی
- < > <= >= == != =~ !~
- عملگر سهتایی
- cond ? exp1 : exp2
- عملگر گروهبندی
- ( exp )
- فراخوانی تابع
- fn ([ arg1, arg2, ... ])
- بررسی عضویت در آرایه
- exp in array
[exp1, exp2, ... ] in array
[*, *, ... ] in array
تطبیق عبارات باقاعده (REGULAR EXPRESSION MATCHING)
زبان اسکریپتنویسی از تطبیق عبارات باقاعده پشتیبانی میکند. نحو پایه به شکل زیر است:
exp =~ regex exp !~ regex
(عملوند اول باید عبارتی باشد که به یک رشته ارزیابی میشود؛ عملوند دوم باید یک رشته متنی حاوی یک عبارت باقاعده از نظر نحوی معتبر باشد.)
نحو عبارت باقاعده از ویژگیهای عبارات باقاعده توسعهیافته POSIX همانطور که در grep(1) مستند شده است، به جز قابلیت استفاده مجدد از زیرعبارت ("\1") پشتیبانی میکند.
پس از یک تطبیق موفق، محتوای رشته تطبیقیافته و زیرعبارتها را میتوان با استفاده از توابع تپست matched() و ngroups() به شکل زیر استخراج کرد:
if ("an example string" =~ "str(ing)") {
matched(0) // -> مقدار "string"، زیررشته تطبیقیافته را برمیگرداند
matched(1) // -> مقدار "ing"، اولین زیرعبارت تطبیقیافته را برمیگرداند
ngroups() // -> مقدار 2، تعداد گروههای تطبیقیافته را برمیگرداند
}
کاوشگرها (PROBES)
ساختار اصلی در زبان اسکریپتنویسی، کاوشگرها را مشخص میکند. کاوشگرها رویدادهای انتزاعی را با یک بلوک دستورات («گرداننده کاوشگر» یا probe handler) پیوند میدهند که در هنگام رخ دادن هر یک از آن رویدادها اجرا میشود. نحو عمومی به صورت زیر است:
probe PROBEPOINT [, PROBEPOINT] { [STMT ...] }
probe PROBEPOINT [, PROBEPOINT] if (CONDITION) { [STMT ...] }
رویدادها با نحوی خاص به نام «نقاط کاوش» (probe points) مشخص میشوند. انواع مختلفی از نقاط کاوش توسط مترجم تعریف شدهاند و اسکریپتهای تپست میتوانند موارد بیشتری را با استفاده از نامهای مستعار تعریف کنند. نقاط کاوش ممکن است دارای نویسههای عمومی باشند، گروهبندی شوند، در دنبالههای اولویتدار فهرست شوند، یا به عنوان اختیاری اعلان شوند. جزئیات بیشتر درباره نحو و معناشناسی نقاط کاوش در صفحه راهنمای stapprobes(3stap) فهرست شده است.
گرداننده کاوشگر متناسب با زمینه (context) هر رویداد تفسیر میشود. برای رویدادهای مرتبط با کد هسته، این زمینه ممکن است شامل متغیرهایی باشد که در کد منبع در آن نقطه تعریف شدهاند. این «متغیرهای زمینه» به عنوان متغیرهایی که نام آنها با "$" پیشوندگذاری شده است به اسکریپت ارائه میشوند. این متغیرها تنها در صورتی قابل دسترسی هستند که کامپایلر هسته علیرغم بهینهسازیها آنها را حفظ کرده باشد. این همان محدودیتی است که کاربر یک دیباگر هنگام کار با کد بهینهشده با آن مواجه میشود. علاوه بر این، اشیاء باید در لحظه اجرای گرداننده کاوشگر systemtap در حافظه صفحهبندیشده (paged-in) وجود داشته باشند، زیرا systemtap نباید هیچگونه صفحهبندی اضافی ایجاد کند (آن را سرکوب میکند). برخی از انواع کاوشگرها دارای زمینه بسیار کمی هستند. صفحات راهنمای stapprobes(3stap) را برای دیدن انواع متغیرهای زمینه موجود در هر نوع نقطه کاوش ببینید. از نسخه ۴.۳ سیستمتپ، توابعی که از درون گردانندههای برخی از انواع نقاط کاوش فراخوانی میشوند نیز ممکن است به متغیرهای زمینه ارجاع دهند. با این موارد به گونهای رفتار میشود که گویی کلونی از آن تابع در گرداننده کاوشگر فراخواننده به صورت درونخطی قرار گرفته و متغیرهای $ در زمینه آن ارزیابی شدهاند.
کاوشگرها ممکن است با یک شرط مسلحسازی (arming condition) تزیین شوند، که شامل یک عبارت بولی ساده روی متغیرهای سراسری فقطخواندنی اسکریپت است. در حالی که کاوشگر غیرمسلح (غیرفعال، ارزیابی شرط به نادرست) است، برخی از انواع کاوشگرها بار پردازشی زمان اجرای خود را کاهش داده یا حذف میکنند. هنگامی که یک شرط مسلحسازی به درست ارزیابی شود، کاوشگرها به زودی مجدداً مسلح میشوند، و با فعال شدن رویدادها، گردانندههای کاوشگر آنها شروع به فراخوانی شدن میکنند. (برخی رویدادها ممکن است در طول بازه مسلحسازی از دست بروند. اگر این امر غیرقابل قبول است، از شرایط مسلحسازی برای آن کاوشگرها استفاده نکنید.) مثالی از نحو:
probe timer.us(TIMER) if (enabled) {
}
نقاط کاوش جدید را میتوان با استفاده از «نامهای مستعار» (aliases) تعریف کرد. نامهای مستعار نقاط کاوش شبیه به تعاریف کاوشگر هستند، اما بهجای فعالسازی کاوشگر در نقطه دادهشده، صرفاً نام نقطه کاوش جدیدی را به عنوان نام مستعار برای یک نقطه موجود تعریف میکنند. دو نوع نام مستعار وجود دارد، یعنی سبک پیشدرآمد (prologue) و سبک پسدرآمد (epilogue) که به ترتیب با "=" و "+=" مشخص میشوند.
برای نام مستعار سبک پیشدرآمد، بلوک دستوراتی که بعد از تعریف نام مستعار میآید، به طور ضمنی به عنوان یک پیشدرآمد به هر کاوشگری که به این نام مستعار ارجاع میدهد اضافه میشود. در حالی که برای نام مستعار سبک پسدرآمد، بلوک دستوراتی که بعد از تعریف نام مستعار میآید، به طور ضمنی به عنوان یک پسدرآمد به هر کاوشگری که به این نام مستعار ارجاع میدهد اضافه میشود. برای مثال:
probe syscall.read = kernel.function("sys_read") {
fildes = $fd
if (execname() == "init") next # رد کردن ادامه کاوشگر
}
یک نقطه کاوش جدید به نام syscall.read تعریف میکند، که به kernel.function("sys_read") بسط مییابد، همراه با دستور دادهشده به عنوان یک پیشدرآمد، که برای از پیش تعریف کردن برخی متغیرها برای کاربر نام مستعار و/یا برای رد کردن کامل پردازش کاوشگر بر اساس برخی شرایط مفید است. و
probe syscall.read += kernel.function("sys_read") {
if (tracethis) println ($fd)
}
یک نقطه کاوش جدید همراه با دستور دادهشده به عنوان پسدرآمد تعریف میکند، که برای انجام اقداماتی بر اساس متغیرهای تنظیمشده یا باقیمانده توسط کاربر نام مستعار مفید است. لطفاً توجه داشته باشید که در هر حالت، با دستورات موجود در بلوک گرداننده نام مستعار به صورت عادی رفتار میشود، بهطوری که متغیرهای اختصاصیافته در آنجا صرفاً مقداردهی اولیه را تشکیل میدهند، نه یک جایگزینی ماکرو.
نامهای مستعار را میتوان به گونهای نیز تعریف کرد که شامل هر دو بخش پیشدرآمد و پسدرآمد باشند.
probe syscall.read = kernel.function("sys_read") {
fildes = $fd
if (execname() == "init") next
},{
if (tracethis) println ($fd)
}
یک نام مستعار دقیقاً مانند یک نوع کاوشگر توکار استفاده میشود.
probe syscall.read {
printf("reading fd=%d\n", fildes)
if (fildes > 10) tracethis = 1
}
کاوشگرهای دارای نام مستعار میتوانند از گزاره @probewrite استفاده کنند. این بررسی برای تشخیص این است که آیا در بدنه گرداننده کاوشگر در یک متغیر اسکریپت یا متغیر هدف مقداری نوشته شده است یا خیر.
- @probewrite(var)
- در صورتی و تنها در صورتی به 1 بسط مییابد که در بدنه گرداننده کاوشگر روی var نوشته شده باشد، در غیر این صورت به 0 بسط مییابد.
در مثال زیر، @probewrite(var) به 1 بسط مییابد زیرا در بدنه گرداننده کاوشگر روی var نوشته شده است و در نتیجه، دستور شرطی اجرا خواهد شد.
probe foo = begin { var = 0 }, { if (@probewrite(var)) println(var) }
probe foo {
var = 1
}
توابع (FUNCTIONS)
اسکریپتهای systemtap میتوانند زیرروالهایی را برای تفکیک کارهای مشترک تعریف کنند. توابع هر تعداد آرگومان اسکالر (عدد صحیح یا رشته) را میپذیرند و باید یک اسکالر منفرد (عدد صحیح یا رشته) را برگردانند. یک نمونه اعلان تابع به این صورت است:
function thisfn (arg1, arg2) {
return arg1 + arg2
}
به عدم وجود کلی اعلان نوع توجه داشته باشید که در عوض توسط مترجم استنتاج میشود. با این حال، در صورت تمایل، یک تعریف تابع میتواند شامل اعلانهای نوع صریح برای مقدار بازگشتی و/یا آرگومانهای آن باشد. این به ویژه برای توابع C جاسازیشده مفید است. در مثال زیر، موتور استنتاج نوع تنها نیاز دارد نوع arg2 (یک رشته) را استنتاج کند:
function thatfn:string (arg1:long, arg2) {
return sprint(arg1) . arg2
}
توابع ممکن است توابع دیگر یا خود را به صورت بازگشتی، تا یک محدودیت تودرتویی ثابت فراخوانی کنند. این محدودیت توسط ماکروی MAXNESTING در کد C ترجمهشده تعریف شده و در حدود ۱۰ است.
توابع را میتوان با استفاده از کلیدواژه private خصوصی علامتگذاری کرد تا دامنه آنها به تپست یا فایل اسکریپت کاربری که در آن تعریف شدهاند محدود شود. یک نمونه تعریف از یک تابع خصوصی در ادامه آمده است:
private function three:long () { return 3 }
توابعی که بدون رسیدن به دستور return صریح خاتمه مییابند، یک مقدار ضمنی 0 یا "" را برمیگردانند که توسط استنتاج نوع تعیین میشود.
توابع را میتوان در زمان اجرا و زمان کامپایل اورلود (overload) کرد.
اورلودینگ زمان اجرا امکان میدهد که تابع اجراشونده در حین اجرای ماژول بر اساس شرایط زمان اجرا انتخاب شود و این با استفاده از دستور «next» در توابع اسکریپت و ماکروی STAP_NEXT برای توابع C جاسازیشده حاصل میشود. برای مثال:
function f() { if (condition) next; print("first function") }
function f() %{ STAP_NEXT; print("second function") %}
function f() { print("third function") }
در طول فراخوانی تابع f()، در صورتی که condition به درست ارزیابی شود، اجرا به تابع سوم منتقل شده و عبارت "third function" را چاپ میکند. توجه داشته باشید که تابع دوم بدون قید و شرط به تابع بعدی منتقل میشود (unconditionally nexted).
اورلودینگ پارامتر امکان میدهد تابع اجراشونده در زمان کامپایل بر اساس تعداد آرگومانهای ارائهشده به فراخوانی تابع انتخاب شود. برای مثال:
function g() { print("first function") }
function g(x) { print("second function") }
g() -> "first function"
g(1) -> "second function"
توجه داشته باشید که اورلودینگ زمان اجرا در مثال بالا رخ نمیدهد، زیرا دقیقاً یک تابع برای فراخوانی تابع حل خواهد شد. استفاده از دستور next در داخل یک تابع در حالی که هیچ اورلود دیگری باقی نمانده باشد، یک استثنای زمان اجرا ایجاد میکند. اورلودینگ زمان اجرا تنها در صورتی رخ میدهد که توابع دارای تعداد پارامترهای یکسان باشند؛ توابع با نام یکسان اما تعداد پارامترهای متفاوت کاملاً بیارتباط هستند.
ترتیب اجرا با یک مقدار اولویت که ممکن است مشخص شود تعیین میگردد. اگر هیچ اولویت صریحی مشخص نشده باشد، به توابع اسکریپت کاربر اولویت بالاتری نسبت به توابع کتابخانهای داده میشود. به توابع اسکریپت کاربر و توابع کتابخانهای به ترتیب مقدار اولویت پیشفرض 0 و 1 اختصاص مییابد. توابع با اولویت یکسان به ترتیب اعلان اجرا میشوند. برای مثال:
function f():3 { if (condition) next; print("first function") }
function f():1 { if (condition) next; print("second function") }
function f():2 { print("third function") }
از آنجا که تابع دوم بالاترین اولویت را دارد، ابتدا اجرا میشود. تابع اول هرگز اجرا نمیشود زیرا هیچ دستور "next" در تابع سوم برای انتقال اجرا وجود ندارد.
چاپ (PRINTING)
مجموعهای از نامهای توابع وجود دارند که به طور ویژه توسط مترجم مورد پردازش قرار میگیرند. آنها مقادیر را برای چاپ در جریان خروجی استاندارد systemtap به روشی راحتتر قالببندی میکنند (توجه داشته باشید که دادههای تولیدشده در ماژول هسته باید به فضای کاربری منتقل شوند تا چاپ شوند).
گونههای sprint* بهجای چاپ رشته قالببندیشده، آن را برمیگردانند.
- print, sprint
- چاپ یک یا چند مقدار از هر نوع، که مستقیماً به هم متصل شدهاند.
- println, sprintln
- چاپ مقادیر مانند print و sprint، اما همراه با افزودن یک خط جدید (newline).
- printd, sprintd
- دریافت یک جداکننده رشتهای و دو یا چند مقدار از هر نوع، و چاپ مقادیر در حالی که جداکننده بین آنها قرار گرفته است. جداکننده باید یک ثابت رشتهای متنی باشد.
- printdln, sprintdln
- چاپ مقادیر با جداکننده مانند printd و sprintd، اما همراه با افزودن یک خط جدید.
- printf, sprintf
- دریافت یک رشته قالببندی و تعدادی مقدار از انواع متناظر، و چاپ همه آنها. قالب باید یک ثابت رشتهای متنی باشد.
دستورالعملهای قالببندی printf مشابه دستورالعملهای C هستند، با این تفاوت که به طور کامل توسط مترجم بررسی نوع میشوند:
- %b
- نوشتن یک بلوک باینری از مقدار دادهشده، بهجای متن ASCII. مشخصکننده عرض، تعداد بایتها را برای نوشتن تعیین میکند؛ مشخصکنندههای معتبر %b %1b %2b %4b %8b هستند. پیشفرض (%b) برابر با ۸ بایت است.
- %c
- نویسه (Character).
- %d,%i
- عدد صحیح دهدهی علامتدار.
- %m
- خواندن ایمن حافظه هسته (بدون #) یا حافظه کاربر (با #) در آدرس دادهشده، و خروجی دادن محتوای آن. مشخصکننده دقت اختیاری (نه عرض فیلد) تعداد بایتها را برای خواندن تعیین میکند - پیشفرض ۱ بایت است. %10.4m تعداد ۴ بایت از حافظه را در یک فیلد با عرض ۱۰ نویسه چاپ میکند. توجه داشته باشید که در برخی معماریها حافظه کاربر همچنان میتواند بدون # خوانده شود.
- %M
- همانند %m، اما خروجی را در مبنای شانزده تولید میکند. حداقل اندازه خروجی دو برابر مشخصکننده دقت اختیاری است - پیشفرض ۱ بایت (۲ نویسه هگز) است. %10.4M تعداد ۴ بایت از حافظه را به عنوان ۸ نویسه هگزادسیمال در فیلدی با عرض ۱۰ نویسه چاپ میکند. %.*M یک تخلیه هگزادسیمال از تعداد مشخصی بایت از یک بافر دادهشده را ارائه میدهد.
- %o
- عدد در مبنای هشت بدون علامت.
- %p
- آدرس اشارهگر بدون علامت.
- %s
- رشته.
- %u
- عدد دهدهی بدون علامت.
- %x
- مقدار هگزادسیمال بدون علامت، با حروف کوچک.
- %X
- مقدار هگزادسیمال بدون علامت، با حروف بزرگ.
- %%
- چاپ یک علامت %.
فلگ # اشکال جایگزین را انتخاب میکند. برای مبنای هشت، یک 0 پیشوند میزند. برای هگز، بسته به بزرگی یا کوچکی حروف، 0x یا 0X پیشوند میزند. برای نویسهها، مقادیر غیرقابل چاپ را با کدهای گریز مشابه C یا هشتهشتی خام گریز میدهد. در مورد %#m/%#M، این به طور ایمن به حافظه فضای کاربری دسترسی پیدا میکند تا حافظه فضای هسته.
مثالها:
a = "alice", b = "bob", p = 0x1234abcd, i = 123, j = -1, id[a] = 1234, id[b] = 4567
print("hello")
Prints: hello
println(b)
Prints: bob\n
println(a . " is " . sprint(16))
Prints: alice is 16
foreach (name in id) printdln("|", strlen(name), name, id[name])
Prints: 5|alice|1234\n3|bob|4567
printf("%c is %s; %x or %X or %p; %d or %u\n",97,a,p,p,p,j,j)
Prints: a is alice; 1234abcd or 1234ABCD or 0x1234abcd; -1 or 18446744073709551615\n
printf("2 bytes of kernel buffer at address %p: %2m", p, p)
Prints: 2 byte of kernel buffer at address 0x1234abcd: <binary data>
printf("%4b", p)
Prints (these values as binary data): 0x1234abcd
printf("%#o %#x %#X\n", 1, 2, 3)
Prints: 01 0x2 0X3
printf("%#c %#c %#c\n", 0, 9, 42)
Prints: \000 \t *
آمار (STATISTICS)
اغلب مطلوب است که آمارها به گونهای جمعآوری شوند که از جریمههای قفل کردن مکرر و انحصاری متغیرهای سراسری که این اعداد در آنها قرار میگیرند جلوگیری شود. Systemtap با استفاده از یک عملگر ویژه برای انباشت مقادیر، و چندین شبهتابع برای استخراج مقادیر تجمیعی آماری، راهکاری را ارائه میدهد.
عملگر تجمیع <<< است و شبیه به یک انتساب یا عملیات جریان خروجی ++C است. عملوند چپ یک lvalue اسکالر یا شاخص آرایه را مشخص میکند که باید سراسری اعلان شده باشد. عملوند راست یک عبارت عددی است. معنای آن شهودی است: عدد دادهشده را به انبوه اعدادی که باید آمار آنها محاسبه شود اضافه کنید. (فهرست خاص آمارهایی که باید جمعآوری شوند به طور جداگانه توسط توابع استخراج ارائه میشود.)
foo <<< 1 stats[pid()] <<< memsize
توابع استخراج نیز ویژه هستند. برای هر بار استفاده از یک تابع استخراج متمایز که روی یک شناسه مشخص عمل میکند، مترجم ترتیب محاسبه مجموعهای از آمارها را میدهد که آن را برآورده سازد. بدین ترتیب سیستم آمار به صورت «در صورت تقاضا» (on-demand) است. هر اجرای یک تابع استخراج باعث میشود که تجمیع برای آن لحظه در سراسر تمام پردازندهها محاسبه شود.
در اینجا مجموعه توابع استخراجکننده آورده شده است. اولین آرگومان هر کدام همان سبک lvalue استفادهشده در سمت چپ عملیات انباشت است. توابع استخراجکننده @count(v), @sum(v), @min(v), @max(v), @avg(v), و @variance(v[, b]) تعداد/مجموع/حداقل/حداکثر/میانگین/واریانس تمام مقادیر انباشتهشده را محاسبه میکنند. مقادیر حاصل همگی اعداد صحیح ساده هستند. آرایههای حاوی مقادیر تجمیعی را میتوان مرتب کرده و روی آنها پیمایش انجام داد. ساختار foreach در بالا را ببینید.
واریانس از الگوریتم آنلاین Welford استفاده میکند. محاسبات مبتنی بر محاسبات اعداد صحیح است و بنابراین ممکن است از دقت پایین و سرریز رنج ببرد. برای بهبود این مورد، @variance(v[, b]) یک پارامتر اختیاری b یعنی جابجایی بیتی (bit-shift) را در محدوده 0 (پیشفرض) تا 62 برای مقیاسبندی داخلی میپذیرد. تنها یک مقدار جابجایی بیتی ممکن است با متغیر سراسری دادهشده استفاده شود. مقدار جابجایی بیتی بزرگتر دقت را افزایش میدهد، اما احتمال سرریز را نیز بیشتر میکند.
$ stap -e > 'global x probe oneshot { for(i=1;i<=5;i++) x<<<i println(@variance(x)) }'
12
$ stap -e > 'global x probe oneshot { for(i=1;i<=5;i++) x<<<i println(@variance(x,1)) }'
2
$ python3 -c 'import statistics; print(statistics.variance([1, 2, 3, 4, 5]))'
2.5
$
سرریز (ناشی از ضرب داخلی اعداد بزرگ) ممکن است رخ دهد و ممکن است باعث نتیجه واریانس منفی شود. نرمالسازی دادههای ورودی خود را در نظر بگیرید. افزودن یا کم کردن یک مقدار ثابت از تمام ورودیهای واریانس، واریانس اصلی را حفظ میکند. تقسیم ورودیهای واریانس بر یک مقدار ثابت، واریانس اصلی را به توان دو آن مقدار کوچک میکند.
نمودارهای میلهای (هیستوگرامها) نیز در دسترس هستند، اما پیچیدهترند زیرا به جای مقدار اسکالر دارای مقدار برداری هستند. @hist_linear(v,start,stop,interval) یک هیستوگرام خطی را از "start" تا "stop" (شامل هر دو) با گامهای "interval" نشان میدهد. بازه باید مثبت باشد. به همین ترتیب، @hist_log(v) یک هیستوگرام لگاریتمی در مبنای ۲ را نشان میدهد. چاپ یک هیستوگرام با خانواده توابع print یک شیء هیستوگرام را به صورت یک نمودار میلهای جدولبندیشده "ASCII art" رندر میکند.
probe timer.profile {
x[1] <<< pid()
x[2] <<< uid()
y <<< tid()
}
global x // an array containing aggregates
global y // a scalar
probe end {
foreach ([i] in x @count+) {
printf ("x[%d]: avg %d = sum %d / count %d\n",
i, @avg(x[i]), @sum(x[i]), @count(x[i]))
println (@hist_log(x[i]))
}
println ("y:")
println (@hist_log(y))
}
تعداد مقادیر هر بخش (bucket) هیستوگرام را میتوان به صورت جداگانه از طریق عملگر [index] در دسترس قرار داد. هر بخش از 1 تا N (برای هر بخش طبیعی) آدرسدهی میشود. علاوه بر این، بخش شماره 0 تمام نمونههای زیر مقدار شروع را میشمارد و بخش شماره N+1 تمام نمونههای بالای مقدار توقف را میشمارد. روی بخشهای هیستوگرام (شامل دو بخش خارج از محدوده) نیز میتوان با foreach پیمایش کرد.
global x
probe oneshot {
x <<< -100
x <<< 1
x <<< 2
x <<< 3
x <<< 100
foreach (bucket in @hist_linear(x,1,3,1))
// expecting 1 out-of-range-low bucket
// 3 payload buckets
// 1 out-of-range-high bucket
printf("bucket %d count %d\n",
bucket, @hist_linear(x,1,3,1)[bucket])
}
تبدیل نوع (TYPECASTING)
به محض اینکه یک اشارهگر (بخش CONTEXT VARIABLES در stapprobes(3stap) را ببینید) در یک متغیر عددی اسکریپت ذخیره شد، مترجم تلاش میکند اطلاعات نوع لازم را برای دسترسی به اعضا از آن اشارهگر حفظ کند.
مترجم تلاش میکند تا نوعبندی DWARF مرتبط با متغیرهای اسکریپت اختصاصیافته از آدرسهای متغیرهای زمینه $، عملگرهای @cast یا @var را ردیابی کند. بسته به پیچیدگی کد اسکریپت، این وابستگی ممکن است به متغیرهای مرتبط منتقل شود، به طوری که عملگرهای -> و [] بتوانند روی آنها استفاده شوند، دقیقاً همانند متغیر زمینه اصلی. برای مثال:
foo = $param->foo; printf("x:%d y:%d\n", foo->x, foo->y)
printf("my value is %d\n", ($type == 42 ? $foo : $bar)->value)
printf("my parent pid is %d\n", task_parent(task_current())->tgid)
با این حال، اگر این روش اکتشافی وابستگی برای یک اسکریپت کار نکند، استفاده از عملگر @cast() به مترجم میگوید که چگونه عدد را به عنوان یک اشارهگر دارای نوع تفسیر کند.
@cast(p, "type_name"[, "module"])->member
این کار p را به عنوان یک اشارهگر به یک struct/union به نام type_name تفسیر کرده و مقدار member را ارجاعزدایی میکند. عبارات دیگر ->subfield را میتوان برای ارجاعزدایی سطوح بیشتر ضمیمه کرد. توجه داشته باشید که برای ارجاعزدایی مستقیم یک اشارهگر باید از {kernel,user}_{char,int,...}($p) استفاده شود (برای جزئیات بیشتر به stapfuncs(5) مراجعه کنید). نکته: همان عملگر ارجاعزدایی -> برای اشاره به هر دوی دربرگیری مستقیم یا ارجاع غیرمستقیم اشارهگر استفاده میشود. Systemtap به طور خودکار تعیین میکند که کدام یک است. آرگومان اختیاری module به مترجم میگوید که کجا به دنبال اطلاعات درباره آن نوع بگردد. چندین ماژول را میتوان به صورت یک فهرست با جداکنندههای : مشخص کرد. اگر ماژول مشخص نشده باشد، مقدار پیشفرض آن برای کاوشگرهای dwarf برابر با ماژول کاوشگر، یا برای توابع و سایر انواع کاوشگرها برابر با "kernel" خواهد بود.
پیش از این تا نسخه ۴.۲ سیستمتپ، در صورت عدم تعیین، "kernel" استنتاج میشد. از --compatible=4.2 برای فعالسازی این پیشفرض استفاده کنید.
مترجم میتواند در صورتی که debuginfo عادی در دسترس نباشد، ماژول خود را با اطلاعات نوع از یک سرآیند محصور در براکتهای زاویهدار ایجاد کند. برای سرآیندهای هسته، آن را با "kernel" پیشوندگذاری کنید تا از سیستم ساخت مناسب استفاده شود. سایر سرآیندها با پارامترهای پیشفرض GCC در یک ماژول کاربری ساخته میشوند. چندین سرآیند را میتوان به ترتیب برای حل وابستگی متقابل مشخص کرد.
از نسخه ۵.۴ سیستمتپ، سرآیند هسته "<vmlinux.h>" قبل از هر سرآیند یا ماژول هسته مشخصشده امتحان میشود، که ممکن است ذکر هرگونه نام صریح فایل ماژول یا سرآیند را برای ساختارهای داده هسته غیرضروری سازد.
@cast(tv, "timeval", "<sys/time.h>")->tv_sec
@cast(task, "task_struct", "kernel<linux/sched.h>")->tgid
@cast(task, "task_struct",
"kernel<linux/sched.h><linux/fs_struct.h>")->fs->umask
مقادیر به دست آمده توسط @cast ممکن است با عملگرهای پسوندی $ و $$ به زیبایی چاپ شوند، به همان روشی که در بخش CONTEXT VARIABLES در صفحه راهنمای stapprobes(3stap) شرح داده شده است.
در حالت guru، مترجم به اسکریپتها اجازه میدهد تا مقادیر جدیدی را نیز به اعضای اشارهگرهای تبدیلنوعشده اختصاص دهند.
تبدیل نوع همچنین در مورد اعضای void* که نوع آنها ممکن است در زمان اجرا قابل تعیین باشد، مفید است.
probe foo {
if ($var->type == 1) {
value = @cast($var->data, "type1")->bar
} else {
value = @cast($var->data, "type2")->baz
}
print(value)
}
کد C جاسازیشده (EMBEDDED C)
در حالت guru، مترجم کد C جاسازیشده را در سطح بالای اسکریپت میپذیرد. چنین کدی بین نشانگرهای %{ و %} محصور میشود و عیناً و بدون تحلیل، در دنبالهای مشخص به سطح بالای کد C تولیدشده منتقل میشود. در بیرونیترین سطح، این ممکن است برای افزودن دستورالعملهای #include و هرگونه تعاریف کمکی برای استفاده توسط سایر کدهای جاسازیشده مفید باشد.
محل دیگری که کد جاسازیشده در آن مجاز است، به عنوان بدنه یک تابع است. در این حالت، بدنه زبان اسکریپت به طور کامل با قطعهای از کد C که مجدداً بین نشانگرهای %{ و %} محصور شده است جایگزین میشود. این کد C ممکن است هر کار معقول و ایمنی را انجام دهد. تعدادی محدودیت ایمنی مستندنشده اما پیچیده در مورد اتمیک بودن، همزمانی، مصرف منابع، و محدودیتهای زمان اجرا وجود دارد، بنابراین این یک تکنیک پیشرفته است.
مکانهای حافظه اختصاصدادهشده برای مقادیر ورودی و خروجی با استفاده از ماکروهای STAP_ARG_* و STAP_RETVALUE در دسترس آن قرار میگیرند. خطاها را میتوان با STAP_ERROR علامت داد. خروجی را میتوان با STAP_PRINTF نوشت. تابع ممکن است با STAP_RETURN زودتر بازگردد. در اینجا چند مثال آورده شده است:
function integer_ops (val) %{
STAP_PRINTF("%d\n", STAP_ARG_val);
STAP_RETVALUE = STAP_ARG_val + 1;
if (STAP_RETVALUE == 4)
STAP_ERROR("wrong guess: %d", (int) STAP_RETVALUE);
if (STAP_RETVALUE == 3)
STAP_RETURN(0);
STAP_RETVALUE ++;
%}
function string_ops (val) %{
strlcpy (STAP_RETVALUE, STAP_ARG_val, MAXSTRINGLEN);
strlcat (STAP_RETVALUE, "one", MAXSTRINGLEN);
if (strcmp (STAP_RETVALUE, "three-two-one"))
STAP_RETURN("parameter should be three-two-");
%}
function no_ops () %{
STAP_RETURN(); /* function inferred with no return value */
%}
برای اینکه این کار کند، انواع آرگومانهای تابع و مقدار بازگشتی باید توسط مترجم از محلهای فراخوانی استنتاج شوند. کاربر باید کد C تولیدشده برای توابع عادی زبان اسکریپت را بررسی کند تا بتواند توابع C جاسازیشده سازگار را بنویسد.
آخرین جایی که کد جاسازیشده در آن مجاز است، به عنوان مقدار سمت راست (rvalue) یک عبارت است. در این حالت، کد C محصور بین نشانگرهای %{ و %} به عنوان یک مقدار عبارت عادی تفسیر میشود. فرض بر این است که این یک عدد ۶۴ بیتی علامتدار عادی است، مگر اینکه نشانگر /* string */ گنجانده شده باشد که در این صورت با آن به عنوان یک رشته رفتار میشود.
function add_one (val) {
return val + %{ 1 %}
}
function add_string_two (val) {
return val . %{ /* string */ "two" %}
}
@define SOME_STAP_MACRO %( %{ SOME_C_MACRO %} %)
probe begin {
printf("SOME_C_MACRO has value: %d\n", @SOME_STAP_MACRO);
}
کد C جاسازیشده ممکن است حاوی نشانگرهایی برای اثبات ویژگیهای بهینهسازی و ایمنی باشد:
- /* pure */
- بدین معناست که کد C هیچ اثر جانبی ندارد و در صورتی که مقدار آن توسط کد اسکریپت استفاده نشود، ممکن است به طور کامل حذف شود.
- /* stable */
- بدین معناست که کد C همیشه دارای مقدار یکسانی است (در هر فراخوانی مشخص از گرداننده کاوشگر)، بنابراین فراخوانیهای مکرر ممکن است به طور خودکار با مقادیر ذخیرهشده (memoized) جایگزین شوند. چنین توابعی نباید پارامتری دریافت کنند و همچنین باید pure باشند.
- /* unprivileged */
- بدین معناست که کد C چنان ایمن است که حتی کاربران غیرممتاز نیز مجاز به استفاده از آن هستند.
- /* myproc-unprivileged */
- بدین معناست که کد C چنان ایمن است که حتی کاربران غیرممتاز نیز مجاز به استفاده از آن هستند، به شرطی که هدف کاوشگر فعلی در فرایند خود کاربر باشد.
- /* guru */
- بدین معناست که کد C چنان ناامن است که کاربر systemtap باید گزینه -g (حالت guru) را برای استفاده از آن مشخص کند. (تپستها مجاز هستند و فرض بر این است که آنها را به صورت ایمن فراخوانی میکنند.)
- /* unmangled */
- در یک تابع C جاسازیشده، به این معنی است که نحو دسترسی به آرگومان قدیمی (پیش از نسخه ۱.۸) باید در داخل تابع در دسترس باشد. از این رو، علاوه بر STAP_ARG_foo و STAP_RETVALUE میتوان به ترتیب از THIS->foo و THIS->__retvalue در داخل تابع استفاده کرد. این برای مهاجرت سریع کدهای نوشتهشده برای نسخه ۱.۷ و پیش از آن در SystemTap مفید است.
- /* pragma:suffix */
- انتشار کد C دربردارنده سطح فایل در نزدیکی انتهای فایل منبع C ماژول هسته حاصل.
- /* unmodified-fnargs */
- در یک تابع C جاسازیشده، بدین معناست که آرگومانهای تابع در داخل بدنه تابع اصلاح نمیشوند.
- /* string */
- فقط در عبارات C جاسازیشده، بدین معناست که عبارت دارای نوع const char * است و باید به عنوان یک مقدار رشتهای رفتار شود، نه مقدار عددی پیشفرض long.
به متغیرهای سراسری سطح اسکریپت میتوان در توابع و بلوکهای C جاسازیشده دسترسی داشت. برای خواندن یا نوشتن متغیر سراسری var ، ابتدا باید نشانگر /* pragma:read:var */ یا /* pragma:write:var */ در تابع یا بلوک C جاسازیشده قرار داده شود. این کار ماکروهای STAP_GLOBAL_GET_* و STAP_GLOBAL_SET_* را برای امکان خواندن و نوشتن فراهم میکند. برای مثال:
global var
global var2[100]
function increment() %{
/* pragma:read:var */ /* pragma:write:var */
/* pragma:read:var2 */ /* pragma:write:var2 */
STAP_GLOBAL_SET_var(STAP_GLOBAL_GET_var()+1); //var++
STAP_GLOBAL_SET_var2(1, 1, STAP_GLOBAL_GET_var2(1, 1)+1); //var2[1,1]++
%}
متغیرها را میتوان در هر دو توابع و عبارات C جاسازیشده خواند و تنظیم کرد. رشتههای بازگرداندهشده از کد C جاسازیشده به اشارهگرها کاهش مییابند. متغیرها همچنین باید در سطح اسکریپت اختصاص داده شوند تا امکان استنتاج نوع فراهم شود. انتساب نقشه مقدار نوشتهشده را برنمیگرداند، بنابراین زنجیرهسازی کار نمیکند.
توابع و ساختارهای توکار (BUILT-INS)
مجموعهای از نامهای مستعار نقاط کاوش توکار توسط اسکریپتهای نصبشده در دایرکتوری مشخصشده در صفحه راهنمای stappaths(7) ارائه شدهاند. توابع در صفحه راهنمای stapprobes(3stap) شرح داده شدهاند.
ارجاعزدایی (DEREFERENCING)
اعداد صحیح را میتوان با استفاده از عملگرهای @kderef() یا @uderef() از اشارهگرهای ذخیرهشده به عنوان متغیرهای عددی اسکریپت ارجاعزدایی کرد. عملگر @kderef() برای آدرسهای فضای هسته و @uderef() برای آدرسهای فضای کاربری استفاده میشود.
@kderef(SIZE, addr) @uderef(SIZE, addr)
این دستور addr را به عنوان یک آدرس هسته/کاربر تفسیر کرده و SIZE بایت را با شروع از آن آدرس میخواند. SIZE باید ۱، ۲، ۴ یا ۸ بایت باشد.
ثباتها (REGISTERS)
مقدار ذخیرهشده در یک ثبات را میتوان با استفاده از عملگرهای @kregister() یا @uregister() به دست آورد. عملگر @kregister() برای ثباتهای فضای هسته و @uregister() برای ثباتهای فضای کاربری استفاده میشود. ثبات مورد نظر با استفاده از شماره DWARF آن مشخص میشود.
@kregister(0) @uregister(5)
پردازش (PROCESSING)
مترجم گذر ۱ را با تجزیه اسکریپت ورودی دادهشده و تمام اسکریپتهای (فایلهای با نام *.stp) موجود در دایرکتوری تپست آغاز میکند. دایرکتوریهای فهرستشده با -I به ترتیب پردازش میشوند و هر یک در «حالت guru» پردازش میگردند. برای هر دایرکتوری، تعدادی زیردایرکتوری نیز جستجو میشوند. این زیردایرکتوریها از نسخه هسته انتخابشده (گزینه -R) مشتق میشوند تا به اسکریپتهای خاصتر نسخه هسته امکان دهند بر اسکریپتهای با عمومیت بیشتر اولویت پیدا کنند. برای مثال، برای یک نسخه هسته 2.6.12-23.FC3 الگوهای زیر به ترتیب جستجو میشوند: 2.6.12-23.FC3/*.stp، 2.6.12/*.stp، 2.6/*.stp، و در نهایت *.stp. توقف مترجم پس از گذر ۱ باعث چاپ درختهای تجزیه میشود.
در گذر ۲، مترجم اسکریپت ورودی را برای حل نمادها و نوعها تحلیل میکند. ارجاعات به متغیرها، توابع و نامهای مستعار کاوشگر که به طور داخلی حل نشدهاند، با جستجو در میان فایلهای اسکریپت تپست تجزیهشده برآورده میشوند. اگر هر فایل اسکریپت تپست به این دلیل انتخاب شود که یک نماد حلنشده را تعریف میکند، کل آن فایل به صف حل مترجم اضافه میشود. این فرایند تا زمانی که تمام نمادها حل شوند و زیرمجموعهای از فایلهای اسکریپت تپست انتخاب شوند تکرار میشود.
سپس، تمامی توضیحات نقاط کاوش در برابر تنوع گستردهای که توسط مترجم پشتیبانی میشود اعتبارسنجی میشوند. نقاط کاوشی که به مکانهای کد ارجاع میدهند («نقاط کاوش همگام») نیازمند نصب اطلاعات اشکالزدایی مناسب هسته هستند. در گردانندههای کاوشگر مرتبط، متغیرهای سمت هدف (که نام آنها با "$" شروع میشود) پیدا شده و مکانهای زمان اجرای آنها رمزگشایی میشود.
سپس، تمامی کاوشگرها و توابع برای فرصتهای بهینهسازی تحلیل میشوند تا متغیرها، عبارات و توابعی که هیچ ارزش مفیدی و هیچ اثر جانبی ندارند حذف شوند. فرض بر این است که توابع C جاسازیشده دارای اثرات جانبی هستند، مگر اینکه رشته جادویی /* pure */ را شامل شوند. از آنجا که این بهینهسازی میتواند خطاهای پنهان کد مانند عدم تطابق نوع یا متغیرهای زمینه $ نامعتبر را مخفی کند، گاهی اوقات ممکن است غیرفعال کردن بهینهسازیها با گزینه -u مفید باشد.
در نهایت، انواع تمامی متغیرها، توابع، پارامترها، آرایهها و شاخصها از زمینه (مقادیر متنی و عملگرها) استنتاج میشوند. توقف مترجم پس از گذر ۲ باعث میشود تمام کاوشگرها، توابع و متغیرها را به همراه تمام انواع استنتاجشده فهرست کند. هرگونه نوع ناسازگار یا حلنشده موجب بروز خطا میشود.
در گذر ۳، مترجم کد C را مینویسد که بیانگر اقدامات تمام فایلهای اسکریپت انتخابشده است، و یک Makefile برای ساخت آن در قالب یک شیء هسته ایجاد میکند. این فایلها در یک دایرکتوری موقت قرار میگیرند. توقف مترجم در این نقطه باعث چاپ محتوای فایل C میشود.
در گذر ۴، مترجم سیستم ساخت هسته لینوکس را فراخوانی میکند تا فایل شیء هسته واقعی را بسازد. این کار مستلزم اجرای make در دایرکتوری موقت است و نیازمند نصب سیستم ساخت ماژول هسته (سرآیندها، پیکربندی و Makefileها) در محل معمول /lib/modules/VERSION/build است. توقف مترجم پس از گذر ۴ آخرین فرصت قبل از اجرای شیء هسته است. این ممکن است در صورتی که بخواهید فایل را آرشیو کنید مفید باشد.
در گذر ۵، مترجم برنامه کمکی systemtap به نام staprun را برای شیء هسته دادهشده فراخوانی میکند. این برنامه ترتیبی میدهد تا ماژول بارگذاری شده و سپس با آن ارتباط برقرار کند و دادههای ردیابی را از هسته در فایلهای موقت کپی کند، تا زمانی که کاربر سیگنال وقفه ارسال کند. هرگونه خطای زمان اجرا که توسط گردانندههای کاوشگر با آن مواجه شود، مانند کمبود حافظه، تقسیم بر صفر، فراتر رفتن از محدودیتهای تودرتویی یا زمان اجرا، منجر به یک نشانگر خطای نرم میشود. خطاهای نرم بیش از MAXERRORS تمام کاوشگرهای بعدی (به جز کاوشگرهای مدیریت خطا) را مسدود کرده و نشست را خاتمه میدهند. در نهایت، staprun ماژول را تخلیه کرده و پاکسازی را انجام میدهد.
خاتمه غیرعادی (ABNORMAL TERMINATION)
باید از کشتن اجباری فرایند stap، مثلاً با SIGKILL خودداری کرد، زیرا فرایند stapio (یک فرایند فرزند از فرایند stap) و ماژول بارگذاریشده ممکن است روی سیستم در حال اجرا باقی بمانند. اگر این اتفاق افتاد، SIGTERM یا SIGINT را به هر فرایند باقیمانده stapio ارسال کنید، سپس از rmmod برای تخلیه ماژول systemtap استفاده کنید.
مثالها (EXAMPLES)
برای مجموعهای مختصر از نمونهها به صفحه راهنمای stapex(3stap) مراجعه کنید، یا به مجموعه بزرگی از نمونههای نصبشده در دایرکتوریهای مستندات/مجموعه آزمون (testsuite) ابزار systemtap مراجعه نمایید. برای محل احتمالی این موارد در سیستم به stappaths(7stap) مراجعه فرمایید.
حافظه موقت (CACHING)
مترجم systemtap خروجی گذر ۳ (کد C تولیدشده) و خروجی گذر ۴ (ماژول کامپایلشده هسته) را در صورت موفقیتآمیز بودن گذر ۴ کش میکند. اگر همان اسکریپت مجدداً با فرض برقراری همان شرایط (همان نسخه هسته، همان نسخه systemtap و غیره) ترجمه شود، از این خروجی کششده مجدداً استفاده میشود. فایلهای کششده در دایرکتوری $SYSTEMTAP_DIR/cache ذخیره میشوند. حافظه موقت را میتوان با قرار دادن فایل cache_mb_limit در دایرکتوری کش (نشاندادهشده در بالا) محدود کرد که فقط شامل یک عدد صحیح ASCII است که نشان میدهد حافظه موقت نباید از چند مگابایت (MiB) تجاوز کند. در صورت عدم وجود این فایل، یک پیشفرض با محدودیت ۲۵۶ مگابایت ایجاد میشود. این یک محدودیت «نرم» است به این معنا که اگر بازه پاکسازی کش سپری شده باشد، پس از افزودن یک ورودی جدید حافظه موقت پاکسازی خواهد شد، بنابراین کل حجم کش ممکن است موقتاً از این مقدار بیشتر شود. این بازه را میتوان با قرار دادن فایل cache_clean_interval_s در دایرکتوری کش مشخص کرد که فقط حاوی یک عدد صحیح ASCII به عنوان بازه زمانی به ثانیه است. در صورت نبود این فایل، یک پیشفرض با بازه ۳۰۰ ثانیه ایجاد خواهد شد.
ایمنی و امنیت (SAFETY AND SECURITY)
ابزار Systemtap ممکن است به عنوان یک ابزار مدیریتی قدرتمند استفاده شود. این ابزار میتواند ساختارهای داده داخلی هسته و اطلاعات بالقوه خصوصی کاربر را آشکار کند. (در حالت زمان اجرای dyninst اینگونه نیست، بخش زمانهای اجرای جایگزین (ALTERNATE RUNTIMES) را در ادامه ببینید.)
مترجم محدودیتهای ایمنی بسیاری را در طول کامپایل و موارد بیشتری را در طول زمان اجرا اعمال میکند. هدف آن اطمینان از این است که هیچ زیرروال گردانندهای نتواند برای مدت بسیار طولانی اجرا شود، حافظه بیپایان تخصیص دهد، عملیات ناامن انجام دهد، یا به طور ناخواسته با سیستم تداخل پیدا کند. استفاده از متغیرهای سراسری اسکریپت به طور خودکار به صورت مناسب با قفل خواندن/نوشتن محافظت میشود تا در برابر دستکاری توسط گردانندههای همزمان کاوشگر محافظت گردد. قفلها به گونهای گرفته میشوند که بخش دستکاری متغیر سراسری در گردانندههای کاوشگر به طور اتمیک اجرا شود (قفلها به صورت همه-یا-هیچ گرفته میشوند). بنبستها با مهلتهای زمانی تشخیص داده میشوند. از فلگ -t برای دریافت گزارشهای مربوط به رقابت بیش از حد قفل استفاده کنید. بنابراین آزمایش با اسکریپتها به طور کلی ایمن است. گزینه حالت guru یعنی -g به مدیران اجازه میدهد تا اکثر اقدامات ایمنی را دور بزنند، که این امر اجازه عملیات تهاجمی یا تغییر وضعیت، کد C جاسازیشده را میدهد و خطر اختلال را افزایش میدهد. به صورت پیشفرض، پیشگیری از اضافه بار (overload prevention) برای تمام ماژولها روشن است. اگر مایل به غیرفعال کردن پردازش اضافهبار هستید، از گزینه --suppress-time-limits استفاده کنید.
خطاهایی که در زمان اجرا شناسایی میشوند معمولاً منجر به خاموش شدن تمیز اسکریپت و یک پیام خطای گذر ۵ میشوند. گزینه --suppress-handler-errors به اسکریپتها اجازه میدهد تا خطاهای نرم را بدون خاموش شدن تحمل کنند.
مجوزها (PERMISSIONS)
برای زمان اجرای عادی ماژول هسته لینوکس، جهت اجرای اشیاء هستهای که systemtap میسازد، کاربر باید یکی از موارد زیر باشد:
- کاربر ریشه (root)؛
- عضوی از گروههای stapdev و stapusr ؛
- عضوی از گروههای stapsys و stapusr ؛ یا
- عضوی از گروه stapusr
کاربر ریشه یا کاربری که عضو هر دو گروه stapdev و stapusr است میتواند هر اسکریپت systemtap را بسازد و اجرا کند.
کاربری که عضو هر دو گروه stapsys و stapusr است تنها در شرایط زیر میتواند از ماژولهای از پیش ساختهشده استفاده کند:
- ماژول توسط یک امضاکننده معتمد امضا شده باشد. امضاکنندگان معتمد معمولاً سرورهای کامپایل systemtap هستند که در صورت مشخص شدن گزینه --privilege توسط کلاینت، ماژولها را امضا میکنند. برای اطلاعات بیشتر به صفحه راهنمای stap-server(8) مراجعه کنید.
- ماژول با استفاده از گزینههای --privilege=stapsys یا --privilege=stapusr ساخته شده باشد.
اعضای فقط گروه stapusr تنها تحت شرایط زیر میتوانند از ماژولهای از پیش ساختهشده استفاده کنند:
- •
- ماژول در دایرکتوری /lib/modules/VERSION/systemtap قرار داشته باشد. این دایرکتوری باید متعلق به کاربر root بوده و برای همگان قابل نوشتن نباشد.
یا
- ماژول توسط یک امضاکننده معتمد امضا شده باشد. امضاکنندگان معتمد معمولاً سرورهای کامپایل systemtap هستند که در صورت تعیین گزینه --privilege توسط کلاینت ماژولها را امضا میکنند. برای اطلاعات بیشتر به صفحه راهنمای stap-server(8) مراجعه کنید.
- ماژول با استفاده از گزینه --privilege=stapusr ساخته شده باشد.
ماژولهای هسته تولیدشده توسط برنامه stap توسط برنامه staprun اجرا میشوند. برنامه اخیر بخشی از بسته Systemtap است که به بارگذاری و تخلیه ماژول (اما فقط در منطقه سفید) و انتقال دادهها از هسته به کاربر اختصاص دارد. از آنجا که staprun هیچ بررسی امنیتی اضافی روی اشیاء هستهای که به آن داده میشود انجام نمیدهد، اضافه کردن کاربران غیرقابل اعتماد به گروههای stapdev یا stapusr توسط مدیر سیستم کاری غیرعاقلانه خواهد بود.
بوت امن (SECUREBOOT)
اگر در سیستم فعلی قابلیت SecureBoot در سفتافزار UEFI روشن باشد، تمام ماژولهای هسته باید امضا شوند. (برخی هستهها ممکن است اجازه دهند مدتها پس از بوت با یک توالی کلید مانند SysRq-X قابلیت SecureBoot غیرفعال شود، که امضای ماژولها را غیرضروری میکند.) دو روش برای امضای ماژول systemtap وجود دارد. سرور کامپایل systemtap میتواند ماژولها را با یک MOK (کلید مالک دستگاه) که با سیستم کلاینت مشترک است امضا کند. برای مثال:
stap --use-server=HOSTNAME:PORT -e 'SCRIPT' # اگر کلید mok مشترکی با فهرست کلیدهای mok سرور systemtap # و پایگاهداده mok کلاینت وجود نداشته باشد، کاربر توسط stap هدایت میشود تا دستور زیر را فراخوانی کند: sudo mokutil --import signing_key.x509 # سپس پس از راهاندازی مجدد سیستم: stap --use-server=HOSTNAME:PORT -e 'SCRIPT' # از سرور برای ساخت و امضای ماژول استفاده میکند و ماژول روی کلاینت اجرا خواهد شد
روش دیگر برای امضای ماژولها استفاده از گزینه --sign-module در stap است که از یک MOK در سیستم کلاینت بدون استفاده از سرور استفاده میکند. برای مثال:
stap --sign-module -e 'SCRIPT' # اگر کلید mok مربوط به systemtap در پایگاهداده mok سیستم وجود نداشته باشد # کاربر توسط stap هدایت میشود تا دستور زیر را فراخوانی کند: sudo mokutil --import /home/USER/.systemtap/ssl/server/moks/FINGERPRINT/signing_key.x509 # سپس پس از راهاندازی مجدد سیستم: stap --sign-module -e 'SCRIPT' # ماژول را امضا کرده و اجرا میکند
برای جزئیات بیشتر به صفحه ویکی زیر مراجعه کنید:
برخی از هستهها به systemtap اجازه نمیدهند حدس بزند که آیا امضای ماژول در حال اجرا است یا خیر. در چنین ماشینهایی، متغیر محیطی SYSTEMTAP_SIGN را هنگام اجرای stap روی هر مقداری تنظیم کنید.
محدودیتهای منابع (RESOURCE LIMITS)
بسیاری از محدودیتهای استفاده از منابع توسط ماکروها در کد C تولیدشده تنظیم میشوند. این موارد را میتوان با فلگهای -D لغو کرد. گزیدهای از این موارد به شرح زیر است:
- MAXNESTING
- حداکثر تعداد فراخوانیهای توابع تو در تو. پیشفرض با تحلیل اسکریپت تعیین میشود، همراه با ۱۰ شکاف جایزه که برای اسکریپتهای بازگشتی اضافه میشود.
- MAXSTRINGLEN
- حداکثر طول رشتهها، پیشفرض ۱۲۸.
- MAXTRYLOCK
- حداکثر تعداد تکرارها برای انتظار قفلها روی متغیرهای سراسری پیش از اعلام بنبست احتمالی و رد کردن کاوشگر، پیشفرض ۱۰۰۰.
- MAXACTION
- حداکثر تعداد دستورات برای اجرا در طول هر اصابت کاوشگر تکی (با وقفههای غیرفعال)، پیشفرض ۱۰۰۰. توجه داشته باشید که برای گردانندههای کاوشگر مستقیم و فاقد حلقه یا بازگشت، به دلیل بهینهسازی، این پارامتر ممکن است بیش از حد محافظهکارانه تفسیر شود.
- MAXACTION_INTERRUPTIBLE
- حداکثر تعداد دستورات برای اجرا در طول هر اصابت کاوشگر تکی که با وقفههای فعال اجرا میشود (مانند کاوشگرهای begin/end)، پیشفرض (MAXACTION * 10).
- MAXBACKTRACE
- حداکثر تعداد فریمهای پشته که توسط بازکننده پشته زمان اجرای stap پردازش میشوند، همانطور که توسط توابع backtrace در تپستهای [u]context-unwind.stp تولید میشود، پیشفرض ۲۰.
- MAXMAPENTRIES
- حداکثر تعداد ردیفها در هر آرایه سراسری منفرد، پیشفرض ۲۰۴۸. آرایههای جداگانه را میتوان در عوض با یک محدودیت بزرگتر یا کوچکتر اعلان کرد:
global big[10000],little[5]
یا با % مشخص کرد تا به طور خودکار بچرخند (جایگزینی ورودیهای قدیمی)، مانند
global big%
یا هر دو.
- MAPHASHBIAS
- تعداد توانهای ۲ برای اضافه یا کم کردن از اندازه طبیعی جدول درهمسازی پشتیبان هر آرایه انجمنی سراسری. پیشفرض 0 است. اعداد مثبت کوچک را برای به دست آوردن کارایی بیشتر به قیمت مصرف حافظه بیشتر امتحان کنید، زیرا این کار باید برخوردهای جدول درهمسازی را کاهش دهد. اعداد منفی کوچک را برای معاوضه معکوس امتحان کنید.
- MAXERRORS
- حداکثر تعداد خطاهای نرم پیش از خروج، پیشفرض 0، به این معنی که اولین خطا باعث خروج از اسکریپت میشود. توجه داشته باشید که با گزینه --suppress-handler-errors ، این محدودیت اعمال نمیشود.
- MAXSKIPPED
- حداکثر تعداد کاوشگرهای ردشده پیش از خروج، پیشفرض ۱۰۰. اجرای systemtap با حالت -t (زمانبندی) جزئیات بیشتری درباره کاوشگرهای ردشده ارائه میدهد. با تنظیم پیشفرض -DINTERRUPTIBLE=1، کاوشگرهایی که به دلیل ورود مجدد رد شدهاند در این محدودیت جمع نمیشوند. توجه داشته باشید که با گزینه --suppress-handler-errors ، این محدودیت اعمال نمیشود.
- MINSTACKSPACE
- حداقل بایتهای پشته هسته آزاد مورد نیاز برای اجرای یک گرداننده کاوشگر، پیشفرض ۱۰۲۴. این عدد باید برای نیازهای خود گرداننده کاوشگر، به علاوه یک حاشیه ایمنی، به اندازه کافی بزرگ باشد.
- MAXUPROBES
- حداکثر تعداد کاوشگرهای فضای کاربر (uprobes) مسلح همزمان، پیشفرض تا حدودی بزرگتر از تعداد نقاط کاوش فضای کاربر نامبرده در اسکریپت است. این استخر باید به طور بالقوه بزرگ باشد زیرا اشیاء مجزای uprobe (هر کدام حدود ۶۴ بایت) برای هر فرایند به ازای هر کاوشگر منطبق در سطح اسکریپت تخصیص داده میشوند.
- STP_MAXMEMORY
- حداکثر مقدار حافظه (به کیلوبایت) که ماژول systemtap باید استفاده کند، پیشفرض نامحدود است. اندازه حافظه شامل اندازه خود ماژول به علاوه هرگونه تخصیص اضافی است. این فقط تخصیصهای مستقیم توسط زمان اجرای systemtap را ردیابی میکند. این تخصیصهای غیرمستقیم (مانند موارد انجامشده توسط اجزای داخلی kprobes/uprobes و غیره) را ردیابی نمیکند.
- STP_OVERLOAD_THRESHOLD, STP_OVERLOAD_INTERVAL
- حداکثر تعداد چرخههای ماشین صرفشده در کاوشگرها روی هر پردازنده در بازه دادهشده، پیش از اینکه وضعیت اضافهبار اعلام شود و اسکریپت خاموش گردد. مقادیر پیشفرض ۵۰۰ میلیون و ۱ میلیارد هستند تا مصرف پردازنده اسکریپت stap را در حدود ۵۰٪ محدود کنند.
- STP_PROCFS_BUFSIZE
- اندازه بافرهای خواندن کاوشگر procfs (به بایت). مقدار پیشفرض برابر با MAXSTRINGLEN است. این مقدار را میتوان بر مبنای هر فایل procfs با استفاده از پارامتر کاوشگر خواندن procfs یعنی .maxsize(MAXSIZE) لغو کرد.
در اسکریپتهایی که شامل کاوشگرهایی در هر مسیر وقفه هستند، ممکن است این وقفهها در وسط گرداننده کاوشگر دیگری رخ دهند. در این حالت کاوشگر در گرداننده وقفه رد میشود تا از ورود مجدد جلوگیری شود. برای رفع این مشکل، stap را با گزینه -DINTERRUPTIBLE=0 اجرا کنید تا وقفهها در سرتاسر گرداننده کاوشگر ماسک شوند. این کار مقداری سربار اضافی به کاوشگرها اضافه میکند، اما ممکن است از ورود مجدد در موارد مشکلساز رایج جلوگیری کند. با این حال، کاوشگرها در گردانندههای NMI و در مسیر فراخوانی زمان اجرای stap ممکن است همچنان به دلیل ورود مجدد رد شوند.
در صورتی که پس از شروع اجرای کاوشگر مشکلی برای stap یا staprun پیش بیاید، میتوان هر دو فرایند کاربری را با ایمنی متوقف کرد و ماژول هسته کاوشگر فعال را با rmmod حذف نمود. هرگونه پیام ردیابی معلق ممکن است از دست برود.
کاربران غیرممتاز (UNPRIVILEGED USERS)
ابزار Systemtap ساختارهای داده داخلی هسته و اطلاعات بالقوه خصوصی کاربر را آشکار میسازد. به همین دلیل، استفاده از تمام قابلیتهای systemtap به کاربر ریشه (root) و کاربرانی که عضو گروههای stapdev و stapusr هستند محدود شده است.
با این حال، مجموعهای محدود از ویژگیهای systemtap میتواند در دسترس کاربران مورد اعتماد و غیرممتاز قرار گیرد. این کاربران تنها عضو گروه stapusr، یا عضو گروههای stapusr و stapsys هستند. این کاربران میتوانند ماژولهای systemtap را که توسط یک سرور کامپایل معتمد systemtap کامپایل و تأیید شدهاند، بارگذاری کنند. توضیحات گزینههای --privilege و --use-server را ببینید. برای اطلاعات درباره راهاندازی سرور کامپایل معتمد به فایل README.unprivileged در کد منبع systemtap مراجعه کنید.
محدودیتهای اعمالشده هنگام تعیین --privilege=stapsys به گونهای طراحی شدهاند که از اقدامات زیر توسط کاربران غیرممتاز جلوگیری کنند:
- •
- آسیب رساندن مخرب به سیستم.
محدودیتهای اعمالشده هنگام تعیین --privilege=stapusr به گونهای طراحی شدهاند که از اقدامات زیر توسط کاربران غیرممتاز جلوگیری کنند:
- آسیب رساندن مخرب به سیستم.
- دسترسی به اطلاعاتی که معمولاً در دسترس یک کاربر غیرممتاز نیست.
- مختل کردن کارایی فرایندهای متعلق به سایر کاربران سیستم. مقداری سربار برای کل سیستم به طور کلی اجتنابناپذیر است زیرا کاوشگرهای کاربر غیرممتاز در زمانهای مناسب فعال میشوند. آنچه میخواهیم از آن جلوگیری کنیم وقفه هدفمند در فرایندهای کاربر دیگر است که معمولاً توسط یک کاربر غیرممتاز امکانپذیر نیست.
محدودیتهای کاوشگر (PROBE RESTRICTIONS)
عضوی از گروههای stapusr و stapsys میتواند از تمام نقاط کاوش استفاده کند.
عضوی که فقط در گروه stapusr است میتواند تنها از کاوشگرهای زیر استفاده کند:
- begin, begin(n)
- end, end(n)
- error(n)
- never
- process.*، در جایی که فرایند هدف متعلق به خود کاربر باشد.
- timer.{jiffies,s,sec,ms,msec,us,usec,ns,nsec}(n)*
- timer.hz(n)
محدودیتهای زبان اسکریپت (SCRIPT LANGUAGE RESTRICTIONS)
ویژگیهای زبان اسکریپتنویسی زیر برای تمام کاربران غیرممتاز غیرقابل دسترس است:
- هر ویژگیای که توسط گزینه حالت گورو (-g) فعال شود.
- کد C جاسازیشده.
محدودیتهای زمان اجرا (RUNTIME RESTRICTIONS)
محدودیتهای زمان اجرای زیر برای تمام کاربران غیرممتاز اعمال میشود:
- •
- تنها کد زمان اجرای پیشفرض (گزینه -R را ببینید) میتواند استفاده شود.
محدودیتهای اضافی برای اعضای فقط گروه stapusr اعمال میشود:
- کاوش فرایندهای متعلق به سایر کاربران مجاز نیست.
- دسترسی به حافظه هسته (خواندن و نوشتن) مجاز نیست.
محدودیتهای گزینههای خط فرمان (COMMAND LINE OPTION RESTRICTIONS)
برخی از گزینههای خط فرمان دسترسی به ویژگیهایی را فراهم میکنند که نباید برای تمام کاربران غیرممتاز در دسترس باشد:
- گزینه -g نباید مشخص شود.
- گزینههای زیر نباید توسط کلاینت سرور کامپایل استفاده شوند:
-a, -B, -D, -I, -r, -R
محدودیتهای محیط (ENVIRONMENT RESTRICTIONS)
متغیرهای محیطی زیر نباید برای تمام کاربران غیرممتاز تنظیم شوند:
SYSTEMTAP_RUNTIME SYSTEMTAP_TAPSET SYSTEMTAP_DEBUGINFO_PATH
محدودیتهای تَپست (TAPSET RESTRICTIONS)
به طور کلی، توابع تپست تنها زمانی برای اعضای گروه stapusr در دسترس هستند که اطلاعاتی را جمعآوری نکنند که یک برنامه عادی اجراشده با دسترسیهای آن کاربر از دسترسی به آنها محروم باشد.
دو دسته از توابع تپست غیرممتاز وجود دارد. دسته اول شامل توابع کاربردی است که بدون قید و شرط در دسترس همه کاربران قرار دارند؛ این موارد شامل چیزهایی مانند زیر است:
cpu:long () exit () str_replace:string (prnt_str:string, srch_str:string, rplc_str:string)
دسته دوم شامل توابع اصطلاحاً myproc-unprivileged است که تنها میتوانند اطلاعات درون فرایندهای خود کاربر را جمعآوری کنند. اسکریپتهایی که مایل به استفاده از این توابع هستند باید نتیجه تابع تپست is_myproc را آزمایش کنند و تنها در صورتی این توابع را فراخوانی کنند که نتیجه 1 باشد. اگر هر یک از این توابع توسط یک کاربر غیرممتاز درون یک کاوشگر در فرایندی که متعلق به آن کاربر نیست فراخوانی شود، اسکریپت بلافاصله خارج خواهد شد. نمونههایی از توابع myproc-unprivileged عبارتند از:
print_usyms (stk:string) user_int:long (addr:long) usymname:string (addr:long)
هنگامی که هر تابعی که در هیچیک از دستههای بالا قرار ندارد توسط اعضای فقط گروه stapusr استفاده شود، یک خطای کامپایل ایجاد میشود.
هیچ تابع تپست توکار دیگری نباید توسط اعضای فقط گروه stapusr استفاده شود.
زمانهای اجرای جایگزین (ALTERNATE RUNTIMES)
همانطور که در بالا شرح داده شد، حالت زمان اجرای پیشفرض systemtap شامل ساخت و بارگذاری ماژولهای هسته است که ملاحظات امنیتی مختلفی را به همراه دارد. Systemtap اکنون شامل دو پیشزمینه (backend) نمونه اولیه جدید است: --runtime=dyninst و --runtime=bpf.
گزینه --runtime=dyninst از Dyninst برای ابزار دقیق کردن فرایندهای خود کاربر در زمان اجرا استفاده میکند. این پیشزمینه از ماژولهای هسته استفاده نمیکند و نیازی به مجوزهای ریشه ندارد، اما نسبت به انواع کاوشگرها و سایر ساختارهایی که یک اسکریپت میتواند استفاده کند محدود است. زمان اجرای dyninst در حالت اتصال به هدف عمل میکند، بنابراین نیازمند یک فرایند با -c COMMAND یا -x PID است. برای مثال:
stap --runtime=dyninst -c 'stap -V' -e 'probe process.function("main")
{ println("hi from dyninst!") }'
ممکن است غیرفعال کردن یک بررسی متداخل selinux با دستور زیر لازم باشد:
# setsebool allow_execstack 1
گزینه --runtime=bpf اسکریپت کاربر را بهجای ماژول هسته به برنامههای فیلتر بسته برکلی توسعهیافته (eBPF) کامپایل میکند. برنامههای eBPF توسط هسته از نظر ایمنی تأیید میشوند و توسط یک ماشین مجازی درون هسته اجرا میگردند. این زمان اجرا در مراحل اولیه توسعه است و در حال حاضر فاقد پشتیبانی از تعدادی از ویژگیهای موجود در زمان اجرای پیشفرض است. لطفاً برای اطلاعات بیشتر به صفحه راهنمای stapbpf(8) مراجعه فرمایید.
وضعیت خروج (EXIT STATUS)
مترجم systemtap معمولاً در صورتی که اسکریپت درخواستی با موفقیت تا گذر درخواستی پردازش و اجرا شده باشد با کد موفقیت 0 بازمیگردد. در غیر این صورت، خطاها ممکن است در stderr چاپ شوند و یک کد خرابی برگردانده شود. از -v یا -vp N برای افزایش سطح پرگویی (سراسری یا بر مبنای هر گذر) جهت شناسایی منبع مشکل استفاده کنید.
در حالت فهرستبندی (-l و -L)، پیامهای خطا معمولاً سرکوب میشوند. در صورتی که حداقل یک کاوشگر منطبق پیدا شود، کد موفقیت 0 برگردانده میشود.
اسکریپتی که در گذر ۵ اجرا میشود و با ^C / SIGINT متوقف میشود، موفقیتآمیز در نظر گرفته میشود.
منسوخشدگی (DEPRECATION)
با گذشت زمان، ممکن است برخی از ویژگیهای زبان اسکریپت و کتابخانه تپست دستخوش تغییرات ناسازگاری شوند، بهطوری که اسکریپت نوشتهشده برای نسخه قدیمی systemtap دیگر اجرا نشود. در این موارد، اجرای systemtap با فلگ --compatible VERSION و مشخص کردن آخرین نسخه کارآمد شناختهشده ممکن است کمک کند. اجرای systemtap با فلگ --check-version در صورتی که هرگونه عنصر بالقوه ناسازگار تجزیه شده باشد، یک هشدار صادر میکند. جزئیات تاریخی منسوخشدگی را میتوان در فایل NEWS یافت.
هدف از امکانات منسوخشدگی، بهبود تجربه اسکریپتهای نوشتهشده برای نسخههای جدیدتر systemtap است (با افزودن جایگزینهای بهتر و حذف گزینههای قدیمی متعارض یا نامرتب)، در حالی که همزمان به اسکریپتهای نوشتهشده برای نسخههای قدیمیتر systemtap اجازه میدهد به کار خود ادامه دهند. بنابراین منسوخشدگی به عنوان یک خدمت به کاربران (و یک زحمت برای توسعهدهندگان systemtap) در نظر گرفته شده است، نه برعکس.
لطفاً توجه داشته باشید که شناسههای دارای پیشوند خط زیرین (_) در تپست گاهی اوقات دستخوش چنان تغییراتی میشوند که حفظ سازگاری برای آنها حتی با سازوکارهای منسوخشدگی دشوار است. از اتکا به این موارد در اسکریپتهای خود خودداری کنید؛ در عوض ارتقای آنها را به وضعیت بدون خط زیرین پیشنهاد دهید.
فایلها (FILES)
- فایلهای مهم و مسیرهای متناظر آنها را میتوان در صفحه راهنمای
- stappaths(7) یافت.
همچنین ببینید (SEE ALSO)
stapprobes(3stap), function::*(3stap), probe::*(3stap), tapset::*(3stap), stappaths(7), staprun(8), stapdyn(8), systemtap(8), stapvars(3stap), stapex(3stap), stap-server(8), stap-prep(1), stapref(1), awk(1), gdb(1)
اشکالات (BUGS)
از پیوند Bugzilla در صفحه وب پروژه یا فهرست پستی ما استفاده کنید: http://sourceware.org/systemtap, <systemtap@sourceware.org>.
error::reporting(7stap), https://sourceware.org/systemtap/wiki/HowToReportBugs