জাভাতে ব্যতিক্রম না ছড়িয়ে কোনও স্ট্যাক ট্রেস ফেলে দেওয়ার কোনও উপায় আছে কি?


159

আমি আমার জাভা অ্যাপ্লিকেশনটির জন্য একটি ডিবাগ সরঞ্জাম তৈরি করার কথা ভাবছি।

আমি ভাবছি যদি স্ট্যাক ট্রেস পাওয়া সম্ভব, ঠিক তেমন Exception.printStackTrace()তবে আসলে ব্যতিক্রম না ছুঁড়ে দেওয়া?

আমার লক্ষ্য, কোনও প্রদত্ত পদ্ধতিতে, পদ্ধতি কলারটি কে তা দেখার জন্য একটি স্ট্যাক ফেলে দিন।

উত্তর:


84

আপনি Thread.getAllStackTraces()জীবিত সমস্ত থ্রেডের জন্য স্ট্যাকের চিহ্নগুলির একটি মানচিত্র পাওয়ার চেষ্টা করতে পারেন।


250

হ্যাঁ, সহজভাবে ব্যবহার করুন

Thread.dumpStack()

44
... কিন্তু ফেলে দেয় না
রব

5
এটি সেই উত্তর যা আসলে প্রশ্নের উত্তর দেয়।
ব্রুনো

7
খুব সাধারণ এবং মার্জিত। এটি গ্রহণযোগ্য উত্তর হওয়া উচিত ছিল।
ডিলক

11
Fwiw, এই পদ্ধতির উৎস: public static void dumpStack() { new Exception("Stack trace").printStackTrace(); }
JohnK

এটি যদি আপনি আউটপুট আউট দিয়ে খুশি হন তবে এটি প্রশ্নের উত্তরের উত্তর stderr, যা মনে হয় প্রশ্নের জড়িত বলে মনে হচ্ছে।
মাইকে রডেন্ট

46

আপনি যদি কেবলমাত্র বর্তমান থ্রেডের জন্য ট্রেস চান (সিস্টেমের সমস্ত থ্রেডের চেয়ে, রামের পরামর্শ অনুসারে), করুন:

Thread.currentThread ()। getStackTrace ()

কলার সন্ধান করতে, করুন:

private String getCallingMethodName() {
    StackTraceElement callingFrame = Thread.currentThread().getStackTrace()[4];
    return callingFrame.getMethodName();
}

এবং সেই পদ্ধতিটিকে সেই পদ্ধতির মধ্যে থেকেই কল করুন যার জন্য এটির আহ্বায়ক কে তা জানতে হবে। তবে, সতর্কতার একটি শব্দ: তালিকার মধ্যে কলিং ফ্রেমের সূচিটি জেভিএম অনুসারে পরিবর্তিত হতে পারে! এটি সমস্তই নির্ভর করে যে আপনি যে বিন্দুতে ট্রেস তৈরি করেছেন সেখানে আঘাত করার আগে getStackTrace এর মধ্যে কলগুলির কত স্তর রয়েছে on আরও শক্তিশালী সমাধান হ'ল ট্রেসটি পাওয়া এবং গেটকলিংথমেডনামের ফ্রেম সন্ধান করার জন্য এটি পুনরুক্ত করা, তারপরে সত্যিকারের কলার সন্ধানের জন্য আরও দুটি পদক্ষেপ নেওয়া।


2
সুতরাং আপনার নিজের উপর একটি নতুন ব্যতিক্রম তৈরি করুন এবং [1] সূচক হিসাবে ব্যবহার করুন!
ড্যানিয়েল

3
এই প্রশ্নের শিরোনামটি "একটি ব্যতিক্রম ছুঁড়ে না ফেলে" বলে। মঞ্জুর, আপনি ব্যতিক্রমটি তৈরি করার পরামর্শ দিচ্ছেন কিন্তু ছুঁড়ে ফেলছেন না, তবে আমি এখনও মনে করি এটি প্রশ্নের উদ্বেগের মধ্যে নেই।
টম অ্যান্ডারসন

1
অবশ্যই এটা. একটি ব্যতিক্রম তৈরি করা স্ট্যাকট্রেস পাওয়ার সবচেয়ে নিম্নতম উপায়। এমনকি আপনার থ্রেড.কন্ট্রেনথ্রেড () .স্টেটট্রেস () এটি করে তবে আমার উপায় এটি দ্রুত করে তোলে :)।
ড্যানিয়েল

@ ড্যানিয়েল এর আরও একটি বিবেচনা রয়েছে: অনেকগুলি পরীক্ষামূলক কাঠামোর সাথে, উদাহরণস্বরূপ স্পক, কেবল একটি ব্যতিক্রম তৈরি করা (এটি ছোঁড়া ছাড়াই) কাঠামোটি গ্রহণের জন্য যথেষ্ট হবে: পরীক্ষাটি তখন বিবেচনা করবে যে কোনও ব্যতিক্রম "ঘটেছে" এবং পরীক্ষাটি হবে শেষ, একটি ব্যর্থতা সঙ্গে।
মাইকে রডেন্ট

@ মিকেরোডেন্ট: আপনি কি নিশ্চিত? স্পোককে এজেন্ট ব্যবহার করতে হবে। তবে যাইহোক, কারণ আমার কেবল ক্লাস কল করার দরকার ছিল আমি একটি ইউটিলিটি ফাংশনে রিফ্লেকশন.জেটকলারক্লাস (2) ব্যবহার করেছি। আপনি ফাংশন এবং লাইন নম্বরটি সেভাবে পাবেন না, ভেবেছিলেন।
ড্যানিয়েল

37

আপনি এই জাতীয় স্ট্যাক ট্রেস পেতে পারেন:

