জাভা / অ্যান্ড্রয়েড - একটি সম্পূর্ণ স্ট্যাক ট্রেস কীভাবে মুদ্রণ করবেন?


124

অ্যান্ড্রয়েডে (জাভা) আমি কীভাবে একটি সম্পূর্ণ স্ট্যাক ট্রেস মুদ্রণ করব? যদি আমার অ্যাপ্লিকেশনটি নালপয়েন্টার এক্সসেপশন বা অন্য কোনও কিছু থেকে ক্র্যাশ হয়ে যায় তবে এটি এর মতো একটি (প্রায়) পূর্ণ স্ট্যাক ট্রেস প্রিন্ট করে:

java.io.IOException: Attempted read from closed stream.
com.android.music.sync.common.SoftSyncException: java.io.IOException: Attempted read from closed stream.
    at com.android.music.sync.google.MusicSyncAdapter.getChangesFromServerAsDom(MusicSyncAdapter.java:545)
    at com.android.music.sync.google.MusicSyncAdapter.fetchDataFromServer(MusicSyncAdapter.java:488)
    at com.android.music.sync.common.AbstractSyncAdapter.download(AbstractSyncAdapter.java:417)
    at com.android.music.sync.common.AbstractSyncAdapter.innerPerformSync(AbstractSyncAdapter.java:313)
    at com.android.music.sync.common.AbstractSyncAdapter.onPerformLoggedSync(AbstractSyncAdapter.java:243)
    at com.google.android.common.LoggingThreadedSyncAdapter.onPerformSync(LoggingThreadedSyncAdapter.java:33)
    at android.content.AbstractThreadedSyncAdapter$SyncThread.run(AbstractThreadedSyncAdapter.java:164)
Caused by: java.io.IOException: Attempted read from closed stream.
    at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:148)
    at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:159)
    at java.util.zip.GZIPInputStream.readFully(GZIPInputStream.java:212)
    at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:81)
    at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:64)
    at android.net.http.AndroidHttpClient.getUngzippedContent(AndroidHttpClient.java:218)
    at com.android.music.sync.api.MusicApiClientImpl.createAndExecuteMethod(MusicApiClientImpl.java:312)
    at com.android.music.sync.api.MusicApiClientImpl.getItems(MusicApiClientImpl.java:588)
    at com.android.music.sync.api.MusicApiClientImpl.getTracks(MusicApiClientImpl.java:638)
    at com.android.music.sync.google.MusicSyncAdapter.getChangesFromServerAsDom(MusicSyncAdapter.java:512)
    ... 6 more

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

StackTraceElement trace = new Exception().getStackTrace();
Log.d("myapp", trace.toString());

তবে এটি কেবলমাত্র বস্তুটির পয়েন্টারটি প্রিন্ট করে ... আমার কি সমস্ত স্ট্যাক ট্রেস উপাদানগুলি মুদ্রণের জন্য পুনরাবৃত্তি করতে হবে? বা এগুলি ছাপানোর কোনও সহজ পদ্ধতি আছে?


1
আপনি এই পদ্ধতি Thread.currentThread () ব্যবহার করতে পারেন getStackTrace ()। Stackoverflow.com/questions/1069066/...
user2024270

উত্তর:


119

স্বাক্ষর সহ সমস্ত লগ পদ্ধতির ওভাররাইড রয়েছে (String tag, String msg, Throwable tr)

তৃতীয় প্যারামিটার হিসাবে একটি ব্যতিক্রম পাস করার জন্য আপনাকে লগক্যাটটিতে পুরো স্ট্যাকট্রেস দেওয়া উচিত।


5
এফওয়াইআই, তিন-যুক্তিযুক্ত লগ পদ্ধতিগুলি getStackTraceString()পর্দার আড়ালে @ থমাস দ্বারা উল্লিখিত পদ্ধতিটি ব্যবহার করে ।
ফিলিপ রেচার্ট

6
আমি দু'বছর ধরে অ্যান্ড্রয়েড বিকাশ করেছি এবং এর আগে এর আগে কখনও লক্ষ্য করেছি না। আপনাকে অনেক ধন্যবাদ.
আনহ তুয়ান

উত্স কোডটির দিকে তাকিয়ে, আপনি ঠিক @ ফিলিপ রিচার্ট। এখানে কোড এর Log.d AOSP 4.2.2_r1 উপর
Ehtesh চৌধুরী

