Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0fb888d0 authored by Colin Cross's avatar Colin Cross
Browse files

Add getBinderKernelReferences

Add a wrapper for the new BINDER_GET_NODE_DEBUG_INFO ioctl for use by
libmemunreachable.

Test: memunreachable_binder_test
Bug: 28275695
Change-Id: Ic112584fa05071bd336974b3a18869077a69389b
Merged-In: Ic112584fa05071bd336974b3a18869077a69389b
(cherry picked from commit b869cc94)
parent 2bb661ca
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */

#include <binder/Debug.h>
#include <binder/ProcessState.h>

#include <utils/misc.h>

@@ -294,5 +295,14 @@ void printHexData(int32_t indent, const void *buf, size_t length,
    }
}

ssize_t getBinderKernelReferences(size_t count, uintptr_t* buf) {
    sp<ProcessState> proc = ProcessState::selfOrNull();
    if (proc.get() == NULL) {
        return 0;
    }

    return proc->getKernelReferences(count, buf);
}

}; // namespace android
+46 −0
Original line number Diff line number Diff line
@@ -75,6 +75,12 @@ sp<ProcessState> ProcessState::self()
    return gProcess;
}

sp<ProcessState> ProcessState::selfOrNull()
{
    Mutex::Autolock _l(gProcessMutex);
    return gProcess;
}

void ProcessState::setContextObject(const sp<IBinder>& object)
{
    setContextObject(object, String16("default"));
@@ -161,6 +167,46 @@ bool ProcessState::becomeContextManager(context_check_func checkFunc, void* user
    return mManagesContexts;
}

// Get references to userspace objects held by the kernel binder driver
// Writes up to count elements into buf, and returns the total number
// of references the kernel has, which may be larger than count.
// buf may be NULL if count is 0.  The pointers returned by this method
// should only be used for debugging and not dereferenced, they may
// already be invalid.
ssize_t ProcessState::getKernelReferences(size_t buf_count, uintptr_t* buf)
{
    // TODO: remove these when they are defined by bionic's binder.h
    struct binder_node_debug_info {
        binder_uintptr_t ptr;
        binder_uintptr_t cookie;
        __u32 has_strong_ref;
        __u32 has_weak_ref;
    };
#define BINDER_GET_NODE_DEBUG_INFO _IOWR('b', 11, struct binder_node_debug_info)

    binder_node_debug_info info = {};

    uintptr_t* end = buf ? buf + buf_count : NULL;
    size_t count = 0;

    do {
        status_t result = ioctl(mDriverFD, BINDER_GET_NODE_DEBUG_INFO, &info);
        if (result < 0) {
            return -1;
        }
        if (info.ptr != 0) {
            if (buf && buf < end)
                *buf++ = info.ptr;
            count++;
            if (buf && buf < end)
                *buf++ = info.cookie;
            count++;
        }
    } while (info.ptr != 0);

    return count;
}

ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
{
    const size_t N=mHandleToObject.size();
+6 −6
Original line number Diff line number Diff line
@@ -18,14 +18,13 @@
#define ANDROID_BINDER_DEBUG_H

#include <stdint.h>
#include <sys/cdefs.h>
#include <sys/types.h>

namespace android {
// ---------------------------------------------------------------------------

#ifdef __cplusplus
extern "C" {
#endif
__BEGIN_DECLS

const char* stringForIndent(int32_t indentLevel);

@@ -39,9 +38,10 @@ void printHexData(int32_t indent, const void *buf, size_t length,
    size_t alignment=0, bool cArrayStyle=false,
    debugPrintFunc func = 0, void* cookie = 0);

#ifdef __cplusplus
}
#endif

ssize_t getBinderKernelReferences(size_t count, uintptr_t* buf);

__END_DECLS

// ---------------------------------------------------------------------------
}; // namespace android
+3 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ class ProcessState : public virtual RefBase
{
public:
    static  sp<ProcessState>    self();
    static  sp<ProcessState>    selfOrNull();

            void                setContextObject(const sp<IBinder>& object);
            sp<IBinder>         getContextObject(const sp<IBinder>& caller);
@@ -64,6 +65,8 @@ public:
            status_t            setThreadPoolMaxThreadCount(size_t maxThreads);
            void                giveThreadPoolName();

            ssize_t             getKernelReferences(size_t count, uintptr_t* buf);

private:
    friend class IPCThreadState;