Throwable t = new Throwable();
t.printStackTrace();

আপনি যদি ফ্রেমটি অ্যাক্সেস করতে চান তবে স্ট্যাক ফ্রেমের অ্যারে পেতে আপনি t.getStackTrace () ব্যবহার করতে পারেন।

হটস্পট সংকলক জিনিসগুলির অনুকূলকরণে ব্যস্ত থাকলে এই স্ট্যাকট্রেসটি (অন্যগুলির মতো) কিছু ফ্রেম অনুপস্থিত হতে পারে তা অবগত থাকুন।


আমি এই উত্তরটি পছন্দ করি কারণ এটি আমাকে আউটপুট পরিচালনার সুযোগ দেয়। আমি প্রতিস্থাপন করতে পারেন t.printStackTraceসঙ্গে t.printStackTrace(System.out)

4
এক লাইনে:new Throwable().printStackTrace(System.out);

1
এটি গ্রহণযোগ্য উত্তর হওয়া উচিত। এটি সহজ এবং সোজা এগিয়ে! ভাগ করে নেওয়ার জন্য ধন্যবাদ
স্যাম

2
এবং java.util.Loggerlog.log(Level.SEVERE, "Failed to do something", new Throwable());
মিচব্রোডহেডে


6

আপনি চলমান জাভা প্রক্রিয়াতে প্রসেসটিতে একটি কুইট সিগন্যাল প্রেরণ করে থ্রেড.জেটএলস্ট্যাকট্রেসেস () চালানোর জন্য আপনি জেভিএমকে সংকেত পাঠাতে পারেন।

ইউনিক্স / লিনাক্স ব্যবহারে:

kill -QUIT process_id, যেখানে প্রক্রিয়া_আইডি হ'ল আপনার জাভা প্রোগ্রামের প্রক্রিয়া নম্বর।

উইন্ডোজে আপনি অ্যাপ্লিকেশনটিতে Ctrl-Break টিপতে পারেন, যদিও আপনি কনসোল প্রক্রিয়া চালা না করে আপনি সাধারণত এটি দেখতে পাবেন না।

জেডি কে another আরও একটি বিকল্প চালু করেছে, জেস্ট্যাক কমান্ড, যা আপনার কম্পিউটারে চলমান জেডিকে process প্রক্রিয়া থেকে স্ট্যাকটি প্রদর্শন করবে:

jstack [-l] <pid>

এই বিকল্পগুলি অ্যাপ্লিকেশনগুলির জন্য খুব দরকারী যা একটি উত্পাদন পরিবেশে চলছে এবং সহজেই পরিবর্তন করা যায় না। রানটাইম ডেডলকগুলি বা পারফরম্যান্স সমস্যা নির্ণয়ের জন্য এগুলি বিশেষত কার্যকর।

http://java.sun.com/developer/technicalArticles/Programming/Stacktrace/ http://java.sun.com/javase/6/docs/technotes/tools/share/jstack.html



6

জাভা 9 StackWalkerস্ট্যাকটি হাঁটার জন্য এবং সহায়ক ক্লাসগুলি চালু করেছিল ।

জাভাডোকের কয়েকটি স্নিপেট এখানে রয়েছে:

walkপদ্ধতির একটি অনুক্রমিক প্রবাহ প্রর্দশিত StackFramesবর্তমান থ্রেড জন্য এবং তারপর হেঁটে যাওয়ার দেওয়া ফাংশন প্রযোজ্য StackFrameস্ট্রীম। স্ট্রিমটি স্ট্যাক ফ্রেম উপাদানগুলিকে যথাযথভাবে প্রতিবেদন করে, শীর্ষ সর্বাধিক ফ্রেম থেকে যা কার্যকরভাবে পয়েন্ট উপস্থাপন করে যেখানে স্ট্যাকটি নীচে সবচেয়ে ফ্রেমে তৈরি করা হয়েছিল। StackFrameওয়াক পদ্ধতিটি ফিরে আসার পরে স্ট্রিমটি বন্ধ হয়ে যায়। যদি বন্ধ স্ট্রিমটি পুনরায় ব্যবহার করার চেষ্টা করা হয় IllegalStateExceptionতবে ফেলে দেওয়া হবে।

...

  1. বর্তমান থ্রেডের শীর্ষ 10 স্ট্যাক ফ্রেমের স্ন্যাপশট করতে,

    List<StackFrame> stack = StackWalker.getInstance().walk(s ->
     s.limit(10).collect(Collectors.toList()));

0

এইচপিআরএফ জাভা প্রোফাইলার

আপনাকে কোডেও এটি করতে হবে না। আপনি নিজের প্রক্রিয়াটির সাথে জাভা এইচপিআরএফ সংযুক্ত করতে পারেন এবং যে কোনও মুহুর্তে হিপ ডাম্প আউটপুট, চলমান থ্রেড ইত্যাদিতে নিয়ন্ত্রণ- hit চাপুন hit । । আপনার অ্যাপ্লিকেশন কোড চূড়ান্ত না করে। এটি কিছুটা পুরানো, জাভা 6 জিইউআই জকনসোলের সাথে আসে তবে আমি এখনও এইচপিআরএফকে খুব দরকারী বলে মনে করি।


0

রব ডি মার্কো দ্বারা উত্তর দ্বারা পর্যন্ত সেরা যদি আপনি আউটপুট খুশি stderr

আপনি যদি Stringকোনও সাধারণ ট্রেস অনুসারে নতুন লাইনের সাথে একটিতে ক্যাপচার করতে চান তবে আপনি এটি করতে পারেন :

Arrays.toString(Thread.currentThread().getStackTrace()).replace( ',', '\n' );
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.