152

নিম্নলিখিতটি কৌশলটি করা উচিত:

Log.d("myapp", Log.getStackTraceString(new Exception()));

মনে রাখবেন ...x moreশেষে স্ট্যাক ট্রেস থেকে কোনও তথ্য কেটে দেয় না:

(এটি ইঙ্গিত করে) যে এই ব্যতিক্রমটির জন্য স্ট্যাক ট্রেসের অবশিষ্ট অংশটি ব্যতিক্রমের স্ট্যাক ট্রেসের নীচে থেকে ফ্রেমের সংখ্যার সাথে মেলে যা এই ব্যতিক্রমের কারণে ঘটেছিল ("সংলগ্ন" ব্যতিক্রম)।

... বা অন্য কথায়, প্রথম ব্যতিক্রম থেকে x moreশেষ xলাইনগুলির সাথে প্রতিস্থাপন করুন ।


1
কোথা getStackTraceString()থেকে এসেছে? Eclipse এ প্রদর্শিত হবে না? এটি Throwableবা এর অংশ নয় Exception...
জেক উইলসন

9
"... আরও 6" শেষে কোনও তথ্য কাটছে না। এটি আপনাকে বলছে, বাকি স্ট্যাকের ট্রেসটি একই রকম ছিল এটি শীর্ষ ব্যতিক্রমের জন্য ছিল। প্রথম ব্যতিক্রম থেকে কেবল শেষ 6 লাইনটি দেখুন।
টমাসজ

আপনার সম্ভবত লগিং লাইব্রেরি (ব্যবহার করে import android.util.Log;) আমদানি করতে হবে ।
ড্যান

10

লগ.জেটস্ট্যাকট্রেস স্ট্রিং (থ্রোয়েবল টি) ব্যবহার করুন। আরও গভীর খনন করে আপনি স্ট্যাকের দীর্ঘতর চিহ্নগুলি পেতে পারেন। উদাহরণ স্বরূপ:

try {
    ...
} catch(Exception e) {
    Log.d("Some tag", Log.getStackTraceString(e.getCause().getCause()));
}

থেকে পুনরুদ্ধার http://developer.android.com/reference/android/util/Log.html#getStackTraceString%28java.lang.Throwable%29


Log.getStackTraceString()স্ট্যাক ট্রেস লগ করে না এটি স্ট্রিং হিসাবে এটি ফিরে আসে। উপরের কোড কিছু লগ ইন করুন করবে না এবং একটি NPE ব্যর্থ হয়ে যাবে e.getCause()হয় null
ফিলিপ রেচার্ট

9
private static String buildStackTraceString(final StackTraceElement[] elements) {
    StringBuilder sb = new StringBuilder();
    if (elements != null && elements.length > 0) {
        for (StackTraceElement element : elements) {
            sb.append(element.toString());
        }
    }
    return sb.toString();
}


// call this at your check point
Log.d(TAG, buildStackTraceString(Thread.currentThread().getStackTrace()));

6

আপনি এটি ব্যবহার করতে পারেন:

public static String toString(StackTraceElement[] stackTraceElements) {
    if (stackTraceElements == null)
        return "";
    StringBuilder stringBuilder = new StringBuilder();
    for (StackTraceElement element : stackTraceElements)
        stringBuilder.append(element.toString()).append("\n");
    return stringBuilder.toString();
}

4

আপনি আপনার অ্যাপ্লিকেশন কোডের যে কোনও সময়ে যেমন পদ্ধতি ব্যবহার করে একটি স্ট্যাক ট্রেস মুদ্রণ করতে পারেন Thread.dumpStack()

আরও বিশদ জন্য লিংক মাধ্যমে যান


2

পূর্ণ স্ট্যাকট্রেস পেতে আপনার থ্রোয়েবল অবজেক্ট ব্যবহার করা উচিত।

try{
 // code here
}catch(Exception e){
    String exception = getStackTrace(e);
}

public static String getStackTrace(final Throwable throwable) {
     final StringWriter sw = new StringWriter();
     final PrintWriter pw = new PrintWriter(sw, true);
     throwable.printStackTrace(pw);
     return sw.getBuffer().toString();
}

রেফ: https://stackoverflow.com/a/18546861


0

