Skip to content

Commit a51a956

Browse files
author
Craig Mautner
committed
Add call-stack reporting methods into Debug
Added two public methods to Debug. These methods return a String indicating the caller (getCaller()) or callers (getCallers(int depth)) of the calling method. The String indicates the class, method and line number of the caller(s). Similar to using Throwable.fillInStackTrace() but much more concise. Change-Id: I53d0085aa50e4501d28e8eb3ad5b91ef700ac218
1 parent c843642 commit a51a956

File tree

4 files changed

+117
-34
lines changed

4 files changed

+117
-34
lines changed

core/java/android/os/Debug.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,4 +1324,42 @@ public static boolean dumpService(String name, FileDescriptor fd, String[] args)
13241324
return false;
13251325
}
13261326
}
1327+
1328+
/**
1329+
* Return a String describing the calling method and location at a particular stack depth.
1330+
* @param callStack the Thread stack
1331+
* @param depth the depth of stack to return information for.
1332+
* @return the String describing the caller at that depth.
1333+
*/
1334+
private static String getCaller(StackTraceElement callStack[], int depth) {
1335+
// callStack[4] is the caller of the method that called getCallers()
1336+
if (4 + depth >= callStack.length) {
1337+
return "<bottom of call stack>";
1338+
}
1339+
StackTraceElement caller = callStack[4 + depth];
1340+
return caller.getClassName() + "." + caller.getMethodName() + ":" + caller.getLineNumber();
1341+
}
1342+
1343+
/**
1344+
* Return a string consisting of methods and locations at multiple call stack levels.
1345+
* @param depth the number of levels to return, starting with the immediate caller.
1346+
* @return a string describing the call stack.
1347+
* {@hide}
1348+
*/
1349+
public static String getCallers(final int depth) {
1350+
final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
1351+
StringBuffer sb = new StringBuffer();
1352+
for (int i = 0; i < depth; i++) {
1353+
sb.append(getCaller(callStack, i)).append(" ");
1354+
}
1355+
return sb.toString();
1356+
}
1357+
1358+
/**
1359+
* @return a String describing the immediate caller of the calling function.
1360+
* {@hide}
1361+
*/
1362+
public static String getCaller() {
1363+
return getCaller(Thread.currentThread().getStackTrace(), 0);
1364+
}
13271365
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright (C) 2012 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.android.internal.os;
18+
19+
import android.os.Debug;
20+
21+
import android.test.suitebuilder.annotation.SmallTest;
22+
import junit.framework.TestCase;
23+
24+
@SmallTest
25+
public class DebugTest extends TestCase {
26+
27+
private final static String EXPECTED_GET_CALLER =
28+
"com\\.android\\.internal\\.os\\.DebugTest\\.testGetCaller:\\d\\d";
29+
private final static String EXPECTED_GET_CALLERS =
30+
"com\\.android\\.internal\\.os\\.DebugTest.callDepth3:\\d\\d " +
31+
"com\\.android\\.internal\\.os\\.DebugTest.callDepth2:\\d\\d " +
32+
"com\\.android\\.internal\\.os\\.DebugTest.callDepth1:\\d\\d ";
33+
34+
/**
35+
* @return String consisting of the caller to this method.
36+
*/
37+
private String callDepth0() {
38+
return Debug.getCaller();
39+
}
40+
41+
public void testGetCaller() {
42+
assertTrue(callDepth0().matches(EXPECTED_GET_CALLER));
43+
}
44+
45+
/**
46+
* @return String consisting of the callers to this method.
47+
*/
48+
private String callDepth4() {
49+
return Debug.getCallers(3);
50+
}
51+
52+
private String callDepth3() {
53+
return callDepth4();
54+
}
55+
56+
private String callDepth2() {
57+
return callDepth3();
58+
}
59+
60+
private String callDepth1() {
61+
return callDepth2();
62+
}
63+
64+
public void testGetCallers() {
65+
assertTrue(callDepth1().matches(EXPECTED_GET_CALLERS));
66+
}
67+
}

