Package org.jnode.test.core

Source Code of org.jnode.test.core.StackView

/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.test.core;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.jnode.util.NumberUtils;
import org.jnode.vm.classmgr.Signature;
import org.jnode.vm.classmgr.VmCompiledCode;
import org.jnode.vm.classmgr.VmMethod;
import org.jnode.vm.classmgr.VmType;
import org.jnode.vm.facade.VmUtils;
import org.jnode.vm.scheduler.VmThread;
import org.jnode.vm.x86.VmX86StackReader;
import org.jnode.vm.x86.VmX86Thread;
import org.vmmagic.unboxed.Address;
import org.vmmagic.unboxed.ObjectReference;
import org.vmmagic.unboxed.Offset;

/**
* @author Levente S\u00e1ntha
*/
public class StackView {
    public static void main(String[] argv) {
        String threadName = null;
        if (argv.length > 0) {
            threadName = argv[0];
        }

        Thread thread = null;
        if (threadName == null) {
            thread = Thread.currentThread();
        } else {
            // Find the root of the ThreadGroup tree
            ThreadGroup grp = Thread.currentThread().getThreadGroup();
            while (grp.getParent() != null) {
                grp = grp.getParent();
            }

            final int max = grp.activeCount() * 2;
            final Thread[] ts = new Thread[max];
            grp.enumerate(ts);

            for (int i = 0; i < max; i++) {
                final Thread t = ts[i];
                if (t != null) {
                    if (threadName.equals(t.getName())) {
                        thread = t;
                        break;
                    }
                }
            }

            if (thread == null) {
                System.out.println("Thread not found: " + threadName);
                return;
            }
        }

        VmThread vmThread = ThreadHelper.getVmThread(thread);

        final int stackSize = vmThread.getStackSize();
        final Object stack = invoke("getStack", VmThread.class, vmThread);
        if (stack != null) {
            final Address stackBottom = ObjectReference.fromObject(stack).toAddress();
            final Address stackTop = stackBottom.add(stackSize);
            final Address stackEnd;
            if (vmThread == VmThread.currentThread()) {
                stackEnd = stackBottom;
            } else {
                stackEnd = ((VmX86Thread) vmThread).getStackPointer();
            }
            final int slotSize = (Integer) invoke("getReferenceSize", VmX86Thread.class, vmThread);
            Address stackFrame = vmThread.getStackFrame();
            System.out.println("Stack start:    " + NumberUtils.hex(stackTop.toInt()));
            System.out.println("Stack end  :    " + NumberUtils.hex(stackEnd.toInt()));

            System.out.println("Raw stack:");
            Address ptr = stackTop;


            while (ptr.GE(stackEnd)) {
                final Address child = ptr.loadAddress();
                if (child != null) {
                    System.out.print(NumberUtils.hex(ptr.toInt()) + " ");
                    if (VmUtils.getVm().getHeapManager().isObject(child)) {
                        System.out.println(child);
                    } else {
                        System.out.println(NumberUtils.hex(child.toInt()));
                    }
                }
                ptr = ptr.sub(slotSize);
            }

            System.out.println("Stack frames:");
            VmX86StackReader sr = new VmX86StackReader(slotSize);
            Address currFrame = stackFrame;

            //Address prevFrame = null;
            do {
                ptr = currFrame;
                //ccid
                ptr = ptr.add(Offset.fromIntSignExtend(VmX86StackReader.METHOD_ID_OFFSET * slotSize));
                int ccid = ptr.loadInt();
                if (ccid == 0) {
                    //invalid farme, exit
                    break;
                }

                System.out.println("--------------------------------------------------------------------------");
                System.out.println("Stack frame:    " + NumberUtils.hex(stackFrame.toInt()));

                VmCompiledCode cc = VmUtils.getVm().getCompiledMethods().get(ccid);
                VmMethod vmMethod = cc.getMethod();
                int noArguments = vmMethod.getNoArguments();
                VmType[] args = new VmType[noArguments];
                for (int i = 0; i < noArguments; i++) {
                    args[i] = vmMethod.getArgumentType(i);
                }
                System.out.print(NumberUtils.hex(ptr.toInt()) + " ");
                System.out.println(vmMethod.getDeclaringClass().getName() + "." + vmMethod.getName() +
                    Signature.toSignature(vmMethod.getReturnType(), args));

                ptr = ptr.sub(Offset.fromIntSignExtend(VmX86StackReader.METHOD_ID_OFFSET * slotSize));

                //old EBP
                System.out.println("Previous frame");
                ptr = ptr.add(Offset.fromIntSignExtend(VmX86StackReader.PREVIOUS_OFFSET * slotSize));
                System.out.print(NumberUtils.hex(ptr.toInt()) + " ");
                System.out.println(NumberUtils.hex(ptr.loadInt()));

                ptr = ptr.sub(Offset.fromIntSignExtend(VmX86StackReader.PREVIOUS_OFFSET * slotSize));

                //return Address
                System.out.println("Return address");
                ptr = ptr.add(Offset.fromIntSignExtend(VmX86StackReader.RETURNADDRESS_OFFSET * slotSize));
                System.out.print(NumberUtils.hex(ptr.toInt()) + " ");
                System.out.println(NumberUtils.hex(ptr.loadInt()));

                //method argumants
                int sc = vmMethod.getArgSlotCount();
                System.out.println("Method arguments: " + sc);
                for (int i = 0; i < sc; i++) {
                    ptr = ptr.add(slotSize);
                    System.out.print(NumberUtils.hex(ptr.toInt()) + " Arg" + (i + 1) + " = ");
                    Address child = ptr.loadAddress();
                    if (VmUtils.getVm().getHeapManager().isObject(child)) {
                        System.out.println("Class: " + child.getClass() + " Value: " + child);
                    } else {
                        System.out.println(NumberUtils.hex(child.toInt()));
                    }
                    //System.out.println(NumberUtils.hex(ptr.loadInt()));
                }
            } while ((currFrame = sr.getPrevious(currFrame)) != null);

        } else {
            System.out.println("Stack is null");
        }
    }

    private static Object invoke(String methodName, Class clazz, Object instance) {
        try {
            Method met = clazz.getMethod(methodName);
            return met.invoke(instance);
        } catch (Exception x) {
            x.printStackTrace();
            throw new RuntimeException(x);
        }
    }

    private static Object get(String filedName, Class clazz, Object instance) {
        try {
            Field field = clazz.getField(filedName);
            return field.get(instance);
        } catch (Exception x) {
            x.printStackTrace();
            throw new RuntimeException(x);
        }
    }
}
TOP

Related Classes of org.jnode.test.core.StackView

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.