diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 6ef5be7ba..000000000 --- a/.travis.yml +++ /dev/null @@ -1,65 +0,0 @@ -language: java -sudo: false - -matrix: - include: -# Target option 6 is no longer supported. Use 7 or later. -# - env: -# - ZULUJDK=12 - - env: - - ZULUJDK=11 - - env: - - ZULUJDK=10 - - env: - - ZULUJDK=9 - - env: - - ZULUJDK=8 - - env: - - ZULUJDK=7 -# TLS error -# - env: -# - ZULUJDK=6 - -before_install: - # installing the rpm package - - sudo apt-get update -qq - - sudo apt-get install -qq rpm - # adding $HOME/.sdkman to cache would create an empty directory, which interferes with the initial installation - - "[[ -d $HOME/.sdkman/bin/ ]] || rm -rf $HOME/.sdkman/" - - curl -sL https://get.sdkman.io | bash - - echo sdkman_auto_answer=true > $HOME/.sdkman/etc/config - - source "$HOME/.sdkman/bin/sdkman-init.sh" - -install: - - sdk install java $(sdk list java | grep -o "$ZULUJDK\.[0-9\.]*-zulu" | head -1) - - unset JAVA_HOME - -cache: - directories: - - "$HOME/.m2/repository" - - "$HOME/.m2/wrapper" - -script: - - ./mvnw -version - - travis_wait 30 ./mvnw clean package --batch-mode -P full - -after_success: - - bash <(curl -s https://codecov.io/bash) - -notifications: - email: false - -deploy: - provider: releases - api_key: - - secure: "V+omzrcAJ/awN3EsDkiELejjInz/rpgPLdyb4uZrcQnqhagbHYE+nY2KcjPEtRBVNkqlh6dxIIsUFvKrs5kxe5EVvI6rLQeZLFMqWUeNfWuhbuQWCV9ZPyQiqXCqNicj+LLHArzQRLx5w5YBvxdzMuXSWo1ZE4wy+c3koprulUSjr6XhNPKyyasq4EXKMXuLCjcvBVPHhXviG59Jbshb2lRHbkxMqYeLhWi/gUOBRbNC1CmcGGAMviFX7HpBOx5fMaVKPR7rzcULw3lXnLhdSwhXJ6ybnsN/osfN8zAx6XZIwvwvVQ12yM8S9eVthnjblFh+WKwOT1AS6hHFXkMTjh1FE5CtUVu+sFbGIngJ4C4O78VzWCKvH/IrIi4p2IkF+fcu8USnm7YZGuyoAwe3O5PqmWBuQV0iCEx0IGo/nPwVzj1+jnz38Go/DP1aVDJZMenysBNxi4l45d3J3CgMPvF00DDQKvxYrkBjdnByANrOisZPjIeUOc7GsWoDLCK9jZtXMID2NM+ehQnDbOJ3BS2Bjg7ojPc0Rw2yJjbzwNqaMiOPXp2ym/5DpaB/l5k2gSi2NCRUFCXhFNRCq9ChFXv+pYJwk0e17sleGvo6tnFDVCR6lFcXrYo/vGC43bL1dT4rY8E6VSRlE0jfoXdFFp4jw3v3a+DqVLGVC9UcTpw=" - file_glob: true - file: - - "packaging/target/*.zip" - - "packaging/target/*.deb" - - "packaging/target/*.rpm" - - "tunnel-server/target/*fatjar.jar" - skip_cleanup: true - on: - tags: true - diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6668ee145..372751abf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -150,6 +150,8 @@ chmod +x /tmp/sphinx.osx-x86_64 * 发布完maven仓库之后,需要到阿里云的仓库里检查是否同步,有可能有延时 比如下载地址: https://maven.aliyun.com/repository/public/com/taobao/arthas/arthas-packaging/3.x.x/arthas-packaging-3.x.x-bin.zip + + 版本号信息地址: https://maven.aliyun.com/repository/public/com/taobao/arthas/arthas-packaging/maven-metadata.xml * 打上tag,push tag到仓库上 * 需要更新 gh-pages 分支下面的 arthas-boot.jar/math-game.jar/as.sh ,下载 doc.zip,解压覆盖掉文档的更新 diff --git a/Dockerfile b/Dockerfile index 7c2d5ac0f..4e26de0b8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM openjdk:8-jdk-alpine -ARG ARTHAS_VERSION="3.5.3" +ARG ARTHAS_VERSION="3.5.4" ARG MIRROR=false ENV MAVEN_HOST=https://repo1.maven.org/maven2 \ diff --git a/Dockerfile-No-Jdk b/Dockerfile-No-Jdk index e14548b2e..73ad93e13 100644 --- a/Dockerfile-No-Jdk +++ b/Dockerfile-No-Jdk @@ -1,6 +1,6 @@ FROM alpine -ARG ARTHAS_VERSION="3.5.3" +ARG ARTHAS_VERSION="3.5.4" ARG MIRROR=false ENV MAVEN_HOST=https://repo1.maven.org/maven2 \ diff --git a/NOTICE b/NOTICE index b51bd599d..6f3d6f220 100644 --- a/NOTICE +++ b/NOTICE @@ -10,3 +10,18 @@ The greys-anatomy Project ================= Please visit Github for more information: * https://github.com/oldmanpushcart/greys-anatomy + + +------------------------------------------------------------------------------- +This product contains a modified portion of 'Apache Commons Lang': + * LICENSE: + * Apache License 2.0 + * HOMEPAGE: + * https://commons.apache.org/proper/commons-lang/ + + +This product contains a modified portion of 'Apache Commons Net': + * LICENSE: + * Apache License 2.0 + * HOMEPAGE: + * https://commons.apache.org/proper/commons-net/ diff --git a/README.md b/README.md index 27367fcc8..5b58adc85 100644 --- a/README.md +++ b/README.md @@ -323,7 +323,7 @@ ts=2018-09-18 10:26:28;result=@ArrayList[ * https://arthas.aliyun.com/doc/en/monitor -Monitor a specific method invocation statistics, including total number of invocations, average response time, success rate, and every 5 seconds: +Monitor a specific method invocation statistics, including the total number of invocations, average response time, success rate, and every 5 seconds: ```bash $ monitor -c 5 org.apache.dubbo.demo.provider.DemoServiceImpl sayHello diff --git a/arthas-vmtool/src/main/native/head/classfile_constants.h b/arthas-vmtool/src/main/native/head/classfile_constants.h index e5c20cd9a..cca9832f8 100755 --- a/arthas-vmtool/src/main/native/head/classfile_constants.h +++ b/arthas-vmtool/src/main/native/head/classfile_constants.h @@ -1,26 +1,26 @@ /* - * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. - * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. */ #ifndef CLASSFILE_CONSTANTS_H @@ -31,7 +31,7 @@ extern "C" { #endif /* Classfile version number for this information */ -#define JVM_CLASSFILE_MAJOR_VERSION 52 +#define JVM_CLASSFILE_MAJOR_VERSION 60 #define JVM_CLASSFILE_MINOR_VERSION 0 /* Flags */ @@ -54,9 +54,29 @@ enum { JVM_ACC_STRICT = 0x0800, JVM_ACC_SYNTHETIC = 0x1000, JVM_ACC_ANNOTATION = 0x2000, - JVM_ACC_ENUM = 0x4000 + JVM_ACC_ENUM = 0x4000, + JVM_ACC_MODULE = 0x8000 }; +#define JVM_ACC_PUBLIC_BIT 0 +#define JVM_ACC_PRIVATE_BIT 1 +#define JVM_ACC_PROTECTED_BIT 2 +#define JVM_ACC_STATIC_BIT 3 +#define JVM_ACC_FINAL_BIT 4 +#define JVM_ACC_SYNCHRONIZED_BIT 5 +#define JVM_ACC_SUPER_BIT 5 +#define JVM_ACC_VOLATILE_BIT 6 +#define JVM_ACC_BRIDGE_BIT 6 +#define JVM_ACC_TRANSIENT_BIT 7 +#define JVM_ACC_VARARGS_BIT 7 +#define JVM_ACC_NATIVE_BIT 8 +#define JVM_ACC_INTERFACE_BIT 9 +#define JVM_ACC_ABSTRACT_BIT 10 +#define JVM_ACC_STRICT_BIT 11 +#define JVM_ACC_SYNTHETIC_BIT 12 +#define JVM_ACC_ANNOTATION_BIT 13 +#define JVM_ACC_ENUM_BIT 14 + /* Used in newarray instruction. */ enum { @@ -86,8 +106,12 @@ enum { JVM_CONSTANT_InterfaceMethodref = 11, JVM_CONSTANT_NameAndType = 12, JVM_CONSTANT_MethodHandle = 15, // JSR 292 - JVM_CONSTANT_MethodType = 16, // JSR 292 - JVM_CONSTANT_InvokeDynamic = 18 + JVM_CONSTANT_MethodType = 16, // JSR 292 + JVM_CONSTANT_Dynamic = 17, + JVM_CONSTANT_InvokeDynamic = 18, + JVM_CONSTANT_Module = 19, + JVM_CONSTANT_Package = 20, + JVM_CONSTANT_ExternalMax = 20 }; /* JVM_CONSTANT_MethodHandle subtypes */ @@ -120,6 +144,10 @@ enum { /* Type signatures */ enum { + JVM_SIGNATURE_SLASH = '/', + JVM_SIGNATURE_DOT = '.', + JVM_SIGNATURE_SPECIAL = '<', + JVM_SIGNATURE_ENDSPECIAL = '>', JVM_SIGNATURE_ARRAY = '[', JVM_SIGNATURE_BYTE = 'B', JVM_SIGNATURE_CHAR = 'C', diff --git a/arthas-vmtool/src/main/native/head/jawt.h b/arthas-vmtool/src/main/native/head/jawt.h index f06e80713..2079b0bc1 100755 --- a/arthas-vmtool/src/main/native/head/jawt.h +++ b/arthas-vmtool/src/main/native/head/jawt.h @@ -1,26 +1,26 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. - * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. */ #ifndef _JAVASOFT_JAWT_H_ @@ -33,23 +33,27 @@ extern "C" { #endif /* - * AWT native interface (new in JDK 1.3) + * AWT native interface. * * The AWT native interface allows a native C or C++ application a means * by which to access native structures in AWT. This is to facilitate moving * legacy C and C++ applications to Java and to target the needs of the - * community who, at present, wish to do their own native rendering to canvases - * for performance reasons. Standard extensions such as Java3D also require a - * means to access the underlying native data structures of AWT. + * developers who need to do their own native rendering to canvases + * for performance or other reasons. * - * There may be future extensions to this API depending on demand. + * Conversely it also provides mechanisms for an application which already + * has a native window to provide that to AWT for AWT rendering. * - * A VM does not have to implement this API in order to pass the JCK. - * It is recommended, however, that this API is implemented on VMs that support - * standard extensions, such as Java3D. + * Since every platform may be different in its native data structures + * and APIs for windowing systems the application must necessarily + * provided per-platform source and compile and deliver per-platform + * native code to use this API. + * + * These interfaces are not part of the Java SE specification and + * a VM is not required to implement this API. However it is strongly + * recommended that all implementations which support headful AWT + * also support these interfaces. * - * Since this is a native API, any program which uses it cannot be considered - * 100% pure java. */ /* @@ -58,7 +62,7 @@ extern "C" { * For each platform, there is a native drawing surface structure. This * platform-specific structure can be found in jawt_md.h. It is recommended * that additional platforms follow the same model. It is also recommended - * that VMs on Win32 and Solaris support the existing structures in jawt_md.h. + * that VMs on all platforms support the existing structures in jawt_md.h. * ******************* * EXAMPLE OF USAGE: @@ -98,8 +102,8 @@ extern "C" { * jboolean result; * jint lock; * - * // Get the AWT - * awt.version = JAWT_VERSION_1_3; + * // Get the AWT. Request version 9 to access features in that release. + * awt.version = JAWT_VERSION_9; * result = JAWT_GetAWT(env, &awt); * assert(result != JNI_FALSE); * @@ -154,7 +158,7 @@ typedef struct jawt_DrawingSurfaceInfo { /* * Pointer to the platform-specific information. This can be safely * cast to a JAWT_Win32DrawingSurfaceInfo on Windows or a - * JAWT_X11DrawingSurfaceInfo on Solaris. On Mac OS X this is a + * JAWT_X11DrawingSurfaceInfo on Linux and Solaris. On Mac OS X this is a * pointer to a NSObject that conforms to the JAWT_SurfaceLayers * protocol. See jawt_md.h for details. */ @@ -237,7 +241,8 @@ typedef struct jawt_DrawingSurface { typedef struct jawt { /* * Version of this structure. This must always be set before - * calling JAWT_GetAWT() + * calling JAWT_GetAWT(). It affects the functions returned. + * Must be one of the known pre-defined versions. */ jint version; /* @@ -279,6 +284,50 @@ typedef struct jawt { */ jobject (JNICALL *GetComponent)(JNIEnv* env, void* platformInfo); + /** + * Since 9 + * Creates a java.awt.Frame placed in a native container. Container is + * referenced by the native platform handle. For example on Windows this + * corresponds to an HWND. For other platforms, see the appropriate + * machine-dependent header file for a description. The reference returned + * by this function is a local reference that is only valid in this + * environment. This function returns a NULL reference if no frame could be + * created with matching platform information. + */ + jobject (JNICALL *CreateEmbeddedFrame) (JNIEnv *env, void* platformInfo); + + /** + * Since 9 + * Moves and resizes the embedded frame. The new location of the top-left + * corner is specified by x and y parameters relative to the native parent + * component. The new size is specified by width and height. + * + * The embedded frame should be created by CreateEmbeddedFrame() method, or + * this function will not have any effect. + * + * java.awt.Component.setLocation() and java.awt.Component.setBounds() for + * EmbeddedFrame really don't move it within the native parent. These + * methods always locate the embedded frame at (0, 0) for backward + * compatibility. To allow moving embedded frames this method was + * introduced, and it works just the same way as setLocation() and + * setBounds() for usual, non-embedded components. + * + * Using usual get/setLocation() and get/setBounds() together with this new + * method is not recommended. + */ + void (JNICALL *SetBounds) (JNIEnv *env, jobject embeddedFrame, + jint x, jint y, jint w, jint h); + /** + * Since 9 + * Synthesize a native message to activate or deactivate an EmbeddedFrame + * window depending on the value of parameter doActivate, if "true" + * activates the window; otherwise, deactivates the window. + * + * The embedded frame should be created by CreateEmbeddedFrame() method, or + * this function will not have any effect. + */ + void (JNICALL *SynthesizeWindowActivation) (JNIEnv *env, + jobject embeddedFrame, jboolean doActivate); } JAWT; /* @@ -288,9 +337,17 @@ typedef struct jawt { _JNI_IMPORT_OR_EXPORT_ jboolean JNICALL JAWT_GetAWT(JNIEnv* env, JAWT* awt); +/* + * Specify one of these constants as the JAWT.version + * Specifying an earlier version will limit the available functions to + * those provided in that earlier version of JAWT. + * See the "Since" note on each API. Methods with no "Since" + * may be presumed to be present in JAWT_VERSION_1_3. + */ #define JAWT_VERSION_1_3 0x00010003 #define JAWT_VERSION_1_4 0x00010004 #define JAWT_VERSION_1_7 0x00010007 +#define JAWT_VERSION_9 0x00090000 #ifdef __cplusplus } /* extern "C" */ diff --git a/arthas-vmtool/src/main/native/head/jdwpTransport.h b/arthas-vmtool/src/main/native/head/jdwpTransport.h index 4f4b92ede..cdbd04d42 100755 --- a/arthas-vmtool/src/main/native/head/jdwpTransport.h +++ b/arthas-vmtool/src/main/native/head/jdwpTransport.h @@ -1,26 +1,26 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. - * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. */ /* @@ -33,7 +33,8 @@ #include "jni.h" enum { - JDWPTRANSPORT_VERSION_1_0 = 0x00010000 + JDWPTRANSPORT_VERSION_1_0 = 0x00010000, + JDWPTRANSPORT_VERSION_1_1 = 0x00010001 }; #ifdef __cplusplus @@ -95,6 +96,8 @@ typedef struct { * See: http://java.sun.com/j2se/1.5/docs/guide/jpda/jdwp-spec.html */ +#define JDWP_HEADER_SIZE 11 + enum { /* * If additional flags are added that apply to jdwpCmdPacket, @@ -142,6 +145,13 @@ typedef jint (JNICALL *jdwpTransport_OnLoad_t)(JavaVM *jvm, jint version, jdwpTransportEnv** env); +/* + * JDWP transport configuration from the agent. + */ +typedef struct jdwpTransportConfiguration { + /* Field added in JDWPTRANSPORT_VERSION_1_1: */ + const char* allowed_peers; /* Peers allowed for connection */ +} jdwpTransportConfiguration; /* Function Interface */ @@ -191,6 +201,9 @@ struct jdwpTransportNativeInterface_ { jdwpTransportError (JNICALL *GetLastError)(jdwpTransportEnv* env, char** error); + /* 12: SetTransportConfiguration added in JDWPTRANSPORT_VERSION_1_1 */ + jdwpTransportError (JNICALL *SetTransportConfiguration)(jdwpTransportEnv* env, + jdwpTransportConfiguration *config); }; @@ -248,6 +261,10 @@ struct _jdwpTransportEnv { return functions->GetLastError(this, error); } + /* SetTransportConfiguration added in JDWPTRANSPORT_VERSION_1_1 */ + jdwpTransportError SetTransportConfiguration(jdwpTransportEnv* env, + return functions->SetTransportConfiguration(this, config); + } #endif /* __cplusplus */ }; diff --git a/arthas-vmtool/src/main/native/head/jni.h b/arthas-vmtool/src/main/native/head/jni.h index 0ffe244b6..aa0cdf5c2 100755 --- a/arthas-vmtool/src/main/native/head/jni.h +++ b/arthas-vmtool/src/main/native/head/jni.h @@ -1,26 +1,26 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. - * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. */ /* @@ -765,6 +765,11 @@ struct JNINativeInterface_ { jobjectRefType (JNICALL *GetObjectRefType) (JNIEnv* env, jobject obj); + + /* Module Features */ + + jobject (JNICALL *GetModule) + (JNIEnv* env, jclass clazz); }; /* @@ -1857,9 +1862,29 @@ struct JNIEnv_ { return functions->GetObjectRefType(this, obj); } + /* Module Features */ + + jobject GetModule(jclass clazz) { + return functions->GetModule(this, clazz); + } + #endif /* __cplusplus */ }; +/* + * optionString may be any option accepted by the JVM, or one of the + * following: + * + * -D= Set a system property. + * -verbose[:class|gc|jni] Enable verbose output, comma-separated. E.g. + * "-verbose:class" or "-verbose:gc,class" + * Standard names include: gc, class, and jni. + * All nonstandard (VM-specific) names must begin + * with "X". + * vfprintf extraInfo is a pointer to the vfprintf hook. + * exit extraInfo is a pointer to the exit hook. + * abort extraInfo is a pointer to the abort hook. + */ typedef struct JavaVMOption { char *optionString; void *extraInfo; @@ -1952,6 +1977,8 @@ JNI_OnUnload(JavaVM *vm, void *reserved); #define JNI_VERSION_1_4 0x00010004 #define JNI_VERSION_1_6 0x00010006 #define JNI_VERSION_1_8 0x00010008 +#define JNI_VERSION_9 0x00090000 +#define JNI_VERSION_10 0x000a0000 #ifdef __cplusplus } /* extern "C" */ diff --git a/arthas-vmtool/src/main/native/head/jvmti.h b/arthas-vmtool/src/main/native/head/jvmti.h index 74243f540..87df35ae5 100755 --- a/arthas-vmtool/src/main/native/head/jvmti.h +++ b/arthas-vmtool/src/main/native/head/jvmti.h @@ -1,30 +1,29 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. - * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. */ - /* AUTOMATICALLY GENERATED FILE - DO NOT EDIT */ - + /* AUTOMATICALLY GENERATED FILE - DO NOT EDIT */ /* Include file for the Java(tm) Virtual Machine Tool Interface */ @@ -42,8 +41,10 @@ enum { JVMTI_VERSION_1_0 = 0x30010000, JVMTI_VERSION_1_1 = 0x30010100, JVMTI_VERSION_1_2 = 0x30010200, + JVMTI_VERSION_9 = 0x30090000, + JVMTI_VERSION_11 = 0x300B0000, - JVMTI_VERSION = 0x30000000 + (1 * 0x10000) + (2 * 0x100) + 1 /* version: 1.2.1 */ + JVMTI_VERSION = 0x30000000 + (16 * 0x10000) + ( 0 * 0x100) + 0 /* version: 16.0.0 */ }; JNIEXPORT jint JNICALL @@ -348,6 +349,7 @@ typedef enum { JVMTI_ERROR_INVALID_METHODID = 23, JVMTI_ERROR_INVALID_LOCATION = 24, JVMTI_ERROR_INVALID_FIELDID = 25, + JVMTI_ERROR_INVALID_MODULE = 26, JVMTI_ERROR_NO_MORE_FRAMES = 31, JVMTI_ERROR_OPAQUE_FRAME = 32, JVMTI_ERROR_TYPE_MISMATCH = 34, @@ -369,7 +371,9 @@ typedef enum { JVMTI_ERROR_NAMES_DONT_MATCH = 69, JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED = 70, JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED = 71, + JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED = 72, JVMTI_ERROR_UNMODIFIABLE_CLASS = 79, + JVMTI_ERROR_UNMODIFIABLE_MODULE = 80, JVMTI_ERROR_NOT_AVAILABLE = 98, JVMTI_ERROR_MUST_POSSESS_CAPABILITY = 99, JVMTI_ERROR_NULL_POINTER = 100, @@ -422,55 +426,56 @@ typedef enum { JVMTI_EVENT_GARBAGE_COLLECTION_FINISH = 82, JVMTI_EVENT_OBJECT_FREE = 83, JVMTI_EVENT_VM_OBJECT_ALLOC = 84, - JVMTI_MAX_EVENT_TYPE_VAL = 84 + JVMTI_EVENT_SAMPLED_OBJECT_ALLOC = 86, + JVMTI_MAX_EVENT_TYPE_VAL = 86 } jvmtiEvent; /* Pre-Declarations */ -struct _jvmtiThreadInfo; -typedef struct _jvmtiThreadInfo jvmtiThreadInfo; -struct _jvmtiMonitorStackDepthInfo; -typedef struct _jvmtiMonitorStackDepthInfo jvmtiMonitorStackDepthInfo; -struct _jvmtiThreadGroupInfo; -typedef struct _jvmtiThreadGroupInfo jvmtiThreadGroupInfo; -struct _jvmtiFrameInfo; -typedef struct _jvmtiFrameInfo jvmtiFrameInfo; -struct _jvmtiStackInfo; -typedef struct _jvmtiStackInfo jvmtiStackInfo; -struct _jvmtiHeapReferenceInfoField; -typedef struct _jvmtiHeapReferenceInfoField jvmtiHeapReferenceInfoField; -struct _jvmtiHeapReferenceInfoArray; -typedef struct _jvmtiHeapReferenceInfoArray jvmtiHeapReferenceInfoArray; -struct _jvmtiHeapReferenceInfoConstantPool; -typedef struct _jvmtiHeapReferenceInfoConstantPool jvmtiHeapReferenceInfoConstantPool; -struct _jvmtiHeapReferenceInfoStackLocal; -typedef struct _jvmtiHeapReferenceInfoStackLocal jvmtiHeapReferenceInfoStackLocal; -struct _jvmtiHeapReferenceInfoJniLocal; -typedef struct _jvmtiHeapReferenceInfoJniLocal jvmtiHeapReferenceInfoJniLocal; -struct _jvmtiHeapReferenceInfoReserved; -typedef struct _jvmtiHeapReferenceInfoReserved jvmtiHeapReferenceInfoReserved; -union _jvmtiHeapReferenceInfo; -typedef union _jvmtiHeapReferenceInfo jvmtiHeapReferenceInfo; -struct _jvmtiHeapCallbacks; -typedef struct _jvmtiHeapCallbacks jvmtiHeapCallbacks; -struct _jvmtiClassDefinition; -typedef struct _jvmtiClassDefinition jvmtiClassDefinition; -struct _jvmtiMonitorUsage; -typedef struct _jvmtiMonitorUsage jvmtiMonitorUsage; -struct _jvmtiLineNumberEntry; -typedef struct _jvmtiLineNumberEntry jvmtiLineNumberEntry; -struct _jvmtiLocalVariableEntry; -typedef struct _jvmtiLocalVariableEntry jvmtiLocalVariableEntry; -struct _jvmtiParamInfo; -typedef struct _jvmtiParamInfo jvmtiParamInfo; -struct _jvmtiExtensionFunctionInfo; -typedef struct _jvmtiExtensionFunctionInfo jvmtiExtensionFunctionInfo; -struct _jvmtiExtensionEventInfo; -typedef struct _jvmtiExtensionEventInfo jvmtiExtensionEventInfo; -struct _jvmtiTimerInfo; -typedef struct _jvmtiTimerInfo jvmtiTimerInfo; -struct _jvmtiAddrLocationMap; -typedef struct _jvmtiAddrLocationMap jvmtiAddrLocationMap; +struct jvmtiThreadInfo; +typedef struct jvmtiThreadInfo jvmtiThreadInfo; +struct jvmtiMonitorStackDepthInfo; +typedef struct jvmtiMonitorStackDepthInfo jvmtiMonitorStackDepthInfo; +struct jvmtiThreadGroupInfo; +typedef struct jvmtiThreadGroupInfo jvmtiThreadGroupInfo; +struct jvmtiFrameInfo; +typedef struct jvmtiFrameInfo jvmtiFrameInfo; +struct jvmtiStackInfo; +typedef struct jvmtiStackInfo jvmtiStackInfo; +struct jvmtiHeapReferenceInfoField; +typedef struct jvmtiHeapReferenceInfoField jvmtiHeapReferenceInfoField; +struct jvmtiHeapReferenceInfoArray; +typedef struct jvmtiHeapReferenceInfoArray jvmtiHeapReferenceInfoArray; +struct jvmtiHeapReferenceInfoConstantPool; +typedef struct jvmtiHeapReferenceInfoConstantPool jvmtiHeapReferenceInfoConstantPool; +struct jvmtiHeapReferenceInfoStackLocal; +typedef struct jvmtiHeapReferenceInfoStackLocal jvmtiHeapReferenceInfoStackLocal; +struct jvmtiHeapReferenceInfoJniLocal; +typedef struct jvmtiHeapReferenceInfoJniLocal jvmtiHeapReferenceInfoJniLocal; +struct jvmtiHeapReferenceInfoReserved; +typedef struct jvmtiHeapReferenceInfoReserved jvmtiHeapReferenceInfoReserved; +union jvmtiHeapReferenceInfo; +typedef union jvmtiHeapReferenceInfo jvmtiHeapReferenceInfo; +struct jvmtiHeapCallbacks; +typedef struct jvmtiHeapCallbacks jvmtiHeapCallbacks; +struct jvmtiClassDefinition; +typedef struct jvmtiClassDefinition jvmtiClassDefinition; +struct jvmtiMonitorUsage; +typedef struct jvmtiMonitorUsage jvmtiMonitorUsage; +struct jvmtiLineNumberEntry; +typedef struct jvmtiLineNumberEntry jvmtiLineNumberEntry; +struct jvmtiLocalVariableEntry; +typedef struct jvmtiLocalVariableEntry jvmtiLocalVariableEntry; +struct jvmtiParamInfo; +typedef struct jvmtiParamInfo jvmtiParamInfo; +struct jvmtiExtensionFunctionInfo; +typedef struct jvmtiExtensionFunctionInfo jvmtiExtensionFunctionInfo; +struct jvmtiExtensionEventInfo; +typedef struct jvmtiExtensionEventInfo jvmtiExtensionEventInfo; +struct jvmtiTimerInfo; +typedef struct jvmtiTimerInfo jvmtiTimerInfo; +struct jvmtiAddrLocationMap; +typedef struct jvmtiAddrLocationMap jvmtiAddrLocationMap; /* Function Types */ @@ -515,43 +520,43 @@ typedef void (JNICALL *jvmtiExtensionEvent) /* Structure Types */ -struct _jvmtiThreadInfo { +struct jvmtiThreadInfo { char* name; jint priority; jboolean is_daemon; jthreadGroup thread_group; jobject context_class_loader; }; -struct _jvmtiMonitorStackDepthInfo { +struct jvmtiMonitorStackDepthInfo { jobject monitor; jint stack_depth; }; -struct _jvmtiThreadGroupInfo { +struct jvmtiThreadGroupInfo { jthreadGroup parent; char* name; jint max_priority; jboolean is_daemon; }; -struct _jvmtiFrameInfo { +struct jvmtiFrameInfo { jmethodID method; jlocation location; }; -struct _jvmtiStackInfo { +struct jvmtiStackInfo { jthread thread; jint state; jvmtiFrameInfo* frame_buffer; jint frame_count; }; -struct _jvmtiHeapReferenceInfoField { +struct jvmtiHeapReferenceInfoField { jint index; }; -struct _jvmtiHeapReferenceInfoArray { +struct jvmtiHeapReferenceInfoArray { jint index; }; -struct _jvmtiHeapReferenceInfoConstantPool { +struct jvmtiHeapReferenceInfoConstantPool { jint index; }; -struct _jvmtiHeapReferenceInfoStackLocal { +struct jvmtiHeapReferenceInfoStackLocal { jlong thread_tag; jlong thread_id; jint depth; @@ -559,13 +564,13 @@ struct _jvmtiHeapReferenceInfoStackLocal { jlocation location; jint slot; }; -struct _jvmtiHeapReferenceInfoJniLocal { +struct jvmtiHeapReferenceInfoJniLocal { jlong thread_tag; jlong thread_id; jint depth; jmethodID method; }; -struct _jvmtiHeapReferenceInfoReserved { +struct jvmtiHeapReferenceInfoReserved { jlong reserved1; jlong reserved2; jlong reserved3; @@ -575,7 +580,7 @@ struct _jvmtiHeapReferenceInfoReserved { jlong reserved7; jlong reserved8; }; -union _jvmtiHeapReferenceInfo { +union jvmtiHeapReferenceInfo { jvmtiHeapReferenceInfoField field; jvmtiHeapReferenceInfoArray array; jvmtiHeapReferenceInfoConstantPool constant_pool; @@ -583,7 +588,7 @@ union _jvmtiHeapReferenceInfo { jvmtiHeapReferenceInfoJniLocal jni_local; jvmtiHeapReferenceInfoReserved other; }; -struct _jvmtiHeapCallbacks { +struct jvmtiHeapCallbacks { jvmtiHeapIterationCallback heap_iteration_callback; jvmtiHeapReferenceCallback heap_reference_callback; jvmtiPrimitiveFieldCallback primitive_field_callback; @@ -601,12 +606,12 @@ struct _jvmtiHeapCallbacks { jvmtiReservedCallback reserved14; jvmtiReservedCallback reserved15; }; -struct _jvmtiClassDefinition { +struct jvmtiClassDefinition { jclass klass; jint class_byte_count; const unsigned char* class_bytes; }; -struct _jvmtiMonitorUsage { +struct jvmtiMonitorUsage { jthread owner; jint entry_count; jint waiter_count; @@ -614,11 +619,11 @@ struct _jvmtiMonitorUsage { jint notify_waiter_count; jthread* notify_waiters; }; -struct _jvmtiLineNumberEntry { +struct jvmtiLineNumberEntry { jlocation start_location; jint line_number; }; -struct _jvmtiLocalVariableEntry { +struct jvmtiLocalVariableEntry { jlocation start_location; jint length; char* name; @@ -626,13 +631,13 @@ struct _jvmtiLocalVariableEntry { char* generic_signature; jint slot; }; -struct _jvmtiParamInfo { +struct jvmtiParamInfo { char* name; jvmtiParamKind kind; jvmtiParamTypes base_type; jboolean null_ok; }; -struct _jvmtiExtensionFunctionInfo { +struct jvmtiExtensionFunctionInfo { jvmtiExtensionFunction func; char* id; char* short_description; @@ -641,14 +646,14 @@ struct _jvmtiExtensionFunctionInfo { jint error_count; jvmtiError* errors; }; -struct _jvmtiExtensionEventInfo { +struct jvmtiExtensionEventInfo { jint extension_event_index; char* id; char* short_description; jint param_count; jvmtiParamInfo* params; }; -struct _jvmtiTimerInfo { +struct jvmtiTimerInfo { jlong max_value; jboolean may_skip_forward; jboolean may_skip_backward; @@ -656,7 +661,7 @@ struct _jvmtiTimerInfo { jlong reserved1; jlong reserved2; }; -struct _jvmtiAddrLocationMap { +struct jvmtiAddrLocationMap { const void* start_address; jlocation location; }; @@ -703,7 +708,10 @@ typedef struct { unsigned int can_retransform_any_class : 1; unsigned int can_generate_resource_exhaustion_heap_events : 1; unsigned int can_generate_resource_exhaustion_threads_events : 1; - unsigned int : 7; + unsigned int can_generate_early_vmstart : 1; + unsigned int can_generate_early_class_hook_events : 1; + unsigned int can_generate_sampled_object_alloc_events : 1; + unsigned int : 4; unsigned int : 16; unsigned int : 16; unsigned int : 16; @@ -883,6 +891,14 @@ typedef void (JNICALL *jvmtiEventResourceExhausted) const void* reserved, const char* description); +typedef void (JNICALL *jvmtiEventSampledObjectAlloc) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jobject object, + jclass object_klass, + jlong size); + typedef void (JNICALL *jvmtiEventSingleStep) (jvmtiEnv *jvmti_env, JNIEnv* jni_env, @@ -994,6 +1010,10 @@ typedef struct { jvmtiEventObjectFree ObjectFree; /* 84 : VM Object Allocation */ jvmtiEventVMObjectAlloc VMObjectAlloc; + /* 85 */ + jvmtiEventReserved reserved85; + /* 86 : Sampled Object Allocation */ + jvmtiEventSampledObjectAlloc SampledObjectAlloc; } jvmtiEventCallbacks; @@ -1011,8 +1031,10 @@ typedef struct jvmtiInterface_1_ { jthread event_thread, ...); - /* 3 : RESERVED */ - void *reserved3; + /* 3 : Get All Modules */ + jvmtiError (JNICALL *GetAllModules) (jvmtiEnv* env, + jint* module_count_ptr, + jobject** modules_ptr); /* 4 : Get All Threads */ jvmtiError (JNICALL *GetAllThreads) (jvmtiEnv* env, @@ -1213,8 +1235,11 @@ typedef struct jvmtiInterface_1_ { jmethodID method, jlocation location); - /* 40 : RESERVED */ - void *reserved40; + /* 40 : Get Named Module */ + jvmtiError (JNICALL *GetNamedModule) (jvmtiEnv* env, + jobject class_loader, + const char* package_name, + jobject* module_ptr); /* 41 : Set Field Access Watch */ jvmtiError (JNICALL *SetFieldAccessWatch) (jvmtiEnv* env, @@ -1492,23 +1517,38 @@ typedef struct jvmtiInterface_1_ { const jthread* request_list, jvmtiError* results); - /* 94 : RESERVED */ - void *reserved94; - - /* 95 : RESERVED */ - void *reserved95; - - /* 96 : RESERVED */ - void *reserved96; - - /* 97 : RESERVED */ - void *reserved97; - - /* 98 : RESERVED */ - void *reserved98; - - /* 99 : RESERVED */ - void *reserved99; + /* 94 : Add Module Reads */ + jvmtiError (JNICALL *AddModuleReads) (jvmtiEnv* env, + jobject module, + jobject to_module); + + /* 95 : Add Module Exports */ + jvmtiError (JNICALL *AddModuleExports) (jvmtiEnv* env, + jobject module, + const char* pkg_name, + jobject to_module); + + /* 96 : Add Module Opens */ + jvmtiError (JNICALL *AddModuleOpens) (jvmtiEnv* env, + jobject module, + const char* pkg_name, + jobject to_module); + + /* 97 : Add Module Uses */ + jvmtiError (JNICALL *AddModuleUses) (jvmtiEnv* env, + jobject module, + jclass service); + + /* 98 : Add Module Provides */ + jvmtiError (JNICALL *AddModuleProvides) (jvmtiEnv* env, + jobject module, + jclass service, + jclass impl_class); + + /* 99 : Is Modifiable Module */ + jvmtiError (JNICALL *IsModifiableModule) (jvmtiEnv* env, + jobject module, + jboolean* is_modifiable_module_ptr); /* 100 : Get All Stack Traces */ jvmtiError (JNICALL *GetAllStackTraces) (jvmtiEnv* env, @@ -1675,7 +1715,7 @@ typedef struct jvmtiInterface_1_ { /* 132 : Set System Property */ jvmtiError (JNICALL *SetSystemProperty) (jvmtiEnv* env, const char* property, - const char* value); + const char* value_ptr); /* 133 : Get Phase */ jvmtiError (JNICALL *GetPhase) (jvmtiEnv* env, @@ -1781,6 +1821,10 @@ typedef struct jvmtiInterface_1_ { jint depth, jobject* value_ptr); + /* 156 : Set Heap Sampling Interval */ + jvmtiError (JNICALL *SetHeapSamplingInterval) (jvmtiEnv* env, + jint sampling_interval); + } jvmtiInterface_1; struct _jvmtiEnv { @@ -2137,6 +2181,50 @@ struct _jvmtiEnv { return functions->ClearFieldModificationWatch(this, klass, field); } + jvmtiError GetAllModules(jint* module_count_ptr, + jobject** modules_ptr) { + return functions->GetAllModules(this, module_count_ptr, modules_ptr); + } + + jvmtiError GetNamedModule(jobject class_loader, + const char* package_name, + jobject* module_ptr) { + return functions->GetNamedModule(this, class_loader, package_name, module_ptr); + } + + jvmtiError AddModuleReads(jobject module, + jobject to_module) { + return functions->AddModuleReads(this, module, to_module); + } + + jvmtiError AddModuleExports(jobject module, + const char* pkg_name, + jobject to_module) { + return functions->AddModuleExports(this, module, pkg_name, to_module); + } + + jvmtiError AddModuleOpens(jobject module, + const char* pkg_name, + jobject to_module) { + return functions->AddModuleOpens(this, module, pkg_name, to_module); + } + + jvmtiError AddModuleUses(jobject module, + jclass service) { + return functions->AddModuleUses(this, module, service); + } + + jvmtiError AddModuleProvides(jobject module, + jclass service, + jclass impl_class) { + return functions->AddModuleProvides(this, module, service, impl_class); + } + + jvmtiError IsModifiableModule(jobject module, + jboolean* is_modifiable_module_ptr) { + return functions->IsModifiableModule(this, module, is_modifiable_module_ptr); + } + jvmtiError GetLoadedClasses(jint* class_count_ptr, jclass** classes_ptr) { return functions->GetLoadedClasses(this, class_count_ptr, classes_ptr); @@ -2484,8 +2572,8 @@ struct _jvmtiEnv { } jvmtiError SetSystemProperty(const char* property, - const char* value) { - return functions->SetSystemProperty(this, property, value); + const char* value_ptr) { + return functions->SetSystemProperty(this, property, value_ptr); } jvmtiError GetPhase(jvmtiPhase* phase_ptr) { @@ -2522,6 +2610,10 @@ struct _jvmtiEnv { return functions->GetJLocationFormat(this, format_ptr); } + jvmtiError SetHeapSamplingInterval(jint sampling_interval) { + return functions->SetHeapSamplingInterval(this, sampling_interval); + } + #endif /* __cplusplus */ }; @@ -2531,4 +2623,3 @@ struct _jvmtiEnv { #endif /* __cplusplus */ #endif /* !_JAVA_JVMTI_H_ */ - diff --git a/arthas-vmtool/src/main/native/head/jvmticmlr.h b/arthas-vmtool/src/main/native/head/jvmticmlr.h index a9c88f36e..c2106d3a7 100755 --- a/arthas-vmtool/src/main/native/head/jvmticmlr.h +++ b/arthas-vmtool/src/main/native/head/jvmticmlr.h @@ -1,26 +1,26 @@ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. - * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. */ /* diff --git a/arthas-vmtool/src/main/native/head/linux/jawt_md.h b/arthas-vmtool/src/main/native/head/linux/jawt_md.h index 825142ca8..2ba3a8e83 100644 --- a/arthas-vmtool/src/main/native/head/linux/jawt_md.h +++ b/arthas-vmtool/src/main/native/head/linux/jawt_md.h @@ -1,26 +1,26 @@ /* * Copyright (c) 1999, 2001, Oracle and/or its affiliates. All rights reserved. - * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. */ #ifndef _JAVASOFT_JAWT_MD_H_ @@ -28,7 +28,6 @@ #include #include -#include #include "jawt.h" #ifdef __cplusplus diff --git a/arthas-vmtool/src/main/native/head/linux/jni_md.h b/arthas-vmtool/src/main/native/head/linux/jni_md.h index ff30a32c3..6e583da71 100644 --- a/arthas-vmtool/src/main/native/head/linux/jni_md.h +++ b/arthas-vmtool/src/main/native/head/linux/jni_md.h @@ -1,26 +1,26 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. - * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. */ #ifndef _JAVASOFT_JNI_MD_H_ @@ -29,18 +29,33 @@ #ifndef __has_attribute #define __has_attribute(x) 0 #endif + +#ifndef JNIEXPORT + #if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility) + #ifdef ARM + #define JNIEXPORT __attribute__((externally_visible,visibility("default"))) + #else + #define JNIEXPORT __attribute__((visibility("default"))) + #endif + #else + #define JNIEXPORT + #endif +#endif + #if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility) - #define JNIEXPORT __attribute__((visibility("default"))) - #define JNIIMPORT __attribute__((visibility("default"))) + #ifdef ARM + #define JNIIMPORT __attribute__((externally_visible,visibility("default"))) + #else + #define JNIIMPORT __attribute__((visibility("default"))) + #endif #else - #define JNIEXPORT #define JNIIMPORT #endif #define JNICALL typedef int jint; -#ifdef _LP64 /* 64-bit Solaris */ +#ifdef _LP64 typedef long jlong; #else typedef long long jlong; diff --git a/arthas-vmtool/src/main/native/head/macos/jawt_md.h b/arthas-vmtool/src/main/native/head/macos/jawt_md.h index d803a0f7f..94a13c9ab 100644 --- a/arthas-vmtool/src/main/native/head/macos/jawt_md.h +++ b/arthas-vmtool/src/main/native/head/macos/jawt_md.h @@ -1,26 +1,26 @@ /* * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. - * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. */ #ifndef _JAVASOFT_JAWT_MD_H_ @@ -37,7 +37,7 @@ extern "C" { #endif /* - * Mac OS X specific declarations for AWT native interface. + * MacOS specific declarations for AWT native interface. * See notes in jawt.h for an example of use. */ diff --git a/arthas-vmtool/src/main/native/head/macos/jni_md.h b/arthas-vmtool/src/main/native/head/macos/jni_md.h index d2b83307f..f0cf64ebe 100644 --- a/arthas-vmtool/src/main/native/head/macos/jni_md.h +++ b/arthas-vmtool/src/main/native/head/macos/jni_md.h @@ -1,26 +1,26 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. - * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. */ #ifndef _JAVASOFT_JNI_MD_H_ diff --git a/arthas-vmtool/src/main/native/head/windows/AccessBridgeCallbacks.h b/arthas-vmtool/src/main/native/head/windows/AccessBridgeCallbacks.h index df5035b84..3f907d5f9 100755 --- a/arthas-vmtool/src/main/native/head/windows/AccessBridgeCallbacks.h +++ b/arthas-vmtool/src/main/native/head/windows/AccessBridgeCallbacks.h @@ -1,30 +1,26 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - */ - -/* - * AccessBridgeCallbacks.h 1.17 05/03/21 + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. */ /* diff --git a/arthas-vmtool/src/main/native/head/windows/AccessBridgeCalls.c b/arthas-vmtool/src/main/native/head/windows/AccessBridgeCalls.c index 368664818..105f342af 100755 --- a/arthas-vmtool/src/main/native/head/windows/AccessBridgeCalls.c +++ b/arthas-vmtool/src/main/native/head/windows/AccessBridgeCalls.c @@ -1,30 +1,33 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - */ - -/* - * @(#)AccessBridgeCalls.c 1.25 05/08/22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* @@ -40,7 +43,6 @@ //#define ACCESSBRIDGE_64 #include "AccessBridgeCalls.h" -#include "AccessBridgeDebug.h" #ifdef __cplusplus extern "C" { @@ -52,21 +54,19 @@ extern "C" { BOOL theAccessBridgeInitializedFlag = FALSE; #define LOAD_FP(result, type, name) \ - PrintDebugString("LOAD_FP loading: %s ...", name); \ if ((theAccessBridge.result = \ (type) GetProcAddress(theAccessBridgeInstance, name)) == (type) 0) { \ - PrintDebugString("LOAD_FP failed: %s", name); \ return FALSE; \ } BOOL initializeAccessBridge() { -#ifdef ACCESSBRIDGE_ARCH_32 // For 32bit AT new bridge +#ifdef ACCESSBRIDGE_ARCH_32 // For 32 bit AT interfacing with Java on 64 bit OS theAccessBridgeInstance = LoadLibrary("WINDOWSACCESSBRIDGE-32"); #else -#ifdef ACCESSBRIDGE_ARCH_64 // For 64bit AT new bridge +#ifdef ACCESSBRIDGE_ARCH_64 // For 64 bit AT interfacing with Java on 64 bit OS theAccessBridgeInstance = LoadLibrary("WINDOWSACCESSBRIDGE-64"); -#else // legacy +#else // For 32 bit AT interfacing with Java on 32 bit OS theAccessBridgeInstance = LoadLibrary("WINDOWSACCESSBRIDGE"); #endif #endif @@ -212,7 +212,6 @@ extern "C" { theAccessBridge.Windows_run(); theAccessBridgeInitializedFlag = TRUE; - PrintDebugString("theAccessBridgeInitializedFlag = TRUE"); return TRUE; } else { return FALSE; diff --git a/arthas-vmtool/src/main/native/head/windows/AccessBridgeCalls.h b/arthas-vmtool/src/main/native/head/windows/AccessBridgeCalls.h index ad0074009..46b42fd1c 100755 --- a/arthas-vmtool/src/main/native/head/windows/AccessBridgeCalls.h +++ b/arthas-vmtool/src/main/native/head/windows/AccessBridgeCalls.h @@ -1,24 +1,43 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* Note: In addition to this header file AccessBridgeCalls.c must be compiled and + * linked to your application. AccessBridgeCalls.c implements the Java Access + * Bridge API and also hides the complexities associated with interfacing to the + * associated Java Access Bridge DLL which is installed when Java is installed. * + * AccessBridgeCalls.c is available for download from the OpenJDK repository using + * the following link: * + * http://hg.openjdk.java.net/jdk9/jdk9/jdk/raw-file/tip/src/jdk.accessibility/windows/native/bridge/AccessBridgeCalls.c * + * Also note that the API is used in the jaccessinspector and jaccesswalker tools. + * The source for those tools is available in the OpenJDK repository at these links: * + * http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/tip/src/jdk.accessibility/windows/native/jaccessinspector/jaccessinspector.cpp + * http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/tip/src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalker.cpp * * */ diff --git a/arthas-vmtool/src/main/native/head/windows/AccessBridgePackages.h b/arthas-vmtool/src/main/native/head/windows/AccessBridgePackages.h index 478f7c636..27c31be09 100755 --- a/arthas-vmtool/src/main/native/head/windows/AccessBridgePackages.h +++ b/arthas-vmtool/src/main/native/head/windows/AccessBridgePackages.h @@ -1,26 +1,26 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. */ /* diff --git a/arthas-vmtool/src/main/native/head/windows/jawt_md.h b/arthas-vmtool/src/main/native/head/windows/jawt_md.h index 66e7256a2..7d43ff827 100755 --- a/arthas-vmtool/src/main/native/head/windows/jawt_md.h +++ b/arthas-vmtool/src/main/native/head/windows/jawt_md.h @@ -1,26 +1,26 @@ /* * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved. - * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. */ #ifndef _JAVASOFT_JAWT_MD_H_ diff --git a/arthas-vmtool/src/main/native/head/windows/jni_md.h b/arthas-vmtool/src/main/native/head/windows/jni_md.h index 38080013b..b8c144fb0 100755 --- a/arthas-vmtool/src/main/native/head/windows/jni_md.h +++ b/arthas-vmtool/src/main/native/head/windows/jni_md.h @@ -1,35 +1,38 @@ /* - * Copyright (c) 1996, 1998, Oracle and/or its affiliates. All rights reserved. - * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. */ #ifndef _JAVASOFT_JNI_MD_H_ #define _JAVASOFT_JNI_MD_H_ -#define JNIEXPORT __declspec(dllexport) +#ifndef JNIEXPORT + #define JNIEXPORT __declspec(dllexport) +#endif #define JNIIMPORT __declspec(dllimport) #define JNICALL __stdcall +// 'long' is always 32 bit on windows so this matches what jdk expects typedef long jint; typedef __int64 jlong; typedef signed char jbyte; diff --git a/bin/as.sh b/bin/as.sh index 956a0764a..466cd81c3 100755 --- a/bin/as.sh +++ b/bin/as.sh @@ -8,10 +8,10 @@ # program : Arthas # author : Core Engine @ Taobao.com -# date : 2021-07-22 +# date : 2021-09-02 # current arthas script version -ARTHAS_SCRIPT_VERSION=3.5.3 +ARTHAS_SCRIPT_VERSION=3.5.4 # SYNOPSIS # rreadlink @@ -453,7 +453,7 @@ EXAMPLES: ./as.sh --stat-url 'http://192.168.10.11:8080/api/stat' ./as.sh -c 'sysprop; thread' ./as.sh -f batch.as - ./as.sh --use-version 3.5.3 + ./as.sh --use-version 3.5.4 ./as.sh --session-timeout 3600 ./as.sh --attach-only ./as.sh --disabled-commands stop,dump diff --git a/boot/src/main/java/com/taobao/arthas/boot/Bootstrap.java b/boot/src/main/java/com/taobao/arthas/boot/Bootstrap.java index 9ff2cbe59..06d2a9b04 100644 --- a/boot/src/main/java/com/taobao/arthas/boot/Bootstrap.java +++ b/boot/src/main/java/com/taobao/arthas/boot/Bootstrap.java @@ -53,7 +53,7 @@ import com.taobao.middleware.cli.annotations.Summary; + " java -jar arthas-boot.jar --stat-url 'http://192.168.10.11:8080/api/stat'\n" + " java -jar arthas-boot.jar -c 'sysprop; thread' \n" + " java -jar arthas-boot.jar -f batch.as \n" - + " java -jar arthas-boot.jar --use-version 3.5.3\n" + + " java -jar arthas-boot.jar --use-version 3.5.4\n" + " java -jar arthas-boot.jar --versions\n" + " java -jar arthas-boot.jar --select math-game\n" + " java -jar arthas-boot.jar --session-timeout 3600\n" + " java -jar arthas-boot.jar --attach-only\n" @@ -694,14 +694,14 @@ public class Bootstrap { result.append("Local versions:\n"); for (String version : versionList) { - result.append(" " + version).append('\n'); + result.append(" ").append(version).append('\n'); } result.append("Remote versions:\n"); List remoteVersions = DownloadUtils.readRemoteVersions(); Collections.reverse(remoteVersions); for (String version : remoteVersions) { - result.append(" " + version).append('\n'); + result.append(" ").append(version).append('\n'); } return result.toString(); } diff --git a/client/src/main/java/com/taobao/arthas/client/TelnetConsole.java b/client/src/main/java/com/taobao/arthas/client/TelnetConsole.java index 7bf1a6d7d..8f223fca2 100644 --- a/client/src/main/java/com/taobao/arthas/client/TelnetConsole.java +++ b/client/src/main/java/com/taobao/arthas/client/TelnetConsole.java @@ -285,7 +285,7 @@ public class TelnetConsole { } // ctrl + c event callback - consoleReader.getKeys().bind(new Character((char) CTRL_C).toString(), new ActionListener() { + consoleReader.getKeys().bind(Character.toString((char) CTRL_C), new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { @@ -300,7 +300,7 @@ public class TelnetConsole { }); // ctrl + d event call back - consoleReader.getKeys().bind(new Character(KeyMap.CTRL_D).toString(), eotEventCallback); + consoleReader.getKeys().bind(Character.toString(KeyMap.CTRL_D), eotEventCallback); try { telnet.connect(telnetConsole.getTargetIp(), telnetConsole.getPort()); diff --git a/client/src/main/java/org/apache/commons/net/PrintCommandListener.java b/client/src/main/java/org/apache/commons/net/PrintCommandListener.java index 8fff4ed17..cf0bad4cb 100644 --- a/client/src/main/java/org/apache/commons/net/PrintCommandListener.java +++ b/client/src/main/java/org/apache/commons/net/PrintCommandListener.java @@ -180,11 +180,9 @@ public class PrintCommandListener implements ProtocolCommandListener } int pos = msg.indexOf(SocketClient.NETASCII_EOL); if (pos > 0) { - StringBuilder sb = new StringBuilder(); - sb.append(msg.substring(0,pos)); - sb.append(__eolMarker); - sb.append(msg.substring(pos)); - return sb.toString(); + return msg.substring(0, pos) + + __eolMarker + + msg.substring(pos); } return msg; } diff --git a/common/src/main/java/com/taobao/arthas/common/ReflectUtils.java b/common/src/main/java/com/taobao/arthas/common/ReflectUtils.java index bb7e3d155..7be111e77 100644 --- a/common/src/main/java/com/taobao/arthas/common/ReflectUtils.java +++ b/common/src/main/java/com/taobao/arthas/common/ReflectUtils.java @@ -212,7 +212,7 @@ public class ReflectUtils { while ((index = className.indexOf("[]", index) + 1) > 0) { dimensions++; } - StringBuffer brackets = new StringBuffer(className.length() - dimensions); + StringBuilder brackets = new StringBuilder(className.length() - dimensions); for (int i = 0; i < dimensions; i++) { brackets.append('['); } diff --git a/common/src/main/java/com/taobao/arthas/common/concurrent/ConcurrentWeakKeyHashMap.java b/common/src/main/java/com/taobao/arthas/common/concurrent/ConcurrentWeakKeyHashMap.java index a77770b29..2bff807b8 100644 --- a/common/src/main/java/com/taobao/arthas/common/concurrent/ConcurrentWeakKeyHashMap.java +++ b/common/src/main/java/com/taobao/arthas/common/concurrent/ConcurrentWeakKeyHashMap.java @@ -26,6 +26,7 @@ import java.lang.ref.WeakReference; import java.util.AbstractCollection; import java.util.AbstractMap; import java.util.AbstractSet; +import java.util.Arrays; import java.util.Collection; import java.util.ConcurrentModificationException; import java.util.Enumeration; @@ -619,10 +620,7 @@ public final class ConcurrentWeakKeyHashMap extends AbstractMap impl if (count != 0) { lock(); try { - HashEntry[] tab = table; - for (int i = 0; i < tab.length; i ++) { - tab[i] = null; - } + Arrays.fill(table, null); ++ modCount; // replace the reference queue to avoid unnecessary stale // cleanups diff --git a/core/src/main/java/arthas.properties b/core/src/main/java/arthas.properties index e562eea80..98457d5ba 100644 --- a/core/src/main/java/arthas.properties +++ b/core/src/main/java/arthas.properties @@ -12,6 +12,9 @@ arthas.sessionTimeout=1800 # arthas.username=arthas # arthas.password=arthas +# local connection non auth, like telnet 127.0.0.1 3658 +arthas.localConnectionNonAuth=true + #arthas.appName=demoapp #arthas.tunnelServer=ws://127.0.0.1:7777/ws #arthas.agentId=mmmmmmyiddddd diff --git a/core/src/main/java/com/taobao/arthas/core/command/basic1000/Base64Command.java b/core/src/main/java/com/taobao/arthas/core/command/basic1000/Base64Command.java index 8ad843704..5a572262f 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/basic1000/Base64Command.java +++ b/core/src/main/java/com/taobao/arthas/core/command/basic1000/Base64Command.java @@ -42,8 +42,8 @@ import io.netty.util.CharsetUtil; public class Base64Command extends AnnotatedCommand { private static final Logger logger = LoggerFactory.getLogger(Base64Command.class); private String file; - private Integer sizeLimit = 128 * 1024; - private int maxSizeLimit = 8 * 1024 * 1024; + private int sizeLimit = 128 * 1024; + private static final int MAX_SIZE_LIMIT = 8 * 1024 * 1024; private boolean decode; @@ -87,8 +87,13 @@ public class Base64Command extends AnnotatedCommand { } // 确认输入 - if (file == null && this.input != null) { - file = input; + if (file == null) { + if (this.input != null) { + file = input; + } else { + process.end(-1, ": No file, nor input"); + return; + } } File f = new File(file); @@ -145,8 +150,8 @@ public class Base64Command extends AnnotatedCommand { return false; } - if (sizeLimit > maxSizeLimit) { - process.end(-1, "sizeLimit cannot be large than: " + maxSizeLimit); + if (sizeLimit > MAX_SIZE_LIMIT) { + process.end(-1, "sizeLimit cannot be large than: " + MAX_SIZE_LIMIT); return false; } diff --git a/core/src/main/java/com/taobao/arthas/core/command/basic1000/EchoCommand.java b/core/src/main/java/com/taobao/arthas/core/command/basic1000/EchoCommand.java index b1db3f084..71e79cd0a 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/basic1000/EchoCommand.java +++ b/core/src/main/java/com/taobao/arthas/core/command/basic1000/EchoCommand.java @@ -2,7 +2,6 @@ package com.taobao.arthas.core.command.basic1000; import com.taobao.arthas.core.command.Constants; import com.taobao.arthas.core.command.model.EchoModel; -import com.taobao.arthas.core.command.model.MessageModel; import com.taobao.arthas.core.shell.command.AnnotatedCommand; import com.taobao.arthas.core.shell.command.CommandProcess; import com.taobao.middleware.cli.annotations.Argument; diff --git a/core/src/main/java/com/taobao/arthas/core/command/klass100/ClassLoaderCommand.java b/core/src/main/java/com/taobao/arthas/core/command/klass100/ClassLoaderCommand.java index efffde390..70ab73fba 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/klass100/ClassLoaderCommand.java +++ b/core/src/main/java/com/taobao/arthas/core/command/klass100/ClassLoaderCommand.java @@ -627,7 +627,7 @@ public class ClassLoaderCommand extends AnnotatedCommand { } } - private class ClassLoaderInterruptHandler implements Handler { + private static class ClassLoaderInterruptHandler implements Handler { private ClassLoaderCommand command; diff --git a/core/src/main/java/com/taobao/arthas/core/command/klass100/MemoryCompilerCommand.java b/core/src/main/java/com/taobao/arthas/core/command/klass100/MemoryCompilerCommand.java index 85a515a37..6e0a02362 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/klass100/MemoryCompilerCommand.java +++ b/core/src/main/java/com/taobao/arthas/core/command/klass100/MemoryCompilerCommand.java @@ -20,7 +20,6 @@ import com.taobao.arthas.core.shell.cli.Completion; import com.taobao.arthas.core.shell.cli.CompletionUtils; import com.taobao.arthas.core.shell.command.AnnotatedCommand; import com.taobao.arthas.core.shell.command.CommandProcess; -import com.taobao.arthas.core.util.ClassLoaderUtils; import com.taobao.arthas.core.util.FileUtils; import com.taobao.arthas.core.util.ClassUtils; import com.taobao.arthas.core.util.ClassLoaderUtils; diff --git a/core/src/main/java/com/taobao/arthas/core/command/model/GetStaticModel.java b/core/src/main/java/com/taobao/arthas/core/command/model/GetStaticModel.java index 0c013cdfc..0aa150f11 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/model/GetStaticModel.java +++ b/core/src/main/java/com/taobao/arthas/core/command/model/GetStaticModel.java @@ -1,7 +1,6 @@ package com.taobao.arthas.core.command.model; import java.util.Collection; -import java.util.List; /** * Data model of GetStaticCommand diff --git a/core/src/main/java/com/taobao/arthas/core/command/model/LoggerModel.java b/core/src/main/java/com/taobao/arthas/core/command/model/LoggerModel.java index 8c09bc942..0846141d4 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/model/LoggerModel.java +++ b/core/src/main/java/com/taobao/arthas/core/command/model/LoggerModel.java @@ -1,7 +1,6 @@ package com.taobao.arthas.core.command.model; import java.util.Collection; -import java.util.List; import java.util.Map; /** diff --git a/core/src/main/java/com/taobao/arthas/core/command/model/RetransformModel.java b/core/src/main/java/com/taobao/arthas/core/command/model/RetransformModel.java index c36885931..33ba7a02d 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/model/RetransformModel.java +++ b/core/src/main/java/com/taobao/arthas/core/command/model/RetransformModel.java @@ -5,7 +5,6 @@ import java.util.Collection; import java.util.List; import com.taobao.arthas.core.command.klass100.RetransformCommand.RetransformEntry; -import com.taobao.arthas.core.util.ClassUtils; /** * diff --git a/core/src/main/java/com/taobao/arthas/core/command/monitor200/DashboardCommand.java b/core/src/main/java/com/taobao/arthas/core/command/monitor200/DashboardCommand.java index 571c3b055..1b1738fc8 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/monitor200/DashboardCommand.java +++ b/core/src/main/java/com/taobao/arthas/core/command/monitor200/DashboardCommand.java @@ -38,6 +38,7 @@ import java.util.List; import java.util.Map; import java.util.Timer; import java.util.TimerTask; +import java.util.concurrent.atomic.AtomicLong; import static com.taobao.arthas.core.command.model.MemoryEntryVO.TYPE_BUFFER_POOL; import static com.taobao.arthas.core.command.model.MemoryEntryVO.TYPE_HEAP; @@ -66,7 +67,7 @@ public class DashboardCommand extends AnnotatedCommand { private long interval = 5000; - private volatile long count = 0; + private final AtomicLong count = new AtomicLong(0); private volatile Timer timer; @Option(shortName = "n", longName = "number-of-execution") @@ -207,7 +208,7 @@ public class DashboardCommand extends AnnotatedCommand { runtimeInfo.setSystemLoadAverage(ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage()); runtimeInfo.setProcessors(Runtime.getRuntime().availableProcessors()); runtimeInfo.setUptime(ManagementFactory.getRuntimeMXBean().getUptime() / 1000); - runtimeInfo.setTimestamp(new Date().getTime()); + runtimeInfo.setTimestamp(System.currentTimeMillis()); dashboardModel.setRuntimeInfo(runtimeInfo); } @@ -297,7 +298,7 @@ public class DashboardCommand extends AnnotatedCommand { @Override public void run() { try { - if (count >= getNumOfExecutions()) { + if (count.get() >= getNumOfExecutions()) { // stop the timer timer.cancel(); timer.purge(); @@ -329,7 +330,7 @@ public class DashboardCommand extends AnnotatedCommand { process.appendResult(dashboardModel); - count++; + count.getAndIncrement(); process.times().incrementAndGet(); } catch (Throwable e) { String msg = "process dashboard failed: " + e.getMessage(); diff --git a/core/src/main/java/com/taobao/arthas/core/command/monitor200/EnhancerCommand.java b/core/src/main/java/com/taobao/arthas/core/command/monitor200/EnhancerCommand.java index 2c7904875..6894948de 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/monitor200/EnhancerCommand.java +++ b/core/src/main/java/com/taobao/arthas/core/command/monitor200/EnhancerCommand.java @@ -20,17 +20,11 @@ import com.taobao.arthas.core.shell.handlers.shell.QExitHandler; import com.taobao.arthas.core.shell.session.Session; import com.taobao.arthas.core.util.Constants; import com.taobao.arthas.core.util.LogUtil; -import com.taobao.arthas.core.util.SearchUtils; import com.taobao.arthas.core.util.affect.EnhancerAffect; import com.taobao.arthas.core.util.matcher.Matcher; import com.taobao.arthas.core.view.Ansi; -import com.taobao.middleware.cli.annotations.Argument; import com.taobao.middleware.cli.annotations.Description; import com.taobao.middleware.cli.annotations.Option; -import com.taobao.text.Color; -import com.taobao.text.Decoration; -import com.taobao.text.ui.LabelElement; -import com.taobao.text.util.RenderUtil; /** * @author beiwei30 on 29/11/2016. diff --git a/core/src/main/java/com/taobao/arthas/core/command/monitor200/MBeanCommand.java b/core/src/main/java/com/taobao/arthas/core/command/monitor200/MBeanCommand.java index 563281337..03dfd6579 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/monitor200/MBeanCommand.java +++ b/core/src/main/java/com/taobao/arthas/core/command/monitor200/MBeanCommand.java @@ -349,7 +349,7 @@ public class MBeanCommand extends AnnotatedCommand { } - public class MBeanInterruptHandler extends CommandInterruptHandler { + public static class MBeanInterruptHandler extends CommandInterruptHandler { private volatile Timer timer; diff --git a/core/src/main/java/com/taobao/arthas/core/command/monitor200/ProfilerCommand.java b/core/src/main/java/com/taobao/arthas/core/command/monitor200/ProfilerCommand.java index d5ad8afbd..3578f4724 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/monitor200/ProfilerCommand.java +++ b/core/src/main/java/com/taobao/arthas/core/command/monitor200/ProfilerCommand.java @@ -253,7 +253,7 @@ public class ProfilerCommand extends AnnotatedCommand { try { File tmpLibFile = File.createTempFile(VmTool.JNI_LIBRARY_NAME, null); tmpLibOutputStream = new FileOutputStream(tmpLibFile); - libInputStream = new FileInputStream(new File(libPath)); + libInputStream = new FileInputStream(libPath); IOUtils.copy(libInputStream, tmpLibOutputStream); libPath = tmpLibFile.getAbsolutePath(); diff --git a/core/src/main/java/com/taobao/arthas/core/command/monitor200/VmToolCommand.java b/core/src/main/java/com/taobao/arthas/core/command/monitor200/VmToolCommand.java index 0a8669b56..133b14f3b 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/monitor200/VmToolCommand.java +++ b/core/src/main/java/com/taobao/arthas/core/command/monitor200/VmToolCommand.java @@ -163,8 +163,14 @@ public class VmToolCommand extends AnnotatedCommand { process.end(-1, "The className option cannot be empty!"); return; } - ClassLoader classLoader = ClassLoader.getSystemClassLoader(); - if (hashCode == null && classLoaderClass != null) { + ClassLoader classLoader = null; + if (hashCode != null) { + classLoader = ClassLoaderUtils.getClassLoader(inst, hashCode); + if (classLoader == null) { + process.end(-1, "Can not find classloader with hashCode: " + hashCode + "."); + return; + } + }else if ( classLoaderClass != null) { List matchedClassLoaders = ClassLoaderUtils.getClassLoaderByClassName(inst, classLoaderClass); if (matchedClassLoaders.size() == 1) { @@ -183,6 +189,8 @@ public class VmToolCommand extends AnnotatedCommand { process.end(-1, "Can not find classloader by class name: " + classLoaderClass + "."); return; } + }else { + classLoader = ClassLoader.getSystemClassLoader(); } List> matchedClasses = new ArrayList>( @@ -256,7 +264,7 @@ public class VmToolCommand extends AnnotatedCommand { try { File tmpLibFile = File.createTempFile(VmTool.JNI_LIBRARY_NAME, null); tmpLibOutputStream = new FileOutputStream(tmpLibFile); - libInputStream = new FileInputStream(new File(libPath)); + libInputStream = new FileInputStream(libPath); IOUtils.copy(libInputStream, tmpLibOutputStream); libPath = tmpLibFile.getAbsolutePath(); diff --git a/core/src/main/java/com/taobao/arthas/core/command/monitor200/WatchCommand.java b/core/src/main/java/com/taobao/arthas/core/command/monitor200/WatchCommand.java index 3d009fc44..f4a651305 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/monitor200/WatchCommand.java +++ b/core/src/main/java/com/taobao/arthas/core/command/monitor200/WatchCommand.java @@ -20,13 +20,12 @@ import com.taobao.middleware.cli.annotations.Summary; @Name("watch") @Summary("Display the input/output parameter, return object, and thrown exception of specified method invocation") @Description(Constants.EXPRESS_DESCRIPTION + "\nExamples:\n" + - " watch -b org.apache.commons.lang.StringUtils isBlank params\n" + - " watch -f org.apache.commons.lang.StringUtils isBlank returnObj\n" + - " watch org.apache.commons.lang.StringUtils isBlank '{params, target, returnObj}' -x 2\n" + - " watch -bf *StringUtils isBlank params\n" + - " watch *StringUtils isBlank params[0]\n" + + " watch org.apache.commons.lang.StringUtils isBlank\n" + + " watch org.apache.commons.lang.StringUtils isBlank '{params, target, returnObj, throwExp}' -x 2\n" + " watch *StringUtils isBlank params[0] params[0].length==1\n" + " watch *StringUtils isBlank params '#cost>100'\n" + + " watch -f *StringUtils isBlank params\n" + + " watch *StringUtils isBlank params[0]\n" + " watch -E -b org\\.apache\\.commons\\.lang\\.StringUtils isBlank params[0]\n" + " watch javax.servlet.Filter * --exclude-class-pattern com.demo.TestFilter\n" + Constants.WIKI + Constants.WIKI_HOME + "watch") @@ -59,7 +58,7 @@ public class WatchCommand extends EnhancerCommand { @Argument(index = 2, argName = "express", required = false) @DefaultValue("{params, target, returnObj}") - @Description("the content you want to watch, written by ognl.\n" + Constants.EXPRESS_EXAMPLES) + @Description("The content you want to watch, written by ognl. Default value is '{params, target, returnObj}'\n" + Constants.EXPRESS_EXAMPLES) public void setExpress(String express) { this.express = express; } diff --git a/core/src/main/java/com/taobao/arthas/core/command/view/LoggerView.java b/core/src/main/java/com/taobao/arthas/core/command/view/LoggerView.java index 40c29b09e..e065516e4 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/view/LoggerView.java +++ b/core/src/main/java/com/taobao/arthas/core/command/view/LoggerView.java @@ -3,7 +3,6 @@ package com.taobao.arthas.core.command.view; import com.taobao.arthas.core.command.logger.LoggerHelper; import com.taobao.arthas.core.command.model.LoggerModel; import com.taobao.arthas.core.shell.command.CommandProcess; -import com.taobao.arthas.core.util.StringUtils; import com.taobao.text.Decoration; import com.taobao.text.ui.TableElement; import com.taobao.text.util.RenderUtil; diff --git a/core/src/main/java/com/taobao/arthas/core/command/view/MBeanView.java b/core/src/main/java/com/taobao/arthas/core/command/view/MBeanView.java index af7feb83c..28ad3eed7 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/view/MBeanView.java +++ b/core/src/main/java/com/taobao/arthas/core/command/view/MBeanView.java @@ -17,7 +17,6 @@ import java.util.Map; import static com.taobao.text.ui.Element.label; import static javax.management.MBeanOperationInfo.*; -import static javax.management.MBeanOperationInfo.UNKNOWN; /** * View of 'mbean' command diff --git a/core/src/main/java/com/taobao/arthas/core/command/view/TraceView.java b/core/src/main/java/com/taobao/arthas/core/command/view/TraceView.java index f7e58185d..d30ba0788 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/view/TraceView.java +++ b/core/src/main/java/com/taobao/arthas/core/command/view/TraceView.java @@ -98,10 +98,10 @@ public class TraceView extends ResultView { //trace_id if (threadNode.getTraceId() != null) { - sb.append(";trace_id="+threadNode.getTraceId()); + sb.append(";trace_id=").append(threadNode.getTraceId()); } if (threadNode.getRpcId() != null) { - sb.append(";rpc_id="+threadNode.getRpcId()); + sb.append(";rpc_id=").append(threadNode.getRpcId()); } } else if (node instanceof ThrowNode) { ThrowNode throwNode = (ThrowNode) node; diff --git a/core/src/main/java/com/taobao/arthas/core/command/view/ViewRenderUtil.java b/core/src/main/java/com/taobao/arthas/core/command/view/ViewRenderUtil.java index a7799c1ac..6980abf0e 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/view/ViewRenderUtil.java +++ b/core/src/main/java/com/taobao/arthas/core/command/view/ViewRenderUtil.java @@ -97,7 +97,7 @@ public class ViewRenderUtil { affectVO.getListenerId())); if (affectVO.getThrowable() != null) { - infoSB.append("\nEnhance error! exception: " + affectVO.getThrowable()); + infoSB.append("\nEnhance error! exception: ").append(affectVO.getThrowable()); } infoSB.append("\n"); diff --git a/core/src/main/java/com/taobao/arthas/core/config/Configure.java b/core/src/main/java/com/taobao/arthas/core/config/Configure.java index 433b22131..14780a0d7 100644 --- a/core/src/main/java/com/taobao/arthas/core/config/Configure.java +++ b/core/src/main/java/com/taobao/arthas/core/config/Configure.java @@ -10,7 +10,11 @@ import java.util.Map; import static java.lang.reflect.Modifier.isStatic; /** - * 配置类 + *
+ * 配置类。
+ * 注意本类里的所有字段不能有默认值,否则会出现配置混乱。
+ * 在 com.taobao.arthas.core.Arthas#attach 里会调用 Configure#toStrig
+ * 
  *
  * @author vlinux
  * @author hengyunabc 2018-11-12