services/java/com/android/server/wm/WindowManagerService.java

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8129,7 +8129,7 @@ private final void performLayoutAndPlaceSurfacesLockedInner(
81298129
boolean recoveringMemory) {
81308130
if (DEBUG_WINDOW_TRACE) {
81318131
Slog.v(TAG, "performLayoutAndPlaceSurfacesLockedInner: entry. Called by "
8132-
+ getCallers(3));
8132+
+ Debug.getCallers(3));
81338133
}
81348134
if (mDisplay == null) {
81358135
Slog.i(TAG, "skipping performLayoutAndPlaceSurfacesLockedInner with no mDisplay");
@@ -9621,27 +9621,4 @@ void bulkSetParameters(final int bulkUpdateParams, int pendingLayoutChanges) {
96219621
mH.sendMessage(mH.obtainMessage(H.BULK_UPDATE_PARAMETERS, bulkUpdateParams,
96229622
pendingLayoutChanges));
96239623
}
9624-
9625-
/**
9626-
* Never call directly. Only call through getCallers(int) or getCaller(). Otherwise
9627-
* the depth will be off.
9628-
* @param depth What level stack to return.
9629-
* @return A String indicating who the caller of the method that calls this is.
9630-
*/
9631-
static String getCaller(int depth) {
9632-
StackTraceElement caller = Thread.currentThread().getStackTrace()[5 + depth];
9633-
return caller.getClassName() + "." + caller.getMethodName() + ":" + caller.getLineNumber();
9634-
}
9635-
9636-
static String getCallers(final int depth) {
9637-
StringBuffer sb = new StringBuffer();
9638-
for (int i = 0; i < depth; i++) {
9639-
sb.append(getCaller(i)).append(" ");
9640-
}
9641-
return sb.toString();
9642-
}
9643-
9644-
static String getCaller() {
9645-
return getCallers(1);
9646-
}
96479624
}

services/java/com/android/server/wm/WindowStateAnimator.java

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import android.graphics.PointF;
1616
import android.graphics.Rect;
1717
import android.graphics.Region;
18+
import android.os.Debug;
1819
import android.os.RemoteException;
1920
import android.util.Slog;
2021
import android.view.Surface;
@@ -421,7 +422,7 @@ public SurfaceTrace(SurfaceSession s,
421422
super(s, pid, display, w, h, format, flags);
422423
mSize = new Point(w, h);
423424
Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
424-
+ WindowManagerService.getCallers(3));
425+
+ Debug.getCallers(3));
425426
}
426427

427428
public SurfaceTrace(SurfaceSession s,
@@ -431,23 +432,23 @@ public SurfaceTrace(SurfaceSession s,
431432
mName = name;
432433
mSize = new Point(w, h);
433434
Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
434-
+ WindowManagerService.getCallers(3));
435+
+ Debug.getCallers(3));
435436
}
436437

437438
@Override
438439
public void setAlpha(float alpha) {
439440
super.setAlpha(alpha);
440441
mSurfaceTraceAlpha = alpha;
441442
Slog.v(SURFACE_TAG, "setAlpha: " + this + ". Called by "
442-
+ WindowManagerService.getCallers(3));
443+
+ Debug.getCallers(3));
443444
}
444445

445446
@Override
446447
public void setLayer(int zorder) {
447448
super.setLayer(zorder);
448449
mLayer = zorder;
449450
Slog.v(SURFACE_TAG, "setLayer: " + this + ". Called by "
450-
+ WindowManagerService.getCallers(3));
451+
+ Debug.getCallers(3));
451452

452453
sSurfaces.remove(this);
453454
int i;
@@ -465,45 +466,45 @@ public void setPosition(float x, float y) {
465466
super.setPosition(x, y);
466467
mPosition = new PointF(x, y);
467468
Slog.v(SURFACE_TAG, "setPosition: " + this + ". Called by "
468-
+ WindowManagerService.getCallers(3));
469+
+ Debug.getCallers(3));
469470
}
470471

471472
@Override
472473
public void setSize(int w, int h) {
473474
super.setSize(w, h);
474475
mSize = new Point(w, h);
475476
Slog.v(SURFACE_TAG, "setSize: " + this + ". Called by "
476-
+ WindowManagerService.getCallers(3));
477+
+ Debug.getCallers(3));
477478
}
478479

479480
@Override
480481
public void hide() {
481482
super.hide();
482483
mShown = false;
483484
Slog.v(SURFACE_TAG, "hide: " + this + ". Called by "
484-
+ WindowManagerService.getCallers(3));
485+
+ Debug.getCallers(3));
485486
}
486487
@Override
487488
public void show() {
488489
super.show();
489490
mShown = true;
490491
Slog.v(SURFACE_TAG, "show: " + this + ". Called by "
491-
+ WindowManagerService.getCallers(3));
492+
+ Debug.getCallers(3));
492493
}
493494

494495
@Override
495496
public void destroy() {
496497
super.destroy();
497498
Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by "
498-
+ WindowManagerService.getCallers(3));
499+
+ Debug.getCallers(3));
499500
sSurfaces.remove(this);
500501
}
501502

502503
@Override
503504
public void release() {
504505
super.release();
505506
Slog.v(SURFACE_TAG, "release: " + this + ". Called by "
506-
+ WindowManagerService.getCallers(3));
507+
+ Debug.getCallers(3));
507508
sSurfaces.remove(this);
508509
}
509510

0 commit comments

Comments
 (0)