আমি দ্রুত এখন একটি পুনরাবৃত্ত ফাংশন করেছিলাম যা নিক্ষেপযোগ্য এবং ছোঁড়া যায় get

কারণ প্রতিটি "থ্রোয়েবল.জেটকজ ()" আপনাকে কিছু লাইন পুনরাবৃত্তি করে এবং নতুন লাইনের সাথে একটি নতুন ব্যতিক্রম বার্তা দেয়। সুতরাং ধারণাটিটি হ'ল: যদি "কারণ" থাকে তবে মূল নিক্ষিপ্ত "এন আরও .." এর সাথে একটি লাইন থাকে তাই আমি "এন আরও .." দিয়ে একটির আগে শেষ লাইনটি পাই তবে আমি কারণ বার্তাটি পাই এবং অবশেষে আমি কারণ বার্তাটি সর্বশেষ পুনরাবৃত্ত লাইনের পরে অংশটি পেয়েছি (শেষ পংক্তি যা উভয়ের উপরে প্রদর্শিত: মূল নিক্ষেপযোগ্য এবং কারণ ছোঁড়া যায়)।

তারপরে আমি কারণ বার্তাটি পেলে পুনরাবৃত্তিটি ব্যবহার করি, সুতরাং মূল থ্রোবেল থেকে কারণ বার্তাটি পেতে একই ফাংশনটিকে পুনরায় কল করাতে আমি ইতিমধ্যে প্রতিস্থাপিত বার্তাটি পেয়ে যাব। যদি মূল নিক্ষেপযোগ্য থেকে ফেলে দেওয়ার কারণটিরও অন্য কারণ থাকে, তবে মূল নিক্ষেপযোগ্যটির 3 টি স্তর থাকে (মূল -> কারণ -> কারণ-কারণ), তবে প্রথম প্রধান স্থানে আমি "কারণ বার্তা" পেয়ে যাব ইতিমধ্যে প্রতিস্থাপিত একটি বার্তা (মূল একই ধারণা ব্যবহার করে

public static <T extends Throwable> String printStackTraceString(T ex) {     // Recursive
    Throwable tr = ex;
    if (tr != null) {
        String st = Log.getStackTraceString(tr);
        if (tr.getCause() != null) {
            // Recursion...
            String cs = printStackTraceString(tr.getCause());

            String r1 = st.subSequence(0x0, st.lastIndexOf("\n", st.lastIndexOf("\n") - "\n".length())).toString();
            String replace = r1.substring(r1.lastIndexOf("\n"));
            if (cs.contains(replace)) {
                return r1.concat(cs.subSequence(cs.indexOf(replace) + replace.length(), cs.length()).toString());
            }
        }
        return st;
    }
    return "";
}

আমি এটি কেবলমাত্র 2 স্তরের (মূল -> কারণ) দিয়ে চেষ্টা করেছি এবং আরও কিছু নয়: / যদি কিছু ভুল হয় তবে দয়া করে ফাংশনটি সম্পাদনা করুন এবং একটি মন্তব্য লিখুন: ডি

একটি সুন্দর কোডিং এবং আপনার একটি সুন্দর দিন দিন: ডি

গুরুত্বপূর্ণ:

"কোড" "\ n" বা অনুরূপ না থাকলে এই কোডটি কখনও কখনও ব্যতিক্রম হয় (আমি দেখতে পেয়েছি কিছু ধরণের ব্যতিক্রম স্ট্যাকট্রেসগুলির এই সমস্যা রয়েছে)। এটি সমাধানের জন্য আপনাকে কোড সারিটির আগে কিছু পরীক্ষা করতে হবে: "স্ট্রিং আর 1 = ..."

আপনার যাচাই করা দরকার: "st" "" \ n "রয়েছে এবং" st.subSequence "এর সূচনা ও শেষ সূচি উভয়ই বৈধ।

যাইহোক আমি এটিকে চেষ্টা-ধরার ভিতরে রাখার এবং ব্যতিক্রমের ক্ষেত্রে খালি স্ট্রিংটি ফিরিয়ে দেওয়ার পরামর্শ দিই। (এটি পুনরাবৃত্ত হয় তাই প্রত্যাবর্তন করা খালি স্ট্রিংটি পূর্ববর্তী প্রক্রিয়াজাত স্ট্রিংয়ের সাথে সংযুক্ত করা হবে))

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.