@@ -65,6 +69,11 @@ public class Configure {
      */
     private String disabledCommands;
 
+    /**
+     * 本地连接不需要鉴权,即使配置了password。arthas.properties 里默认为true
+     */
+    private Boolean localConnectionNonAuth;
+
     public String getIp() {
         return ip;
     }
@@ -193,6 +202,14 @@ public class Configure {
         this.disabledCommands = disabledCommands;
     }
 
+    public boolean isLocalConnectionNonAuth() {
+        return localConnectionNonAuth != null && localConnectionNonAuth;
+    }
+
+    public void setLocalConnectionNonAuth(boolean localConnectionNonAuth) {
+        this.localConnectionNonAuth = localConnectionNonAuth;
+    }
+
     /**
      * 序列化成字符串
      *
diff --git a/core/src/main/java/com/taobao/arthas/core/distribution/impl/SharingResultDistributorImpl.java b/core/src/main/java/com/taobao/arthas/core/distribution/impl/SharingResultDistributorImpl.java
index 3ecd4ca2a..680974735 100644
--- a/core/src/main/java/com/taobao/arthas/core/distribution/impl/SharingResultDistributorImpl.java
+++ b/core/src/main/java/com/taobao/arthas/core/distribution/impl/SharingResultDistributorImpl.java
@@ -135,7 +135,7 @@ public class SharingResultDistributorImpl implements SharingResultDistributor {
         }
     }
 
-    private class SharingResultConsumerImpl implements ResultConsumer {
+    private static class SharingResultConsumerImpl implements ResultConsumer {
         private BlockingQueue resultQueue = new ArrayBlockingQueue(DistributorOptions.resultQueueSize);
         private ReentrantLock queueLock = new ReentrantLock();
         private InputStatusModel lastInputStatus;
diff --git a/core/src/main/java/com/taobao/arthas/core/security/AuthUtils.java b/core/src/main/java/com/taobao/arthas/core/security/AuthUtils.java
new file mode 100644
index 000000000..7a9895782
--- /dev/null
+++ b/core/src/main/java/com/taobao/arthas/core/security/AuthUtils.java
@@ -0,0 +1,37 @@
+package com.taobao.arthas.core.security;
+
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.security.Principal;
+
+import com.taobao.arthas.core.config.Configure;
+import com.taobao.arthas.core.server.ArthasBootstrap;
+
+import io.netty.channel.ChannelHandlerContext;
+
+/**
+ * 
+ * @author hengyunabc 2021-09-01
+ *
+ */
+public class AuthUtils {
+    private static Configure configure = ArthasBootstrap.getInstance().getConfigure();
+
+    public static Principal localPrincipal(ChannelHandlerContext ctx) {
+        if (configure.isLocalConnectionNonAuth() && isLocalConnection(ctx)) {
+            return new LocalConnectionPrincipal();
+        }
+        return null;
+    }
+
+    public static boolean isLocalConnection(ChannelHandlerContext ctx) {
+        SocketAddress remoteAddress = ctx.channel().remoteAddress();
+        if (remoteAddress instanceof InetSocketAddress) {
+            String hostAddress = ((InetSocketAddress) remoteAddress).getAddress().getHostAddress();
+            if ("127.0.0.1".equals(hostAddress)) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/core/src/main/java/com/taobao/arthas/core/security/LocalConnectionPrincipal.java b/core/src/main/java/com/taobao/arthas/core/security/LocalConnectionPrincipal.java
new file mode 100644
index 000000000..06b8e1d88
--- /dev/null
+++ b/core/src/main/java/com/taobao/arthas/core/security/LocalConnectionPrincipal.java
@@ -0,0 +1,27 @@
+package com.taobao.arthas.core.security;
+
+import java.security.Principal;
+
+/**
+ * 本地连接的特殊处理 {@link Principal}.
+ * 
+ * @author hengyunabc 2021-09-01
+ */
+public final class LocalConnectionPrincipal implements Principal {
+
+    public LocalConnectionPrincipal() {
+    }
+
+    @Override
+    public String getName() {
+        return null;
+    }
+
+    public String getUsername() {
+        return null;
+    }
+
+    public String getPassword() {
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/core/src/main/java/com/taobao/arthas/core/security/SecurityAuthenticatorImpl.java b/core/src/main/java/com/taobao/arthas/core/security/SecurityAuthenticatorImpl.java
index e43bd19d8..88b6f4425 100644
--- a/core/src/main/java/com/taobao/arthas/core/security/SecurityAuthenticatorImpl.java
+++ b/core/src/main/java/com/taobao/arthas/core/security/SecurityAuthenticatorImpl.java
@@ -66,6 +66,9 @@ public class SecurityAuthenticatorImpl implements SecurityAuthenticator {
                 return subject;
             }
         }
+        if (principal instanceof LocalConnectionPrincipal) {
+            return subject;
+        }
 
         return null;
     }
diff --git a/core/src/main/java/com/taobao/arthas/core/server/ArthasBootstrap.java b/core/src/main/java/com/taobao/arthas/core/server/ArthasBootstrap.java
index 2ffd72bac..2b29def1d 100644
--- a/core/src/main/java/com/taobao/arthas/core/server/ArthasBootstrap.java
+++ b/core/src/main/java/com/taobao/arthas/core/server/ArthasBootstrap.java
@@ -144,7 +144,7 @@ public class ArthasBootstrap {
         outputPath.mkdirs();
 
         // 3. init logger
-        loggerContext = LogUtil.initLooger(arthasEnvironment);
+        loggerContext = LogUtil.initLogger(arthasEnvironment);
 
         // 4. 增强ClassLoader
         enhanceClassLoader();
@@ -665,4 +665,7 @@ public class ArthasBootstrap {
         return securityAuthenticator;
     }
 
+    public Configure getConfigure() {
+        return configure;
+    }
 }
diff --git a/core/src/main/java/com/taobao/arthas/core/shell/ShellServer.java b/core/src/main/java/com/taobao/arthas/core/shell/ShellServer.java
index b69ae4255..ff11ac2ea 100644
--- a/core/src/main/java/com/taobao/arthas/core/shell/ShellServer.java
+++ b/core/src/main/java/com/taobao/arthas/core/shell/ShellServer.java
@@ -78,9 +78,8 @@ public abstract class ShellServer {
     /**
      * Start the shell service, this is an asynchronous start.
      */
-    @SuppressWarnings("unchecked")
     public ShellServer listen() {
-        return listen(new NoOpHandler());
+        return listen(new NoOpHandler>());
     }
 
     /**
@@ -93,9 +92,8 @@ public abstract class ShellServer {
     /**
      * Close the shell server, this is an asynchronous close.
      */
-    @SuppressWarnings("unchecked")
     public void close() {
-        close(new NoOpHandler());
+        close(new NoOpHandler>());
     }
 
     /**
diff --git a/core/src/main/java/com/taobao/arthas/core/shell/cli/CompletionUtils.java b/core/src/main/java/com/taobao/arthas/core/shell/cli/CompletionUtils.java
index c49e5d125..915afe35c 100644
--- a/core/src/main/java/com/taobao/arthas/core/shell/cli/CompletionUtils.java
+++ b/core/src/main/java/com/taobao/arthas/core/shell/cli/CompletionUtils.java
@@ -121,12 +121,14 @@ public class CompletionUtils {
         File[] listFiles = dir.listFiles();
 
         ArrayList names = new ArrayList();
-        for (File child : listFiles) {
-            if (child.getName().startsWith(partName)) {
-                if (child.isDirectory()) {
-                    names.add(child.getName() + "/");
-                } else {
-                    names.add(child.getName());
+        if (listFiles != null) {
+            for (File child : listFiles) {
+                if (child.getName().startsWith(partName)) {
+                    if (child.isDirectory()) {
+                        names.add(child.getName() + "/");
+                    } else {
+                        names.add(child.getName());
+                    }
                 }
             }
         }
@@ -134,7 +136,7 @@ public class CompletionUtils {
         if (names.size() == 1 && names.get(0).endsWith("/")) {
             String name = names.get(0);
             // 这个函数补全后不会有空格,并且只能传入要补全的内容
-            completion.complete(name.substring(tokenFileName.length(), name.length()), false);
+            completion.complete(name.substring(tokenFileName.length()), false);
             return true;
         }
 
@@ -312,7 +314,7 @@ public class CompletionUtils {
                 if (commonPrefix.length() == prefix.length()) {
                     completion.complete(candidates);
                 } else {
-                    completion.complete(commonPrefix.substring(prefix.length(), commonPrefix.length()), false);
+                    completion.complete(commonPrefix.substring(prefix.length()), false);
                 }
 
             } else {
diff --git a/core/src/main/java/com/taobao/arthas/core/shell/command/internal/WordCountHandler.java b/core/src/main/java/com/taobao/arthas/core/shell/command/internal/WordCountHandler.java
index 640de22b5..90742911b 100644
--- a/core/src/main/java/com/taobao/arthas/core/shell/command/internal/WordCountHandler.java
+++ b/core/src/main/java/com/taobao/arthas/core/shell/command/internal/WordCountHandler.java
@@ -6,6 +6,7 @@ import com.taobao.middleware.cli.CommandLine;
 import com.taobao.middleware.cli.Option;
 
 import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * @author ralf0131 2017-02-23 23:28.
@@ -17,14 +18,14 @@ public class WordCountHandler extends StdoutHandler implements StatisticsFunctio
     private boolean lineMode;
 
     private String result = null;
-    private volatile int total = 0;
+    private final AtomicInteger total = new AtomicInteger(0);
 
     public static StdoutHandler inject(List tokens) {
         List args = StdoutHandler.parseArgs(tokens, NAME);
         CommandLine commandLine = CLIs.create(NAME)
                 .addOption(new Option().setShortName("l").setFlag(true))
                 .parse(args);
-        Boolean lineMode = commandLine.isFlagEnabled("l");
+        boolean lineMode = commandLine.isFlagEnabled("l");
         return new WordCountHandler(lineMode);
     }
 
@@ -39,7 +40,7 @@ public class WordCountHandler extends StdoutHandler implements StatisticsFunctio
             result = "wc currently only support wc -l!\n";
         } else {
             if (input != null && !"".equals(input.trim())) {
-                total += input.split("\n").length;
+                total.getAndAdd(input.split("\n").length);
             }
         }
 
@@ -52,6 +53,6 @@ public class WordCountHandler extends StdoutHandler implements StatisticsFunctio
             return result;
         }
 
-        return total + "\n";
+        return total.get() + "\n";
     }
 }
diff --git a/core/src/main/java/com/taobao/arthas/core/shell/handlers/NoOpHandler.java b/core/src/main/java/com/taobao/arthas/core/shell/handlers/NoOpHandler.java
index 3c80c8c0a..b651764dd 100644
--- a/core/src/main/java/com/taobao/arthas/core/shell/handlers/NoOpHandler.java
+++ b/core/src/main/java/com/taobao/arthas/core/shell/handlers/NoOpHandler.java
@@ -7,12 +7,12 @@ import com.taobao.arthas.core.shell.future.Future;
 /**
  * @author beiwei30 on 22/11/2016.
  */
-public class NoOpHandler implements Handler {
+public class NoOpHandler implements Handler {
 
     private static final Logger logger = LoggerFactory.getLogger(NoOpHandler.class);
 
     @Override
-    public void handle(Object event) {
+    public void handle(E event) {
         if (event instanceof Future && ((Future) event).failed()) {
             logger.error("Error listening term server:", ((Future) event).cause());
         }
diff --git a/core/src/main/java/com/taobao/arthas/core/shell/history/impl/HistoryManagerImpl.java b/core/src/main/java/com/taobao/arthas/core/shell/history/impl/HistoryManagerImpl.java
index c6853a9b7..205331fe4 100644
--- a/core/src/main/java/com/taobao/arthas/core/shell/history/impl/HistoryManagerImpl.java
+++ b/core/src/main/java/com/taobao/arthas/core/shell/history/impl/HistoryManagerImpl.java
@@ -11,6 +11,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 /**
+ * @see io.termd.core.readline.Readline#history
  * @author gongdewei 2020/4/8
  */
 public class HistoryManagerImpl implements HistoryManager {
diff --git a/core/src/main/java/com/taobao/arthas/core/shell/impl/BuiltinCommandResolver.java b/core/src/main/java/com/taobao/arthas/core/shell/impl/BuiltinCommandResolver.java
index ae497c5cb..122b05c87 100644
--- a/core/src/main/java/com/taobao/arthas/core/shell/impl/BuiltinCommandResolver.java
+++ b/core/src/main/java/com/taobao/arthas/core/shell/impl/BuiltinCommandResolver.java
@@ -21,7 +21,7 @@ class BuiltinCommandResolver implements CommandResolver {
     private Handler handler;
 
     public BuiltinCommandResolver() {
-        this.handler = new NoOpHandler();
+        this.handler = new NoOpHandler();
     }
 
     @Override
diff --git a/core/src/main/java/com/taobao/arthas/core/shell/impl/ShellImpl.java b/core/src/main/java/com/taobao/arthas/core/shell/impl/ShellImpl.java
index f69002adf..c37b43033 100644
--- a/core/src/main/java/com/taobao/arthas/core/shell/impl/ShellImpl.java
+++ b/core/src/main/java/com/taobao/arthas/core/shell/impl/ShellImpl.java
@@ -2,6 +2,10 @@ package com.taobao.arthas.core.shell.impl;
 
 import com.alibaba.arthas.deps.org.slf4j.Logger;
 import com.alibaba.arthas.deps.org.slf4j.LoggerFactory;
+import com.taobao.arthas.common.ArthasConstants;
+import com.taobao.arthas.core.security.AuthUtils;
+import com.taobao.arthas.core.security.SecurityAuthenticator;
+import com.taobao.arthas.core.server.ArthasBootstrap;
 import com.taobao.arthas.core.shell.Shell;
 import com.taobao.arthas.core.shell.ShellServer;
 import com.taobao.arthas.core.shell.cli.CliToken;
@@ -22,10 +26,15 @@ import com.taobao.arthas.core.shell.term.impl.http.ExtHttpTtyConnection;
 import com.taobao.arthas.core.util.Constants;
 import com.taobao.arthas.core.util.FileUtils;
 
+import io.netty.channel.ChannelHandlerContext;
+import io.termd.core.telnet.TelnetConnection;
+import io.termd.core.telnet.TelnetTtyConnection;
+import io.termd.core.telnet.netty.NettyTelnetConnection;
 import io.termd.core.tty.TtyConnection;
 
 import java.io.File;
 import java.lang.instrument.Instrumentation;
+import java.security.Principal;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -33,14 +42,17 @@ import java.util.Map.Entry;
 import java.util.Set;
 import java.util.UUID;
 
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginException;
+
 /**
  * The shell session as seen from the shell server perspective.
  *
  * @author Julien Viet
  */
 public class ShellImpl implements Shell {
-
     private static final Logger logger = LoggerFactory.getLogger(ShellImpl.class);
+    private SecurityAuthenticator securityAuthenticator = ArthasBootstrap.getInstance().getSecurityAuthenticator();
 
     private JobControllerImpl jobController;
     final String id;
@@ -57,6 +69,26 @@ public class ShellImpl implements Shell {
         if (term instanceof TermImpl) {
             TermImpl termImpl = (TermImpl) term;
             TtyConnection conn = termImpl.getConn();
+            // 处理telnet本地连接鉴权
+            if (conn instanceof TelnetTtyConnection) {
+                TelnetConnection telnetConnection = ((TelnetTtyConnection) conn).getTelnetConnection();
+                if (telnetConnection instanceof NettyTelnetConnection) {
+                    ChannelHandlerContext handlerContext = ((NettyTelnetConnection) telnetConnection)
+                            .channelHandlerContext();
+                    Principal principal = AuthUtils.localPrincipal(handlerContext);
+                    if (principal != null) {
+                        try {
+                            Subject subject = securityAuthenticator.login(principal);
+                            if (subject != null) {
+                                session.put(ArthasConstants.SUBJECT_KEY, subject);
+                            }
+                        } catch (LoginException e) {
+                            logger.error("local connection auth error", e);
+                        }
+                    }
+                }
+            }
+
             if (conn instanceof ExtHttpTtyConnection) {
                 // 传递http cookie 里的鉴权信息到新建立的session中
                 ExtHttpTtyConnection extConn = (ExtHttpTtyConnection) conn;
@@ -126,11 +158,9 @@ public class ShellImpl implements Shell {
     }
 
     private void setPrompt(){
-        StringBuilder stringBuilder = new StringBuilder();
-        stringBuilder.append("[arthas@");
-        stringBuilder.append(session.getPid());
-        stringBuilder.append("]$ ");
-        this.prompt = stringBuilder.toString();
+        this.prompt = "[arthas@" +
+                session.getPid() +
+                "]$ ";
     }
 
     public ShellImpl init() {
@@ -197,7 +227,7 @@ public class ShellImpl implements Shell {
         return currentForegroundJob;
     }
 
-    private class ShellJobHandler implements JobListener {
+    private static class ShellJobHandler implements JobListener {
         ShellImpl shell;
 
         public ShellJobHandler(ShellImpl shell) {
diff --git a/core/src/main/java/com/taobao/arthas/core/shell/system/impl/JobImpl.java b/core/src/main/java/com/taobao/arthas/core/shell/system/impl/JobImpl.java
index c960f5d53..2f0085042 100644
--- a/core/src/main/java/com/taobao/arthas/core/shell/system/impl/JobImpl.java
+++ b/core/src/main/java/com/taobao/arthas/core/shell/system/impl/JobImpl.java
@@ -1,8 +1,6 @@
 package com.taobao.arthas.core.shell.system.impl;
 
-import java.io.File;
 import java.util.Date;
-import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import com.taobao.arthas.core.shell.future.Future;
diff --git a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/CompletionHandler.java b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/CompletionHandler.java
index 41c2a90f5..dda67c227 100644
--- a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/CompletionHandler.java
+++ b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/CompletionHandler.java
@@ -6,7 +6,6 @@ import com.taobao.arthas.core.shell.cli.CliToken;
 import com.taobao.arthas.core.shell.cli.CliTokens;
 import com.taobao.arthas.core.shell.handlers.Handler;
 import com.taobao.arthas.core.shell.session.Session;
-import com.taobao.arthas.core.shell.term.impl.httptelnet.HttpTelnetTermServer;
 
 import io.termd.core.function.Consumer;
 import io.termd.core.readline.Completion;
diff --git a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/Helper.java b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/Helper.java
index c74322043..54e146048 100644
--- a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/Helper.java
+++ b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/Helper.java
@@ -4,7 +4,6 @@ import com.alibaba.arthas.deps.org.slf4j.Logger;
 import com.alibaba.arthas.deps.org.slf4j.LoggerFactory;
 import com.taobao.arthas.core.shell.ShellServerOptions;
 import com.taobao.arthas.core.shell.term.TermServer;
-import com.taobao.arthas.core.shell.term.impl.httptelnet.HttpTelnetTermServer;
 import io.termd.core.readline.Keymap;
 
 import java.io.FileInputStream;
diff --git a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/BasicHttpAuthenticatorHandler.java b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/BasicHttpAuthenticatorHandler.java
index b14975cd1..f19491e56 100644
--- a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/BasicHttpAuthenticatorHandler.java
+++ b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/BasicHttpAuthenticatorHandler.java
@@ -1,6 +1,7 @@
 package com.taobao.arthas.core.shell.term.impl.http;
 
 import java.nio.charset.Charset;
+import java.security.Principal;
 import java.util.List;
 import java.util.Map;
 
@@ -9,6 +10,7 @@ import javax.security.auth.Subject;
 import com.alibaba.arthas.deps.org.slf4j.Logger;
 import com.alibaba.arthas.deps.org.slf4j.LoggerFactory;
 import com.taobao.arthas.common.ArthasConstants;
+import com.taobao.arthas.core.security.AuthUtils;
 import com.taobao.arthas.core.security.BasicPrincipal;
 import com.taobao.arthas.core.security.SecurityAuthenticator;
 import com.taobao.arthas.core.server.ArthasBootstrap;
@@ -64,18 +66,23 @@ public final class BasicHttpAuthenticatorHandler extends ChannelDuplexHandler {
                 authed = true;
             }
 
+            Principal principal = null;
             if (!authed) {
                 // 判断请求header里是否带有 username/password
-                BasicPrincipal principal = extractBasicAuthSubject(httpRequest);
+                principal = extractBasicAuthSubject(httpRequest);
                 if (principal == null) {
                     // 判断 url里是否有 username/password
                     principal = extractBasicAuthSubjectFromUrl(httpRequest);
                 }
-                Subject subject = securityAuthenticator.login(principal);
-                if (subject != null) {
-                    authed = true;
-                    session.setAttribute(ArthasConstants.SUBJECT_KEY, subject);
-                }
+            }
+            if (!authed && principal == null) {
+                // 判断是否本地连接
+                principal = AuthUtils.localPrincipal(ctx);
+            }
+            Subject subject = securityAuthenticator.login(principal);
+            if (subject != null) {
+                authed = true;
+                session.setAttribute(ArthasConstants.SUBJECT_KEY, subject);
             }
 
             if (!authed) {
diff --git a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/DirectoryBrowser.java b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/DirectoryBrowser.java
index fcb2c578c..df801ad13 100644
--- a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/DirectoryBrowser.java
+++ b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/DirectoryBrowser.java
@@ -147,7 +147,7 @@ public class DirectoryBrowser {
      */
     public static DefaultFullHttpResponse directView(File dir, String path, FullHttpRequest request, ChannelHandlerContext ctx) throws IOException {
         if (path.startsWith("/")) {
-            path = path.substring(1, path.length());
+            path = path.substring(1);
         }
 
         // path maybe: arthas-output/20201225-203454.svg 
diff --git a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/HttpRequestHandler.java b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/HttpRequestHandler.java
index 9978a140b..a9f823946 100644
--- a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/HttpRequestHandler.java
+++ b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/HttpRequestHandler.java
@@ -158,7 +158,7 @@ public class HttpRequestHandler extends SimpleChannelInboundHandler= 0; index = inString.indexOf(oldPattern, pos)) {
-                sb.append(inString.substring(pos, index));
+                sb.append(inString, pos, index);
                 sb.append(newPattern);
                 pos = index + patLen;
             }
@@ -689,7 +705,7 @@ public abstract class StringUtils {
         }
         int arraySize = array.length;
         int bufSize = (arraySize == 0 ? 0 : (array[0].toString().length() + separator.length()) * arraySize);
-        StringBuffer buf = new StringBuffer(bufSize);
+        StringBuilder buf = new StringBuilder(bufSize);
 
         for (int i = 0; i < arraySize; i++) {
             if (i > 0) {
@@ -960,7 +976,7 @@ public abstract class StringUtils {
     // print|(ILjava/util/List;)V
     public static String[] splitMethodInfo(String methodInfo) {
         int index = methodInfo.indexOf('|');
-        return new String[] { methodInfo.substring(0, index), methodInfo.substring(index + 1, methodInfo.length()) };
+        return new String[] { methodInfo.substring(0, index), methodInfo.substring(index + 1) };
     }
 
     // demo/MathGame|primeFactors|(I)Ljava/util/List;|24
@@ -969,6 +985,6 @@ public abstract class StringUtils {
         int index2 = invokeInfo.indexOf('|', index1 + 1);
         int index3 = invokeInfo.indexOf('|', index2 + 1);
         return new String[] { invokeInfo.substring(0, index1), invokeInfo.substring(index1 + 1, index2),
-                invokeInfo.substring(index2 + 1, index3), invokeInfo.substring(index3 + 1, invokeInfo.length()) };
+                invokeInfo.substring(index2 + 1, index3), invokeInfo.substring(index3 + 1) };
     }
 }
diff --git a/core/src/main/java/com/taobao/arthas/core/util/ThreadUtil.java b/core/src/main/java/com/taobao/arthas/core/util/ThreadUtil.java
index f8f313f4b..1a8746de7 100644
--- a/core/src/main/java/com/taobao/arthas/core/util/ThreadUtil.java
+++ b/core/src/main/java/com/taobao/arthas/core/util/ThreadUtil.java
@@ -449,15 +449,13 @@ abstract public class ThreadUtil {
     }
 
     private static String getTCCL(Thread currentThread) {
-        if (null == currentThread.getContextClassLoader()) {
+        ClassLoader contextClassLoader = currentThread.getContextClassLoader();
+        if (null == contextClassLoader) {
             return "null";
         } else {
-            String classloaderClassName = currentThread.getContextClassLoader().getClass().getName();
-            StringBuilder sb = new StringBuilder(classloaderClassName.length()+10);
-            sb.append(classloaderClassName)
-                    .append("@")
-                    .append(Integer.toHexString(currentThread.getContextClassLoader().hashCode()));
-            return  sb.toString();
+            return contextClassLoader.getClass().getName() +
+                    "@" +
+                    Integer.toHexString(contextClassLoader.hashCode());
         }
     }
 
diff --git a/core/src/main/java/com/taobao/arthas/core/util/UserStatUtil.java b/core/src/main/java/com/taobao/arthas/core/util/UserStatUtil.java
index 3ed595e30..cc112d851 100644
--- a/core/src/main/java/com/taobao/arthas/core/util/UserStatUtil.java
+++ b/core/src/main/java/com/taobao/arthas/core/util/UserStatUtil.java
@@ -1,8 +1,7 @@
 package com.taobao.arthas.core.util;
 
-import java.io.BufferedReader;
 import java.io.IOException;
-import java.io.InputStreamReader;
+import java.io.InputStream;
 import java.net.URL;
 import java.net.URLConnection;
 import java.net.URLEncoder;
@@ -17,6 +16,11 @@ import java.util.concurrent.ThreadFactory;
  * Created by zhuyong on 15/11/12.
  */
 public class UserStatUtil {
+
+    private static final int DEFAULT_BUFFER_SIZE = 8192;
+
+    private static final byte[] SKIP_BYTE_BUFFER = new byte[DEFAULT_BUFFER_SIZE];
+
     private static final ExecutorService executorService = Executors.newSingleThreadExecutor(new ThreadFactory() {
         @Override
         public Thread newThread(Runnable r) {
@@ -87,9 +91,9 @@ public class UserStatUtil {
         public void appendQueryData(String key, String value) {
             if (key != null && value != null) {
                 if (queryData.length() == 0) {
-                    queryData.append(key + "=" + value);
+                    queryData.append(key).append("=").append(value);
                 } else {
-                    queryData.append("&" + key + "=" + value);
+                    queryData.append("&").append(key).append("=").append(value);
                 }
             }
         }
@@ -100,28 +104,27 @@ public class UserStatUtil {
             if (link == null) {
                 return;
             }
-            BufferedReader br = null;
+            InputStream inputStream = null;
             try {
                 if (queryData.length() != 0) {
                     link = link + "?" + queryData;
                 }
-                URL url = new URL(link.toString());
+                URL url = new URL(link);
                 URLConnection connection = url.openConnection();
                 connection.setConnectTimeout(1000);
                 connection.setReadTimeout(1000);
                 connection.connect();
-                br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
-                String line = null;
-                StringBuilder result = new StringBuilder();
-                while ((line = br.readLine()) != null) {
-                    result.append(line);
+                inputStream = connection.getInputStream();
+                //noinspection StatementWithEmptyBody
+                while (inputStream.read(SKIP_BYTE_BUFFER) != -1) {
+                    // do nothing
                 }
             } catch (Throwable t) {
                 // ignore
             } finally {
-                if (br != null) {
+                if (inputStream != null) {
                     try {
-                        br.close();
+                        inputStream.close();
                     } catch (IOException e) {
                         // ignore
                     }
diff --git a/core/src/main/java/com/taobao/arthas/core/util/affect/EnhancerAffect.java b/core/src/main/java/com/taobao/arthas/core/util/affect/EnhancerAffect.java
index b0b3b3789..eebf0746d 100644
--- a/core/src/main/java/com/taobao/arthas/core/util/affect/EnhancerAffect.java
+++ b/core/src/main/java/com/taobao/arthas/core/util/affect/EnhancerAffect.java
@@ -144,7 +144,7 @@ public final class EnhancerAffect extends Affect {
                 cost(),
                 listenerId));
         if (this.throwable != null) {
-            infoSB.append("\nEnhance error! exception: " + this.throwable);
+            infoSB.append("\nEnhance error! exception: ").append(this.throwable);
         }
         return infoSB.toString();
     }
diff --git a/core/src/main/java/com/taobao/arthas/core/util/reflect/ArthasReflectUtils.java b/core/src/main/java/com/taobao/arthas/core/util/reflect/ArthasReflectUtils.java
index 1a84e5dc5..b8c6880fe 100644
--- a/core/src/main/java/com/taobao/arthas/core/util/reflect/ArthasReflectUtils.java
+++ b/core/src/main/java/com/taobao/arthas/core/util/reflect/ArthasReflectUtils.java
@@ -144,27 +144,29 @@ public class ArthasReflectUtils {
                         || (file.getName().endsWith(".class"));
             }
         });
-        // 循环所有文件
-        for (File file : dirfiles) {
-            // 如果是目录 则继续扫描
-            if (file.isDirectory()) {
-                findAndAddClassesInPackageByFile(
-                        packageName + "." + file.getName(),
-                        file.getAbsolutePath(), recursive, classes);
-            } else {
-                // 如果是java类文件 去掉后面的.class 只留下类名
-                String className = file.getName().substring(0,
-                        file.getName().length() - 6);
-                try {
-                    // 添加到集合中去
-                    // classes.add(Class.forName(packageName + '.' +
-                    // className));
-                    // 经过回复同学的提醒,这里用forName有一些不好,会触发static方法,没有使用classLoader的load干净
-                    classes.add(Thread.currentThread().getContextClassLoader()
-                            .loadClass(packageName + '.' + className));
-                } catch (ClassNotFoundException e) {
-                    // log.error("添加用户自定义视图类错误 找不到此类的.class文件");
-//                    e.printStackTrace();
+        if (dirfiles != null) {
+            // 循环所有文件
+            for (File file : dirfiles) {
+                // 如果是目录 则继续扫描
+                if (file.isDirectory()) {
+                    findAndAddClassesInPackageByFile(
+                            packageName + "." + file.getName(),
+                            file.getAbsolutePath(), recursive, classes);
+                } else {
+                    // 如果是java类文件 去掉后面的.class 只留下类名
+                    String className = file.getName().substring(0,
+                            file.getName().length() - 6);
+                    try {
+                        // 添加到集合中去
+                        // classes.add(Class.forName(packageName + '.' +
+                        // className));
+                        // 经过回复同学的提醒,这里用forName有一些不好,会触发static方法,没有使用classLoader的load干净
+                        classes.add(Thread.currentThread().getContextClassLoader()
+                                .loadClass(packageName + '.' + className));
+                    } catch (ClassNotFoundException e) {
+                        // log.error("添加用户自定义视图类错误 找不到此类的.class文件");
+                        //                    e.printStackTrace();
+                    }
                 }
             }
         }
diff --git a/core/src/main/resources/com/taobao/arthas/core/http/web-console.js b/core/src/main/resources/com/taobao/arthas/core/http/web-console.js
index 7e0b67802..b301691eb 100644
--- a/core/src/main/resources/com/taobao/arthas/core/http/web-console.js
+++ b/core/src/main/resources/com/taobao/arthas/core/http/web-console.js
@@ -1,5 +1,8 @@
 var ws;
 var xterm;
+const DEFAULT_SCROLL_BACK = 1000
+const MAX_SCROLL_BACK = 9999999
+const MIN_SCROLL_BACK = 1
 
 $(function () {
     var url = window.location.href;
@@ -87,16 +90,23 @@ function initWs (ip, port) {
 }
 
 /** init xterm **/
-function initXterm (cols, rows) {
+function initXterm (cols, rows,scrollback) {
+    let scrollNumber = parseInt(scrollback,10)
     xterm = new Terminal({
         cols: cols,
         rows: rows,
-        screenReaderMode: true,
+        screenReaderMode: false,
         rendererType: 'canvas',
-        convertEol: true
+        convertEol: true,
+        scrollback: isValidNumber(scrollNumber) ? scrollNumber : DEFAULT_SCROLL_BACK
     });
 }
 
+function isValidNumber(scrollNumber){
+    return  scrollNumber >= MIN_SCROLL_BACK &&
+        scrollNumber <= MAX_SCROLL_BACK;
+}
+
 /** begin connect **/
 function startConnect (silent) {
     var ip = $('#ip').val();
@@ -120,10 +130,11 @@ function startConnect (silent) {
         console.log('open');
         $('#fullSc').show();
         var terminalSize = getTerminalSize()
+        let scrollback = getUrlParam('scrollback');
         console.log('terminalSize')
         console.log(terminalSize)
         // init xterm
-        initXterm(terminalSize.cols, terminalSize.rows)
+        initXterm(terminalSize.cols, terminalSize.rows, scrollback)
         ws.onmessage = function (event) {
             if (event.type === 'message') {
                 var data = event.data;
diff --git a/core/src/test/java/com/taobao/arthas/core/util/DateUtilsTest.java b/core/src/test/java/com/taobao/arthas/core/util/DateUtilsTest.java
index e739a4eb5..d10922265 100644
--- a/core/src/test/java/com/taobao/arthas/core/util/DateUtilsTest.java
+++ b/core/src/test/java/com/taobao/arthas/core/util/DateUtilsTest.java
@@ -15,7 +15,7 @@ public class DateUtilsTest {
     	
         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // supported date format
         Date date = new Date();
-        Assert.assertEquals(DateUtils.formatDate(date), dateFormat.format(date).toString());
+        Assert.assertEquals(DateUtils.formatDate(date), dateFormat.format(date));
 
     }
     
@@ -24,7 +24,7 @@ public class DateUtilsTest {
     	
         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); // Not supported Date format
         Date date = new Date();
-        Assert.assertNotEquals(DateUtils.formatDate(date), dateFormat.format(date).toString());
+        Assert.assertNotEquals(DateUtils.formatDate(date), dateFormat.format(date));
 
     }
  }
\ No newline at end of file
diff --git a/core/src/test/java/com/taobao/arthas/core/util/LogUtilTest.java b/core/src/test/java/com/taobao/arthas/core/util/LogUtilTest.java
index 8cb3d153f..7ee43e63c 100644
--- a/core/src/test/java/com/taobao/arthas/core/util/LogUtilTest.java
+++ b/core/src/test/java/com/taobao/arthas/core/util/LogUtilTest.java
@@ -49,7 +49,7 @@ public class LogUtilTest {
         properties1.put("arthas.home", testResourcesDir);
         arthasEnvironment.addLast(new PropertiesPropertySource("test1", properties1));
 
-        LoggerContext loggerContext = LogUtil.initLooger(arthasEnvironment);
+        LoggerContext loggerContext = LogUtil.initLogger(arthasEnvironment);
 
         Logger logger = loggerContext.getLogger("root");
         Level level = logger.getLevel();
@@ -64,7 +64,7 @@ public class LogUtilTest {
         properties1.put(LogUtil.LOGGING_CONFIG_PROPERTY, testResourcesDir + "/logback-test.xml");
         arthasEnvironment.addLast(new PropertiesPropertySource("test1", properties1));
 
-        LoggerContext loggerContext = LogUtil.initLooger(arthasEnvironment);
+        LoggerContext loggerContext = LogUtil.initLogger(arthasEnvironment);
 
         Logger logger = loggerContext.getLogger("root");
         Level level = logger.getLevel();
@@ -80,7 +80,7 @@ public class LogUtilTest {
 
         arthasEnvironment.addLast(new PropertiesPropertySource("test1", properties1));
 
-        LoggerContext loggerContext = LogUtil.initLooger(arthasEnvironment);
+        LoggerContext loggerContext = LogUtil.initLogger(arthasEnvironment);
 
         Logger logger = loggerContext.getLogger("root");
         Level level = logger.getLevel();
@@ -112,7 +112,7 @@ public class LogUtilTest {
         properties1.put(LogUtil.FILE_NAME_PROPERTY, logFile);
         arthasEnvironment.addLast(new PropertiesPropertySource("test1", properties1));
 
-        LoggerContext loggerContext = LogUtil.initLooger(arthasEnvironment);
+        LoggerContext loggerContext = LogUtil.initLogger(arthasEnvironment);
 
         Logger logger = loggerContext.getLogger("root");
         Level level = logger.getLevel();
@@ -144,7 +144,7 @@ public class LogUtilTest {
         properties1.put(LogUtil.FILE_PATH_PROPERTY, tempFolder.getRoot().getAbsolutePath());
         arthasEnvironment.addLast(new PropertiesPropertySource("test1", properties1));
 
-        LoggerContext loggerContext = LogUtil.initLooger(arthasEnvironment);
+        LoggerContext loggerContext = LogUtil.initLogger(arthasEnvironment);
 
         Logger logger = loggerContext.getLogger("root");
         Level level = logger.getLevel();
diff --git a/lib/libArthasJniLibrary-x64.dll b/lib/libArthasJniLibrary-x64.dll
index ac42d1ad2..be253538b 100644
Binary files a/lib/libArthasJniLibrary-x64.dll and b/lib/libArthasJniLibrary-x64.dll differ
diff --git a/memorycompiler/src/main/java/com/taobao/arthas/compiler/PackageInternalsFinder.java b/memorycompiler/src/main/java/com/taobao/arthas/compiler/PackageInternalsFinder.java
index 62b2f7d60..80fdf0597 100644
--- a/memorycompiler/src/main/java/com/taobao/arthas/compiler/PackageInternalsFinder.java
+++ b/memorycompiler/src/main/java/com/taobao/arthas/compiler/PackageInternalsFinder.java
@@ -26,6 +26,7 @@ import java.io.IOException;
 import java.net.JarURLConnection;
 import java.net.URI;
 import java.net.URL;
+import java.net.URLDecoder;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Enumeration;
@@ -55,7 +56,7 @@ public class PackageInternalsFinder {
     }
 
     private Collection listUnder(String packageName, URL packageFolderURL) {
-        File directory = new File(packageFolderURL.getFile());
+        File directory = new File(decode(packageFolderURL.getFile()));
         if (directory.isDirectory()) { // browse local .class files - useful for local execution
             return processDir(packageName, directory);
         } else { // browse a jar file
@@ -94,18 +95,30 @@ public class PackageInternalsFinder {
         List result = new ArrayList();
 
         File[] childFiles = directory.listFiles();
-        for (File childFile : childFiles) {
-            if (childFile.isFile()) {
-                // We only want the .class files.
-                if (childFile.getName().endsWith(CLASS_FILE_EXTENSION)) {
-                    String binaryName = packageName + "." + childFile.getName();
-                    binaryName = binaryName.replaceAll(CLASS_FILE_EXTENSION + "$", "");
-
-                    result.add(new CustomJavaFileObject(binaryName, childFile.toURI()));
+        if (childFiles != null) {
+            for (File childFile : childFiles) {
+                if (childFile.isFile()) {
+                    // We only want the .class files.
+                    if (childFile.getName().endsWith(CLASS_FILE_EXTENSION)) {
+                        String binaryName = packageName + "." + childFile.getName();
+                        binaryName = binaryName.replaceAll(CLASS_FILE_EXTENSION + "$", "");
+
+                        result.add(new CustomJavaFileObject(binaryName, childFile.toURI()));
+                    }
                 }
             }
         }
 
         return result;
     }
+
+    private String decode(String filePath) {
+        try {
+            return URLDecoder.decode(filePath, "utf-8");
+        } catch (Exception e) {
+            // ignore, return original string
+        }
+
+        return filePath;
+    }
 }
diff --git a/memorycompiler/src/test/java/com/taobao/arthas/compiler/PackageInternalsFinderTest.java b/memorycompiler/src/test/java/com/taobao/arthas/compiler/PackageInternalsFinderTest.java
new file mode 100644
index 000000000..535bf083c
--- /dev/null
+++ b/memorycompiler/src/test/java/com/taobao/arthas/compiler/PackageInternalsFinderTest.java
@@ -0,0 +1,33 @@
+package com.taobao.arthas.compiler;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.tools.JavaFileObject;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * description: PackageInternalsFinderTest 
+ * date: 2021/9/23 12:55 下午
+ * author: zzq0324
+ * version: 1.0
+ */ +public class PackageInternalsFinderTest { + + @Test + public void testFilePathContainWhitespace() throws IOException { + PackageInternalsFinder finder = new PackageInternalsFinder(this.getClass().getClassLoader()); + List fileObjectList= finder.find("file/test folder"); + + Assert.assertEquals(fileObjectList.size(), 0); + } + + @Test + public void testFilePathContainChineseCharacter() throws IOException { + PackageInternalsFinder finder = new PackageInternalsFinder(this.getClass().getClassLoader()); + List fileObjectList= finder.find("file/测试目录"); + + Assert.assertEquals(fileObjectList.size(), 0); + } +} diff --git a/memorycompiler/src/test/resources/file/test folder/file.txt b/memorycompiler/src/test/resources/file/test folder/file.txt new file mode 100644 index 000000000..326fdfb77 --- /dev/null +++ b/memorycompiler/src/test/resources/file/test folder/file.txt @@ -0,0 +1 @@ +This is a test file, it's name contains white space. \ No newline at end of file diff --git a/memorycompiler/src/test/resources/file/测试目录/file.txt b/memorycompiler/src/test/resources/file/测试目录/file.txt new file mode 100644 index 000000000..c9f1f7206 --- /dev/null +++ b/memorycompiler/src/test/resources/file/测试目录/file.txt @@ -0,0 +1 @@ +This is a test file, it's name contains chinese character. \ No newline at end of file diff --git a/pom.xml b/pom.xml index 1e1052850..a3371f00a 100644 --- a/pom.xml +++ b/pom.xml @@ -75,7 +75,7 @@ - 3.5.3 + 3.5.4 UTF-8 1.6 1.6 @@ -102,7 +102,7 @@ com.alibaba.middleware termd-core - 1.1.7.11 + 1.1.7.12 com.alibaba.middleware @@ -137,7 +137,7 @@ com.taobao.text text-ui - 0.0.2 + 0.0.3 com.fifesoft diff --git a/site/src/site/sphinx/auth.md b/site/src/site/sphinx/auth.md index 739dab790..35dc3ada8 100644 --- a/site/src/site/sphinx/auth.md +++ b/site/src/site/sphinx/auth.md @@ -19,6 +19,16 @@ java -jar arthas-boot.jar --password ppp Using generated security password: 0vUBJpRIppkKuZ7dYzYqOKtranj4unGh ``` +### 本地连接不鉴权 + +默认情况下,在`arthas.properties`文件里有配置: + +``` +arthas.localConnectionNonAuth=true +``` + +当配置密码时,使用本地连接,也不需要鉴权。默认配置值是true,方便本地连接使用。只有远程连接时,才需要鉴权。 + ### 在telnet console里鉴权 连接到arthas后,直接执行命令会提示需要鉴权: diff --git a/site/src/site/sphinx/en/auth.md b/site/src/site/sphinx/en/auth.md index 937e3aa9e..5b11af66d 100644 --- a/site/src/site/sphinx/en/auth.md +++ b/site/src/site/sphinx/en/auth.md @@ -19,6 +19,14 @@ java -jar arthas-boot.jar --password ppp Using generated security password: 0vUBJpRIppkKuZ7dYzYqOKtranj4unGh ``` +### Local connection does not require authentication +By default, there are configurations in the `arthas.properties` file: + +``` +arthas.localConnectionNonAuth=true +``` +When the password is configured, connect from localhost, the authentication is not required. The default configuration value is true, which is convenient for local connection. Authentication is only required when connecting remotely. + ### Authenticate in the telnet console After connecting to arthas, directly executing the command will prompt for authentication: diff --git a/site/src/site/sphinx/en/trace.md b/site/src/site/sphinx/en/trace.md index bbeb5032e..ed9b5d421 100644 --- a/site/src/site/sphinx/en/trace.md +++ b/site/src/site/sphinx/en/trace.md @@ -238,3 +238,16 @@ So where is the rest of the time consumed? 2. Instruction consumption. For example, instructions such as `i++`, `getfield`, etc. 3. Possible JVM pause during code execution, such as GC, entering synchronization blocks, etc. + +#### Use the -v parameter to print more information + +> The watch/trace/monitor/stack/tt commands all support the `-v` parameter. + +When the command is executed, there is no output result. There are two possibilities: + +1. The matched function is not executed +2. The result of the conditional expression is false + +But the user cannot tell which situation is. + +Using the `-v` option, the specific value and execution result of `Condition express` will be printed for easy confirmation. diff --git a/site/src/site/sphinx/en/tunnel.md b/site/src/site/sphinx/en/tunnel.md index b5807ea3e..59a9d0bbd 100644 --- a/site/src/site/sphinx/en/tunnel.md +++ b/site/src/site/sphinx/en/tunnel.md @@ -9,8 +9,8 @@ For example, in streaming computing, Java processes can be started on different In this case, Arthas Tunnel Server/Client can be used. Reference: -* [Web Console](web-console.md) -* [Arthas Spring Boot Starter](spring-boot-starter.md) +* 1: [Web Console](web-console.md) +* 2: [Arthas Spring Boot Starter](spring-boot-starter.md) ### Download and deploy arthas tunnel server diff --git a/site/src/site/sphinx/en/watch.md b/site/src/site/sphinx/en/watch.md index c95cfbfab..483d0dc4a 100644 --- a/site/src/site/sphinx/en/watch.md +++ b/site/src/site/sphinx/en/watch.md @@ -15,7 +15,7 @@ There are four different scenarios for `watch` command, which makes it rather co |---:|:---| |*class-pattern*|pattern for the class name| |*method-pattern*|pattern for the method name| -|*expression*|expression to monitor| +|*expression*|expression to watch, default value `{params, target, returnObj}`| |*condition-expression*|condition expression to filter| |[b]|before method being invoked| |[e]|when method encountering exceptions| @@ -30,7 +30,7 @@ F.Y.I 3. at the *watching* point, Arthas will use the *expression* to evaluate the variables and print them out; 4. `in parameters` and `out parameters` are different since they can be modified within the invoked methods; `params` stands for `in parameters` in `-b`while `out parameters` in other *watching* points; 5. there are no `return values` and `exceptions` when using `-b`. - +6. In the result of the watch command, the `location` information will be printed. There are three possible values for `location`: `AtEnter`, `AtExit`, and `AtExceptionExit`. Corresponding to the method entry, the method returns normally, and the method throws an exception. Advanced: * [Critical fields in *expression*](advice-class.md) @@ -43,25 +43,44 @@ Advanced: Start `math-game` in [Quick Start](quick-start.md). -#### Check the `out parameters` and `return value` +#### Check the `out parameters`, `this` and `return value` + +> The expression to watch, default value `{params, target, returnObj}` ```bash -$ watch demo.MathGame primeFactors "{params,returnObj}" -x 2 -Press Ctrl+C to abort. -Affect(class-cnt:1 , method-cnt:1) cost in 44 ms. -ts=2018-12-03 19:16:51; [cost=1.280502ms] result=@ArrayList[ +$ watch demo.MathGame primeFactors -x 2 +Press Q or Ctrl+C to abort. +Affect(class count: 1 , method count: 1) cost in 32 ms, listenerId: 5 +method=demo.MathGame.primeFactors location=AtExceptionExit +ts=2021-08-31 15:22:57; [cost=0.220625ms] result=@ArrayList[ + @Object[][ + @Integer[-179173], + ], + @MathGame[ + random=@Random[java.util.Random@31cefde0], + illegalArgumentCount=@Integer[44], + ], + null, +] +method=demo.MathGame.primeFactors location=AtExit +ts=2021-08-31 15:22:58; [cost=1.020982ms] result=@ArrayList[ @Object[][ @Integer[1], ], + @MathGame[ + random=@Random[java.util.Random@31cefde0], + illegalArgumentCount=@Integer[44], + ], @ArrayList[ - @Integer[3], - @Integer[19], - @Integer[191], - @Integer[49199], + @Integer[2], + @Integer[2], + @Integer[26947], ], ] ``` +* In the above result, the method is executed twice, the first result is `location=AtExceptionExit`, indicating that the method throws an exception, so `returnObj` is null +* In the second result is `location=AtExit`, indicating that the method returns normally, so you can see that the result of `returnObj` is an ArrayList #### Check `in parameters` ```bash diff --git a/site/src/site/sphinx/en/web-console.md b/site/src/site/sphinx/en/web-console.md index cbf952cef..91848ba18 100644 --- a/site/src/site/sphinx/en/web-console.md +++ b/site/src/site/sphinx/en/web-console.md @@ -5,7 +5,7 @@ Web Console ### Connect arthas through the browser -Arthas supports the Web Console. After attach success, the user can access: [http://127.0.0.1:3658/](http://127.0.0.1:3658/). +Arthas supports the Web Console. After attach success, the user can access: [http://127.0.0.1:8563/](http://127.0.0.1:8563/). The user can fill in the IP and connect the remote arthas on other machines. @@ -17,6 +17,12 @@ If you have suggestions for the Web Console, please leave a message here: [https * Copy and paste shortcut keys in Web Console: [https://github.com/alibaba/arthas/issues/1056](https://github.com/alibaba/arthas/issues/1056) +> Since 3.5.4, you can right-click to copy and paste in the Web Console. +### scrollback URL parameters +> Since 3.5.5 +By default, the number of rows that the Web Console supports to roll back upwards is 1000. It can be specified with `scrollback` in the URL. for example + +[http://127.0.0.1:8563/?scrollback=3000](http://127.0.0.1:8563/?scrollback=3000) ### Connect remote arthas through arthas tunnel server -[Arthas Tunnel](tunnel.md) \ No newline at end of file +Reference: [Arthas Tunnel](tunnel.md) \ No newline at end of file diff --git a/site/src/site/sphinx/trace.md b/site/src/site/sphinx/trace.md index 84bb7b9f9..d666452c9 100644 --- a/site/src/site/sphinx/trace.md +++ b/site/src/site/sphinx/trace.md @@ -241,4 +241,17 @@ Affect(class count: 1 , method count: 1) cost in 66 ms, listenerId: 1 ``` 2. 非函数调用的指令消耗。比如 `i++`, `getfield`等指令。 -3. 在代码执行过程中,JVM可能出现停顿,比如GC,进入同步块等。 \ No newline at end of file +3. 在代码执行过程中,JVM可能出现停顿,比如GC,进入同步块等。 + +#### 使用 -v 参数打印更多信息 + +> watch/trace/monitor/stack/tt 命令都支持 `-v` 参数 + +当命令执行之后,没有输出结果。有两种可能: + +1. 匹配到的函数没有被执行 +2. 条件表达式结果是 false + +但用户区分不出是哪种情况。 + +使用 `-v`选项,则会打印`Condition express`的具体值和执行结果,方便确认。 \ No newline at end of file diff --git a/site/src/site/sphinx/tunnel.md b/site/src/site/sphinx/tunnel.md index 133b9971a..929dbe263 100644 --- a/site/src/site/sphinx/tunnel.md +++ b/site/src/site/sphinx/tunnel.md @@ -8,8 +8,9 @@ Arthas Tunnel 在这种情况下,可以使用Arthas Tunnel Server/Client。 参考: -* [Web Console](web-console.md) -* [Arthas Spring Boot Starter](spring-boot-starter.md) + +* 1: [Web Console](web-console.md) +* 2: [Arthas Spring Boot Starter](spring-boot-starter.md) ### 下载部署arthas tunnel server diff --git a/site/src/site/sphinx/watch.md b/site/src/site/sphinx/watch.md index 1deb3b132..217c52870 100644 --- a/site/src/site/sphinx/watch.md +++ b/site/src/site/sphinx/watch.md @@ -3,9 +3,9 @@ watch [`watch`在线教程](https://arthas.aliyun.com/doc/arthas-tutorials.html?language=cn&id=command-watch) -> 方法执行数据观测 +> 函数执行数据观测 -让你能方便的观察到指定方法的调用情况。能观察到的范围为:`返回值`、`抛出异常`、`入参`,通过编写 OGNL 表达式进行对应变量的查看。 +让你能方便的观察到指定函数的调用情况。能观察到的范围为:`返回值`、`抛出异常`、`入参`,通过编写 OGNL 表达式进行对应变量的查看。 ### 参数说明 @@ -14,13 +14,13 @@ watch 的参数比较多,主要是因为它能在 4 个不同的场景观察 |参数名称|参数说明| |---:|:---| |*class-pattern*|类名表达式匹配| -|*method-pattern*|方法名表达式匹配| -|*express*|观察表达式| +|*method-pattern*|函数名表达式匹配| +|*express*|观察表达式,默认值:`{params, target, returnObj}`| |*condition-express*|条件表达式| -|[b]|在**方法调用之前**观察| -|[e]|在**方法异常之后**观察| -|[s]|在**方法返回之后**观察| -|[f]|在**方法结束之后**(正常返回和异常返回)观察| +|[b]|在**函数调用之前**观察| +|[e]|在**函数异常之后**观察| +|[s]|在**函数返回之后**观察| +|[f]|在**函数结束之后**(正常返回和异常返回)观察| |[E]|开启正则表达式匹配,默认为通配符匹配| |[x:]|指定输出结果的属性遍历深度,默认为 1| @@ -33,37 +33,58 @@ watch 的参数比较多,主要是因为它能在 4 个不同的场景观察 **特别说明**: -* watch 命令定义了4个观察事件点,即 `-b` 方法调用前,`-e` 方法异常后,`-s` 方法返回后,`-f` 方法结束后 +* watch 命令定义了4个观察事件点,即 `-b` 函数调用前,`-e` 函数异常后,`-s` 函数返回后,`-f` 函数结束后 * 4个观察事件点 `-b`、`-e`、`-s` 默认关闭,`-f` 默认打开,当指定观察点被打开后,在相应事件点会对观察表达式进行求值并输出 -* 这里要注意`方法入参`和`方法出参`的区别,有可能在中间被修改导致前后不一致,除了 `-b` 事件点 `params` 代表方法入参外,其余事件都代表方法出参 -* 当使用 `-b` 时,由于观察事件点是在方法调用前,此时返回值或异常均不存在 - +* 这里要注意`函数入参`和`函数出参`的区别,有可能在中间被修改导致前后不一致,除了 `-b` 事件点 `params` 代表函数入参外,其余事件都代表函数出参 +* 当使用 `-b` 时,由于观察事件点是在函数调用前,此时返回值或异常均不存在 +* 在watch命令的结果里,会打印出`location`信息。`location`有三种可能值:`AtEnter`,`AtExit`,`AtExceptionExit`。对应函数入口,函数正常return,函数抛出异常。 ### 使用参考 #### 启动 Demo 启动[快速入门](quick-start.md)里的`math-game`。 -#### 观察方法出参和返回值 +#### 观察函数调用返回时的参数、this对象和返回值 + +> 观察表达式,默认值是`{params, target, returnObj}` ```bash -$ watch demo.MathGame primeFactors "{params,returnObj}" -x 2 -Press Ctrl+C to abort. -Affect(class-cnt:1 , method-cnt:1) cost in 44 ms. -ts=2018-12-03 19:16:51; [cost=1.280502ms] result=@ArrayList[ +$ watch demo.MathGame primeFactors -x 2 +Press Q or Ctrl+C to abort. +Affect(class count: 1 , method count: 1) cost in 32 ms, listenerId: 5 +method=demo.MathGame.primeFactors location=AtExceptionExit +ts=2021-08-31 15:22:57; [cost=0.220625ms] result=@ArrayList[ + @Object[][ + @Integer[-179173], + ], + @MathGame[ + random=@Random[java.util.Random@31cefde0], + illegalArgumentCount=@Integer[44], + ], + null, +] +method=demo.MathGame.primeFactors location=AtExit +ts=2021-08-31 15:22:58; [cost=1.020982ms] result=@ArrayList[ @Object[][ @Integer[1], ], + @MathGame[ + random=@Random[java.util.Random@31cefde0], + illegalArgumentCount=@Integer[44], + ], @ArrayList[ - @Integer[3], - @Integer[19], - @Integer[191], - @Integer[49199], + @Integer[2], + @Integer[2], + @Integer[26947], ], ] ``` -#### 观察方法入参 +* 上面的结果里,说明函数被执行了两次,第一次结果是`location=AtExceptionExit`,说明函数抛出异常了,因此`returnObj`是null +* 在第二次结果里是`location=AtExit`,说明函数正常返回,因此可以看到`returnObj`结果是一个ArrayList + + +#### 观察函数调用入口的参数和返回值 ```bash $ watch demo.MathGame primeFactors "{params,returnObj}" -x 2 -b @@ -77,10 +98,10 @@ ts=2018-12-03 19:23:23; [cost=0.0353ms] result=@ArrayList[ ] ``` -* 对比前一个例子,返回值为空(事件点为方法执行前,因此获取不到返回值) +* 对比前一个例子,返回值为空(事件点为函数执行前,因此获取不到返回值) -#### 同时观察方法调用前和方法返回后 +#### 同时观察函数调用前和函数返回后 ```bash $ watch demo.MathGame primeFactors "{params,target,returnObj}" -x 2 -b -s -n 2 @@ -119,11 +140,11 @@ ts=2018-12-03 19:29:54; [cost=4.277392ms] result=@ArrayList[ * 参数里`-n 2`,表示只执行两次 -* 这里输出结果中,第一次输出的是方法调用前的观察表达式的结果,第二次输出的是方法返回后的表达式的结果 +* 这里输出结果中,第一次输出的是函数调用前的观察表达式的结果,第二次输出的是函数返回后的表达式的结果 * 结果的输出顺序和事件发生的先后顺序一致,和命令中 `-s -b` 的顺序无关 -#### 调整`-x`的值,观察具体的方法参数值 +#### 调整`-x`的值,观察具体的函数参数值 ```bash $ watch demo.MathGame primeFactors "{params,target}" -x 3 @@ -213,7 +234,7 @@ ts=2018-12-03 19:40:28; [cost=2112.168897ms] result=@ArrayList[ #### 观察当前对象中的属性 -如果想查看方法运行前后,当前对象中的属性,可以使用`target`关键字,代表当前对象 +如果想查看函数运行前后,当前对象中的属性,可以使用`target`关键字,代表当前对象 ```bash $ watch demo.MathGame primeFactors 'target' @@ -235,7 +256,7 @@ ts=2018-12-03 20:04:34; [cost=131.303498ms] result=@Integer[8] ts=2018-12-03 20:04:35; [cost=0.961441ms] result=@Integer[8] ``` -#### 获取类的静态字段、调用类的静态方法的例子 +#### 获取类的静态字段、调用类的静态函数的例子 ```bash watch demo.MathGame * '{params,@demo.MathGame@random.nextInt(100)}' -v -n 1 -x 2 diff --git a/site/src/site/sphinx/web-console.md b/site/src/site/sphinx/web-console.md index 549657409..51cec605e 100644 --- a/site/src/site/sphinx/web-console.md +++ b/site/src/site/sphinx/web-console.md @@ -6,7 +6,7 @@ Web Console ### 通过浏览器连接arthas -Arthas目前支持Web Console,用户在attach成功之后,可以直接访问:[http://127.0.0.1:3658/](http://127.0.0.1:3658/)。 +Arthas目前支持Web Console,用户在attach成功之后,可以直接访问:[http://127.0.0.1:8563/](http://127.0.0.1:8563/)。 可以填入IP,远程连接其它机器上的arthas。 @@ -17,6 +17,16 @@ Arthas目前支持Web Console,用户在attach成功之后,可以直接访问 > 注意会有安全风险,考虑下面的tunnel server的方案。 * 在Web Console复制粘贴快捷键参考: [https://github.com/alibaba/arthas/issues/1056](https://github.com/alibaba/arthas/issues/1056) + +> 3.5.4 版本后,在Web Console可以鼠标右键复制粘贴。 + +### scrollback URL参数 + +> 3.5.5 版本后支持 + +默认Web Console支持向上回滚的行数是1000。可以在URL里用`scrollback`指定。比如 + +[http://127.0.0.1:8563/?scrollback=3000](http://127.0.0.1:8563/?scrollback=3000) ### 使用arthas tunnel server连接远程arthas -[Arthas Tunnel](tunnel.md) \ No newline at end of file +参考:[Arthas Tunnel](tunnel.md) \ No newline at end of file diff --git a/tunnel-client/src/main/java/com/alibaba/arthas/tunnel/client/ProxyClient.java b/tunnel-client/src/main/java/com/alibaba/arthas/tunnel/client/ProxyClient.java index bfa499e11..5bcdb3359 100644 --- a/tunnel-client/src/main/java/com/alibaba/arthas/tunnel/client/ProxyClient.java +++ b/tunnel-client/src/main/java/com/alibaba/arthas/tunnel/client/ProxyClient.java @@ -96,14 +96,14 @@ public class ProxyClient { SimpleHttpResponse httpResponse = new SimpleHttpResponse(); try { - httpResponse.setContent(new String("error").getBytes("utf-8")); + httpResponse.setContent("error".getBytes("utf-8")); } catch (UnsupportedEncodingException e) { // ignore } return httpResponse; } - class HttpProxyClientHandler extends SimpleChannelInboundHandler { + static class HttpProxyClientHandler extends SimpleChannelInboundHandler { private Promise promise; diff --git a/tunnel-server/src/main/java/com/alibaba/arthas/tunnel/server/endpoint/ActuatorSecurity.java b/tunnel-server/src/main/java/com/alibaba/arthas/tunnel/server/app/WebSecurityConfig.java similarity index 50% rename from tunnel-server/src/main/java/com/alibaba/arthas/tunnel/server/endpoint/ActuatorSecurity.java rename to tunnel-server/src/main/java/com/alibaba/arthas/tunnel/server/app/WebSecurityConfig.java index f35b5f857..efa3cf145 100644 --- a/tunnel-server/src/main/java/com/alibaba/arthas/tunnel/server/endpoint/ActuatorSecurity.java +++ b/tunnel-server/src/main/java/com/alibaba/arthas/tunnel/server/app/WebSecurityConfig.java @@ -1,15 +1,30 @@ -package com.alibaba.arthas.tunnel.server.endpoint; +package com.alibaba.arthas.tunnel.server.app; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import com.alibaba.arthas.tunnel.server.app.configuration.ArthasProperties; + +/** + * + * @author hengyunabc 2021-08-11 + * + */ @Configuration -public class ActuatorSecurity extends WebSecurityConfigurerAdapter { +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + ArthasProperties arthasProperties; @Override protected void configure(HttpSecurity httpSecurity) throws Exception { httpSecurity.authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).authenticated().anyRequest() - .permitAll().and().formLogin(); + .permitAll().and().formLogin(); + // allow iframe + if (arthasProperties.isEnableIframeSupport()) { + httpSecurity.headers().frameOptions().disable(); + } } } \ No newline at end of file diff --git a/tunnel-server/src/main/java/com/alibaba/arthas/tunnel/server/app/configuration/ArthasProperties.java b/tunnel-server/src/main/java/com/alibaba/arthas/tunnel/server/app/configuration/ArthasProperties.java index 0eb95c24d..ce1aafbbb 100644 --- a/tunnel-server/src/main/java/com/alibaba/arthas/tunnel/server/app/configuration/ArthasProperties.java +++ b/tunnel-server/src/main/java/com/alibaba/arthas/tunnel/server/app/configuration/ArthasProperties.java @@ -27,6 +27,8 @@ public class ArthasProperties { */ private boolean enableDetailPages = false; + private boolean enableIframeSupport = true; + public Server getServer() { return server; } @@ -51,6 +53,14 @@ public class ArthasProperties { this.enableDetailPages = enableDetailPages; } + public boolean isEnableIframeSupport() { + return enableIframeSupport; + } + + public void setEnableIframeSupport(boolean enableIframeSupport) { + this.enableIframeSupport = enableIframeSupport; + } + public static class Server { /** * tunnel server listen host diff --git a/tunnel-server/src/main/resources/static/web-console.js b/tunnel-server/src/main/resources/static/web-console.js index 5fb9b60c8..9d35bfb41 100644 --- a/tunnel-server/src/main/resources/static/web-console.js +++ b/tunnel-server/src/main/resources/static/web-console.js @@ -1,5 +1,8 @@ var ws; var xterm; +const DEFAULT_SCROLL_BACK = 1000 +const MAX_SCROLL_BACK = 9999999 +const MIN_SCROLL_BACK = 1 $(function () { var url = window.location.href; @@ -92,16 +95,23 @@ function initWs (ip, port, path, agentId, targetServer) { } /** init xterm **/ -function initXterm (cols, rows) { +function initXterm (cols, rows,scrollback) { + let scrollNumber = parseInt(scrollback,10) xterm = new Terminal({ cols: cols, rows: rows, - screenReaderMode: true, + screenReaderMode: false, rendererType: 'canvas', - convertEol: true + convertEol: true, + scrollback: isValidNumber(scrollNumber) ? scrollNumber : DEFAULT_SCROLL_BACK }); } +function isValidNumber(scrollNumber){ + return scrollNumber >= MIN_SCROLL_BACK && + scrollNumber <= MAX_SCROLL_BACK; +} + /** begin connect **/ function startConnect (silent) { var ip = $('#ip').val(); @@ -148,8 +158,9 @@ function startConnect (silent) { var terminalSize = getTerminalSize() console.log('terminalSize') console.log(terminalSize) + let scrollback = getUrlParam('scrollback'); // init xterm - initXterm(terminalSize.cols, terminalSize.rows) + initXterm(terminalSize.cols, terminalSize.rows,scrollback) ws.onmessage = function (event) { if (event.type === 'message') { var data = event.data; diff --git a/tutorials/katacoda/command-watch-cn/watch.md b/tutorials/katacoda/command-watch-cn/watch.md index a4030b1df..93917877d 100644 --- a/tutorials/katacoda/command-watch-cn/watch.md +++ b/tutorials/katacoda/command-watch-cn/watch.md @@ -11,7 +11,7 @@ watch 的参数比较多,主要是因为它能在 4 个不同的场景观察 |---:|:---| |*class-pattern*|类名表达式匹配| |*method-pattern*|方法名表达式匹配| -|*express*|观察表达式| +|*express*|观察表达式,默认值:`{params, target, returnObj}`| |*condition-express*|条件表达式| |[b]|在**方法调用之前**观察| |[e]|在**方法异常之后**观察| @@ -36,29 +36,49 @@ watch 的参数比较多,主要是因为它能在 4 个不同的场景观察 ### 使用参考 -#### 观察方法出参和返回值 +#### 观察方法出参、this对象和返回值 -`watch demo.MathGame primeFactors "{params,returnObj}" -x 2`{{execute T2}} +> 观察表达式,默认值是`{params, target, returnObj}`。 + +`watch demo.MathGame primeFactors -x 2`{{execute T2}} 按`Q`{{execute T2}}或者`Ctrl+c`退出 ```bash -$ watch demo.MathGame primeFactors "{params,returnObj}" -x 2 -Press Ctrl+C to abort. -Affect(class-cnt:1 , method-cnt:1) cost in 44 ms. -ts=2018-12-03 19:16:51; [cost=1.280502ms] result=@ArrayList[ +$ watch demo.MathGame primeFactors -x 2 +Press Q or Ctrl+C to abort. +Affect(class count: 1 , method count: 1) cost in 32 ms, listenerId: 5 +method=demo.MathGame.primeFactors location=AtExceptionExit +ts=2021-08-31 15:22:57; [cost=0.220625ms] result=@ArrayList[ + @Object[][ + @Integer[-179173], + ], + @MathGame[ + random=@Random[java.util.Random@31cefde0], + illegalArgumentCount=@Integer[44], + ], + null, +] +method=demo.MathGame.primeFactors location=AtExit +ts=2021-08-31 15:22:58; [cost=1.020982ms] result=@ArrayList[ @Object[][ @Integer[1], ], + @MathGame[ + random=@Random[java.util.Random@31cefde0], + illegalArgumentCount=@Integer[44], + ], @ArrayList[ - @Integer[3], - @Integer[19], - @Integer[191], - @Integer[49199], + @Integer[2], + @Integer[2], + @Integer[26947], ], ] ``` +* 上面的结果里,说明函数被执行了两次,第一次结果是`location=AtExceptionExit`,说明函数抛出异常了,因此`returnObj`是null +* 在第二次结果里是`location=AtExit`,说明函数正常返回,因此可以看到`returnObj`结果是一个ArrayList + #### 观察方法入参 `watch demo.MathGame primeFactors "{params,returnObj}" -x 2 -b`{{execute T2}} diff --git a/tutorials/katacoda/command-watch-en/watch.md b/tutorials/katacoda/command-watch-en/watch.md index 2231879c5..8716f2685 100644 --- a/tutorials/katacoda/command-watch-en/watch.md +++ b/tutorials/katacoda/command-watch-en/watch.md @@ -11,7 +11,7 @@ There are four different scenarios for `watch` command, which makes it rather co |---:|:---| |*class-pattern*|pattern for the class name| |*method-pattern*|pattern for the method name| -|*expression*|expression to monitor| +|*expression*|expression to watch, default value `{params, target, returnObj}`| |*condition-expression*|condition expression to filter| |[b]|before method being invoked| |[e]|when method encountering exceptions| @@ -26,7 +26,7 @@ F.Y.I 3. at the *watching* point, Arthas will use the *expression* to evaluate the variables and print them out; 4. `in parameters` and `out parameters` are different since they can be modified within the invoked methods; `params` stands for `in parameters` in `-b`while `out parameters` in other *watching* points; 5. there are no `return values` and `exceptions` when using `-b`. - +6. In the result of the watch command, the `location` information will be printed. There are three possible values for `location`: `AtEnter`, `AtExit`, and `AtExceptionExit`. Corresponding to the method entry, the method returns normally, and the method throws an exception. Advanced: * [Special usages](https://github.com/alibaba/arthas/issues/71) @@ -34,29 +34,45 @@ Advanced: ### Usage -#### Check the `out parameters` and `return value` - -`watch demo.MathGame primeFactors "{params,returnObj}" -x 2`{{execute T2}} +#### Check the `out parameters`, `this` and `return value` -Press `Q`{{execute T2}} or `Ctrl+C` to abort +> The expression to watch, default value `{params, target, returnObj}` ```bash -$ watch demo.MathGame primeFactors "{params,returnObj}" -x 2 -Press Ctrl+C to abort. -Affect(class-cnt:1 , method-cnt:1) cost in 44 ms. -ts=2018-12-03 19:16:51; [cost=1.280502ms] result=@ArrayList[ +$ watch demo.MathGame primeFactors -x 2 +Press Q or Ctrl+C to abort. +Affect(class count: 1 , method count: 1) cost in 32 ms, listenerId: 5 +method=demo.MathGame.primeFactors location=AtExceptionExit +ts=2021-08-31 15:22:57; [cost=0.220625ms] result=@ArrayList[ + @Object[][ + @Integer[-179173], + ], + @MathGame[ + random=@Random[java.util.Random@31cefde0], + illegalArgumentCount=@Integer[44], + ], + null, +] +method=demo.MathGame.primeFactors location=AtExit +ts=2021-08-31 15:22:58; [cost=1.020982ms] result=@ArrayList[ @Object[][ @Integer[1], ], + @MathGame[ + random=@Random[java.util.Random@31cefde0], + illegalArgumentCount=@Integer[44], + ], @ArrayList[ - @Integer[3], - @Integer[19], - @Integer[191], - @Integer[49199], + @Integer[2], + @Integer[2], + @Integer[26947], ], ] ``` +* In the above result, the method is executed twice, the first result is `location=AtExceptionExit`, indicating that the method throws an exception, so `returnObj` is null +* In the second result is `location=AtExit`, indicating that the method returns normally, so you can see that the result of `returnObj` is an ArrayList + #### Check `in parameters` `watch demo.MathGame primeFactors "{params,returnObj}" -x 2 -b`{{execute T2}}