का एक स्टैक ट्रेस प्राप्त करें मेरे पास एक स्क्रिप्ट है जो हर रात एक क्रॉन नौकरी से चलती है। हाल ही में, यह स्क्रिप्ट में कई मिनटों के बाद पूरी तरह से ठंडा हो गया है, और मैं यह नहीं समझ सकता कि क्यों। यदि यह जावा था, तो मैं बस kill -3 PID
चला सकता था और यह stdout में थ्रेड डंप मुद्रित करेगा। क्या PHP में कोई समकक्ष है, जहां मैं चल रहे PHP स्क्रिप्ट पर वर्तमान स्टैक ट्रेस (और आदर्श मेमोरी जानकारी) का डंप प्राप्त कर सकता हूं?एक लटका PHP स्क्रिप्ट
उत्तर
सबसे अच्छी बात यह है कि आप configure
के दौरान स्वयं PHP को संकलित कर सकते हैं।
$ gdb -p $PHP_PID
(gdb) bt # Get a system-level stacktrace, might already give some info
(gdb) source /path/to/php-src/.gdbinit # Load some useful macros
(gdb) dump_bt executor_globals.current_execute_data
# Macro from PHP's .gbinit giving PHP stack trace
# If you for whatever reason are using a thread-safe PHP build you have to do this:
(gdb) ____executor_globals
(gdb) dump_bt $eg.current_execute_data
और फिर डिबग आगे :-)
नोट इस आपके पास काम करने के लिए है कि: प्रक्रिया तो अभी भी लटकी हुई है तो आप इन चरणों का उपयोग कर एक PHP स्तरीय स्टैकट्रेस पाने के लिए gdb और कुछ मैक्रो का उपयोग कर सकते हैं प्रतीक जानकारी के साथ एक PHP बाइनरी रखने के लिए, --enable-debug
यह सुनिश्चित करता है कि।
हाय। क्या PHP चर के मौजूदा मानों को उसी तरह मुद्रित करना संभव है? – shark555
मेरे सिर के शीर्ष से: dump_ht execor_globals.active_symbol_table (उपयोग करने के लिए चर के नाम को सत्यापित करने के लिए: lxr.php.net या अपने स्थानीय PHP स्रोत पेड़ पर जाएं और execor_globals परिभाषा की जांच करें) – johannes
मैं pthreads एक्सटेंशन का उपयोग कर रहा हूं (php multithreading) और इसके लिए काम करने के लिए मुझे सबसे पहले सेट_ट्स (अन्यथा ____executor_globals क्रैश) का उपयोग करना था, 'tsrm_ls' तर्क मान स्टैक फ्रेम में दिखाई देने वाले – 2072
हां। आप debug_backtrace
के साथ बैकट्रैक प्राप्त कर सकते हैं। इसके अलावा आपको memory_get_usage
की आवश्यकता हो सकती है।
मेरी समस्या यह है कि मुझे नहीं पता कि यह कहां लटक रहा है। अगर मैंने किया, तो यह आसान समाधान होगा। –
एक PHP स्क्रिप्ट को टाइमटाउट होना चाहिए यदि यह अधिकतम रनटाइम से अधिक हो। निश्चित रूप से यह आपके लिए समस्या का समाधान करेगा; बस इसे तोड़ने के लिए प्रतीक्षा करें, और आपका स्टैक ट्रेस है।
मुझे लगता है कि यह संभव है कि आपके पास आपके कोड (या php.ini) में कुछ है जो इसे तोड़ने से रोकने के लिए अधिकतम रनटाइम शून्य पर सेट करता है। यदि आपको वह मिल गया है, तो इससे छुटकारा पाएं (या डिफ़ॉल्ट रूप से बहुत छोटा होने पर इसे बहुत बड़े टाइमआउट पर सेट करें)।
आप इसे xDebug या इसी तरह के टूल के साथ चलाने का प्रयास भी कर सकते हैं, जो आपको एक प्रोफाइलर ट्रेस देगा जो आपको प्रोग्राम का कॉल पेड़ देगा, और आपको अपने आईडीई में कोड के माध्यम से कदम उठाने की अनुमति देगा, तो आप देख सकते हैं कि क्या हो रहा है; यदि वहां एक अनंत लूप है, तो आपको उससे बहुत जल्दी पहचानने में सक्षम होना चाहिए।
यह एक लंबी चल रही स्क्रिप्ट है। कुछ बार इसमें कई घंटे लग सकते हैं। मैं नियमित रूप से उस राशि के लिए टाइमआउट रीसेट करता हूं जो चल रहे फ़ंक्शन के लिए उचित है, लेकिन यह किसी भी तरह मेरी समस्या को नहीं पकड़ता है। –
मैंने देखा है कि pcntl_signal का उपयोग कर एक संभावित समाधान है। मैं इसे अपने आप प्रयास नहीं किया है, तो आप कुछ नमूना कोड यहाँ पा सकते हैं:
https://secure.phabricator.com/D7797
function __phutil_signal_handler__($signal_number) {
$e = new Exception();
$pid = getmypid();
// Some phabricator daemons may not be attached to a terminal.
Filesystem::writeFile(
sys_get_temp_dir().'/phabricator_backtrace_'.$pid,
$e->getTraceAsString());
}
if (function_exists('pcntl_signal')) {
pcntl_signal(SIGHUP, '__phutil_signal_handler__');
}
यह * काम * कर सकता है अगर आप '--debug नहीं जोड़ सकते कॉन्फ़िगर स्क्रिप्ट के लिए सक्षम 'ध्वज। लेकिन मुझे नहीं लगता कि आप डिबगिंग के इस स्तर को कर रहे होंगे यदि आप कॉन्फ़िगरेशन ऑगमेंट्स के साथ भी नहीं खेल सके। –
बशर्ते आप PHP स्थापित के लिए gdb और डिबगिंग प्रतीकों है, तो आप एक पूर्ण पीएचपी पश्व-अनुरेखन मिल सकती है।
डिबगिंग प्रतीकों को स्थापित करने की विधि डिस्ट्रो से distro में भिन्न हो सकती है। उदाहरण के लिए अमेज़ॅन लिनक्स पर मैंने rpm -qa | grep php56-common
भाग लिया और परिणाम debuginfo-install
पर पास कर दिया। ध्यान दें कि मानक पैकेज मैनेजर का उपयोग कर डिबगिंग प्रतीकों को स्थापित करने से वांछित परिणाम नहीं मिल सकते हैं - अमेज़ॅन लिनक्स पर मुझे yum install php56-debuginfo
चलाते समय PHP के एक अलग संस्करण के लिए डीबगिंग प्रतीक मिल गए और gdb को यह पसंद नहीं आया।
यदि आपके पास है तो आपको बैकट्रैक प्राप्त करने के लिए चलने की प्रक्रिया की भी आवश्यकता नहीं है। आप kill -ABRT $pid
कर सकते हैं और बाद में कोर डंप का निरीक्षण कर सकते हैं।
फिर आप gdb -p $pid
या gdb /usr/bin/php $path_to_core_dump
के साथ कोर डंप के साथ चल रहे प्रक्रिया को डीबग करना प्रारंभ कर सकते हैं।
टाइपिंग bt
आपको एक सी स्टैक ट्रेस देगा। यह कभी-कभी आपको गलत होने का संकेत देने के लिए पर्याप्त होगा। सुनिश्चित करें कि डीबगिंग प्रतीक सही ढंग से स्थापित हैं; bt
को PHP स्रोत कोड में फ़ाइल नाम और रेखा संख्याओं पर इंगित करना चाहिए।
अब p executor_globals.current_execute_data
आज़माएं। इसे $1 = (struct _zend_execute_data *) 0x7f3a9bcb12d0
जैसे कुछ प्रिंट करना चाहिए। यदि ऐसा है, तो इसका मतलब है कि जीडीबी PHP के आंतरिक जांच कर सकता है।
थोड़ा पायथन स्क्रीप्टिंग का उपयोग करके आप एक पूर्ण PHP बैकट्रैक उत्पन्न कर सकते हैं। python-interactive
लिखें और फिर इस छोटे से स्क्रिप्ट सम्मिलित करें:
def bt(o):
if o == 0: return
print "%s:%d" % (o["op_array"]["filename"].string(), o["opline"]["lineno"])
bt(o["prev_execute_data"])
bt(gdb.parse_and_eval("executor_globals.current_execute_data"))
ध्यान दें कि यह विधि पीएचपी के आंतरिक भागों पर निर्भर है, तो यह पहले या बाद के संस्करणों पर काम न करे। मैंने php 5.6.14 के साथ ऐसा किया। इस विधि का लाभ यह है कि यह दोनों चल रही प्रक्रियाओं और कोर डंप दोनों के लिए काम करता है, साथ ही आपको PHP को पुन: संकलित करने या अपनी PHP स्क्रिप्ट को पुनरारंभ करने की आवश्यकता नहीं है। के बाद आप gdb और डिबगिंग प्रतीकों को इंस्टॉल भी कर सकते हैं, आपको एक लटकती प्रक्रिया मिलती है।
- 1. sys.stdin.readlines() लटका हुआ अजगर स्क्रिप्ट
- 2. एक php स्क्रिप्ट
- 3. एक PHP स्क्रिप्ट
- 4. एक php स्क्रिप्ट
- 5. एक PHP स्क्रिप्ट
- 6. PHP/अजाक्स/jQuery - एक php स्क्रिप्ट
- 7. मैं एक PHP स्क्रिप्ट पृष्ठभूमि
- 8. php स्क्रिप्ट
- 9. PHP स्क्रिप्ट
- 10. php स्क्रिप्ट
- 11. PHP स्क्रिप्ट
- 12. अजगर popen()। Stdout.read() लटका
- 13. एक PHP स्क्रिप्ट एक बार हर मिनट
- 14. PHP स्क्रिप्ट
- 15. PHP स्क्रिप्ट
- 16. PHP स्क्रिप्ट
- 17. PHP स्क्रिप्ट
- 18. PHP स्क्रिप्ट से पायथन स्क्रिप्ट
- 19. एक लटका बाल प्रक्रिया को मारें
- 20. एक सतत PHP स्क्रिप्ट कैसे चलाना है?
- 21. SWFUpload एक ही PHP स्क्रिप्ट निष्पादन
- 22. एक बैश/PHP स्क्रिप्ट से दूसरे
- 23. देखें कि कर्ल एक PHP स्क्रिप्ट
- 24. कैसे एक PHP स्क्रिप्ट को तोड़ते
- 25. सर्वर साइड स्क्रिप्ट (PHP)
- 26. प्रत्येक PHP स्क्रिप्ट से पहले php स्क्रिप्ट निष्पादित करें?
- 27. PHP टेक्स्ट diff स्क्रिप्ट
- 28. PHP लॉगिन स्क्रिप्ट
- 29. अपरिभाषित सूचकांक: PHP स्क्रिप्ट
- 30. कमांड लाइन स्क्रिप्ट php
सरल समाधान, अपने कोड में कुछ लॉगिंग स्टेटमेंट फेंकें और देखें कि निष्पादन में वे कहां रुकते हैं। – Sammitch