Java / Android - 전체 스택 트레이스를 인쇄하는 방법
Android(Java)에서 전체 스택 트레이스를 인쇄하려면 어떻게 해야 합니까?응용 프로그램이 null Pointer에서 크래시하는 경우예외 같은 경우는 다음과 같이 (거의) 풀스택 트레이스를 출력합니다.
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());
하지만 이건 포인터만 출력하면...모든 스택 트레이스 요소를 인쇄하기 위해 반복해야 합니까?아니면 간단하게 출력할 수 있는 방법이 있을까요?
다음 사항이 효과적입니다.
Log.d("myapp", Log.getStackTraceString(new Exception()));
주의:...x more
는 스택 트레이스에서 정보를 절단하지 않습니다.
(이는 이 예외에 대한 스택트레이스의 나머지 부분이 이 예외에 의해 발생한 예외의 스택트레이스 하단에서 지정된 프레임 수와 일치함을 나타냅니다).
...또는 바꿔 말하면,x more
마지막과 함께x
첫 번째 예외의 행.
모든 로그 메서드의 덮어쓰기가 있습니다.(String tag, String msg, Throwable tr)
시그니처.
세 번째 파라미터로 예외를 전달하면 logcat의 완전한 스택트레이스가 표시됩니다.
Log.getStackTraceString(Throwable t)을 사용합니다.더 깊이 파고들면 더 긴 스택 트레이스를 얻을 수 있습니다.예를 들어 다음과 같습니다.
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에서 취득.
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()));
다음을 사용할 수 있습니다.
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();
}
다음과 같은 방법을 사용하여 앱 코드의 임의의 지점에서 스택 트레이스를 인쇄할 수도 있습니다.Thread.dumpStack()
자세한 내용은 링크를 참조하십시오.
완전한 stackTrace를 얻으려면 Throwable Object를 사용해야 합니다.
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
이제 던질 수 있고 던질 수 있는.getCause()를 반복하는 재귀 함수를 실행했습니다.
이는 모든 "throwable.getCause()"가 일부 행과 새 행을 반복하여 새로운 예외 메시지를 반환하기 때문입니다.즉, '원인'이 있을 경우 'n more'와 같은 행이 있습니다."n more..."가 붙은 줄 앞에 마지막 줄을 붙일게요.그 후 원인 메시지가 표시되고 마지막으로 원인 메시지가 표시되는 것은 마지막 반복 행 뒤의 부분뿐입니다(두 행에 모두 표시되는 마지막 행: 주요 투척 가능과 투척 가능).
그 후 원인 메시지를 받았을 때 재귀를 사용하기 때문에 동일한 함수를 호출하여 메인 슬로우 가능에서 원인 메시지를 가져오면 이미 교체된 메시지가 나타납니다.메인 슬로우 가능의 원인에도 다른 원인이 있어 메인 슬로우 가능에는 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레벨(메인->원인)만으로 시도했고, 그 이상으로는 시도하지 않았습니다:/ 잘못된 것이 있으면 함수를 편집하여 코멘트를 써주세요.d
좋은 코딩과 좋은 하루 되세요:d
중요:
이 코드는 "st"에 "\n" 또는 유사한 항목이 포함되지 않은 경우 예외가 발생할 수 있습니다(스택트레이스의 일부 예외에 문제가 있음을 발견했습니다).이 문제를 해결하려면 코드 행 앞에 "String r1 = ..." 검사를 추가해야 합니다.
"st"에 "\n"이 포함되어 있고 "st.subSequence"의 시작 인덱스와 끝 인덱스가 모두 유효한지 확인해야 합니다.
어쨌든, 이것을 트라이 캐치에 넣고, 예외의 경우는 빈 문자열을 반환하는 것을 추천합니다.(반환된 빈 문자열은 이전 처리 문자열에 연결되도록 재귀적입니다).
kotlin 안드로이드 사용자의 경우, kotlin에 의해 던질 수 있는 클래스에 내장된 스택 메시지 전체를 루프하기 위한 확장 기능을 만들 필요가 없습니다.
이것은 kotlin v > 1.4의 후드 아래에 있는 것입니다.
@SinceKotlin("1.4")
public actual fun Throwable.stackTraceToString(): String {
val sw = StringWriter()
val pw = PrintWriter(sw)
printStackTrace(pw)
pw.flush()
return sw.toString()
}
사용방법:
Log.d("ERROR_STACKTRACE","${t.stackTraceToString()}") // 't' is the throwable obj
언급URL : https://stackoverflow.com/questions/7841232/java-android-how-to-print-out-a-full-stack-trace
'programing' 카테고리의 다른 글
일반 Python 목록에 비해 NumPy의 장점은 무엇입니까? (0) | 2022.10.06 |
---|---|
두 좌표 사이의 거리를 계산하는 함수 (0) | 2022.10.06 |
PHP 객체 vs 어레이 -- 반복 시 성능 비교 (0) | 2022.10.06 |
64비트 OS에서 32비트 JVM의 최대 Java 힙 크기 (0) | 2022.10.06 |
생성 시 및 업데이트 시 MySQL CURRENT_TIMESTamp (0) | 2022.10.06 |