/* * Copyright 2003-2012 Yusuke Yamamoto * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package samurai.core; import java.util.ArrayList; import java.util.List; public class BEAThreadDump extends ThreadDump { private static final long serialVersionUID = -6581661997485086419L; private final String[] STATUS_ARRAY; private final boolean IS_WEBLOGIC_ADMIN; private final String CONDITION; private final String ID; /*package*/ BEAThreadDump(String header) { super(header); int statusFrom; IS_WEBLOGIC_ADMIN = getHeader().startsWith("Thread-"); if (!IS_WEBLOGIC_ADMIN) { CONDITION = super.getCondition(); } else { int paramBegin = super.getCondition().lastIndexOf("<") + 1; int paramEnd = super.getCondition().lastIndexOf(">"); CONDITION = super.getCondition().substring(paramBegin, paramEnd); } if (!IS_WEBLOGIC_ADMIN) { ID = this.getHeaderParameter("id"); } else { int idBegin = getHeader().indexOf("-") + 1; int idEnd = getHeader().indexOf(" "); ID = getHeader().substring(idBegin, idEnd); } if (IS_WEBLOGIC_ADMIN) { //Thread-0xf80 "ExecuteThread: '0' for queue: 'weblogic.admin.RMI'" <Waiting, priority=5, DAEMON> { List<String> statusList = new ArrayList<String>(); String[] statusArray = getCondition().split(","); for (int i = 0; i < statusArray.length; i++) { statusArray[i] = statusArray[i].trim(); if (-1 == statusArray[i].indexOf("=")) { statusList.add(statusArray[i]); } } STATUS_ARRAY = statusList.toArray(statusArray); } else { if (isAriane()) { //assuming JRockit1.4.2_03 //"Main Thread" prio=5 id=0x80 pid=13184 waiting int paramEnd = getCondition().indexOf("pid="); if (-1 == paramEnd) { //JRockit1.4.2_05 //"Main Thread" prio=5 id=0x80 tid=0x1650 waiting paramEnd = getCondition().indexOf("tid="); } statusFrom = getCondition().indexOf(" ", paramEnd); } else { statusFrom = getCondition().indexOf(" ", getCondition().indexOf("prio: ") + 6); } String[] statusArray = getCondition().substring(statusFrom).split(","); for (int i = 0; i < statusArray.length; i++) { statusArray[i] = statusArray[i].trim(); } STATUS_ARRAY = statusArray; } if (IS_WEBLOGIC_ADMIN) { IS_IDLE = hasStatus("Waiting") || hasStatus("waiting"); } else if (isAriane()) { //maybe ariane //-8.1SP4 -> waiting //9.0 -> sleeping IS_IDLE = hasStatus("waiting") || hasStatus("sleeping") || hasStatus("native_waiting"); } else { //maybe viking IS_IDLE = hasStatus("WAITING"); } if (isAriane()) { //maybe ariane IS_DAEMON = hasStatus("daemon"); } else { //maybe viking or weblogic.Admin thread dump IS_DAEMON = hasStatus("DAEMON"); } } /*package*/ void addStackLine(String stackLine) { super.addStackLine(new BEAStackLine(stackLine.substring(stackLine.indexOf(" ") + 1))); } private boolean isAriane() { return !IS_WEBLOGIC_ADMIN && -1 != getCondition().indexOf("="); } public boolean isDaemon() { return IS_DAEMON; } private boolean isBlockedAnalyzed = false; public boolean isBlocked() { if (!isBlockedAnalyzed) { if (isAriane() || IS_WEBLOGIC_ADMIN) { //81SP3 if (hasStatus("blocked")) { IS_BLOCKED = true; } else if (this.size() >= 1) { //81SP4 sometimes shows blocked thread as "active". need to check the 1st line to test if the thread is blocked IS_BLOCKED = this.getLine(0).getLine().trim().startsWith( "-- Blocked trying to get lock"); } else { IS_BLOCKED = false; } } else { //maybe viking if (this.size() >= 3) { StackLine line = this.getLine(2); if (line.isLine()) { if ("COM.jrockit.vm.RNI".equals(line.getClassName()) && "waitOnThinLocker".equals(line.getMethodName())) { IS_BLOCKED = true; } } } if (this.size() >= 4) { StackLine line = this.getLine(3); IS_BLOCKED = IS_BLOCKED || line.isLine() && ("jrockit/vm/Locks".equals(line.getClassName()) && "monitorEnter".equals(line.getMethodName())); } else { IS_BLOCKED = IS_BLOCKED || hasStatus("LOCKED"); } } isBlockedAnalyzed = true; } return IS_BLOCKED; } public boolean isIdle() { return IS_IDLE; } public String getId() { return ID; } private boolean hasStatus(String status) { for (String aStatusArray : STATUS_ARRAY) { if (status.equals(aStatusArray)) { return true; } } return false; } public String getCondition() { return CONDITION; } }