Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
9d011637
D
dragonwell8_hotspot
项目概览
openanolis
/
dragonwell8_hotspot
通知
2
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_hotspot
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
9d011637
编写于
3月 17, 2013
作者:
D
dcubed
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
735c82ca
322081c6
变更
25
展开全部
隐藏空白更改
内联
并排
Showing
25 changed file
with
2157 addition
and
1051 deletion
+2157
-1051
agent/src/os/bsd/MacosxDebuggerLocal.m
agent/src/os/bsd/MacosxDebuggerLocal.m
+388
-309
agent/src/os/bsd/Makefile
agent/src/os/bsd/Makefile
+38
-13
agent/src/os/bsd/libproc.h
agent/src/os/bsd/libproc.h
+40
-9
agent/src/os/bsd/libproc_impl.c
agent/src/os/bsd/libproc_impl.c
+288
-188
agent/src/os/bsd/libproc_impl.h
agent/src/os/bsd/libproc_impl.h
+99
-10
agent/src/os/bsd/ps_core.c
agent/src/os/bsd/ps_core.c
+920
-452
agent/src/os/bsd/symtab.c
agent/src/os/bsd/symtab.c
+174
-25
agent/src/os/bsd/symtab.h
agent/src/os/bsd/symtab.h
+3
-3
agent/src/share/classes/sun/jvm/hotspot/BsdVtblAccess.java
agent/src/share/classes/sun/jvm/hotspot/BsdVtblAccess.java
+12
-5
agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java
...t/src/share/classes/sun/jvm/hotspot/CommandProcessor.java
+2
-2
agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java
agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java
+32
-1
agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java
...lasses/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java
+44
-8
agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java
...share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java
+9
-3
agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java
...src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java
+5
-1
agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java
agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java
+11
-1
agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java
agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java
+7
-1
agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java
...share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java
+3
-3
agent/src/share/native/sadis.c
agent/src/share/native/sadis.c
+7
-5
make/bsd/makefiles/saproc.make
make/bsd/makefiles/saproc.make
+12
-6
src/share/vm/classfile/classLoaderData.cpp
src/share/vm/classfile/classLoaderData.cpp
+5
-0
src/share/vm/classfile/systemDictionary.cpp
src/share/vm/classfile/systemDictionary.cpp
+39
-5
src/share/vm/classfile/systemDictionary.hpp
src/share/vm/classfile/systemDictionary.hpp
+1
-0
src/share/vm/memory/metaspace.cpp
src/share/vm/memory/metaspace.cpp
+3
-0
src/share/vm/oops/klass.cpp
src/share/vm/oops/klass.cpp
+6
-0
src/share/vm/oops/method.cpp
src/share/vm/oops/method.cpp
+9
-1
未找到文件。
agent/src/os/bsd/MacosxDebuggerLocal.m
浏览文件 @
9d011637
此差异已折叠。
点击以展开。
agent/src/os/bsd/Makefile
浏览文件 @
9d011637
#
#
# Copyright (c) 2002, 20
09
, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2002, 20
13
, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
#
# This code is free software; you can redistribute it and/or modify it
# This code is free software; you can redistribute it and/or modify it
...
@@ -22,34 +22,60 @@
...
@@ -22,34 +22,60 @@
#
#
#
#
ARCH
:=
$(
shell
if
([
`
uname
-m
`
=
"ia64"
]
)
;
then
echo
ia64
;
elif
([
`
uname
-m
`
=
"amd64"
]
)
;
then
echo
amd64
;
elif
([
`
uname
-m
`
=
"sparc64"
]
)
;
then
echo
sparc
;
else
echo
i386
;
fi
)
ARCH
:=
$(
shell
if
([
`
uname
-m
`
=
"ia64"
]
)
;
then
echo
ia64
;
elif
([
`
uname
-m
`
=
"amd64"
]
)
;
then
echo
amd64
;
elif
([
`
uname
-m
`
=
"x86_64"
]
)
;
then
echo
amd64
;
elif
([
`
uname
-m
`
=
"sparc64"
]
)
;
then
echo
sparc
;
else
echo
i386
;
fi
)
OS
:=
$(
shell
uname
-s
)
GCC
=
gcc
GCC
=
gcc
JAVAH
=
${JAVA_HOME}
/bin/javah
JAVAH
=
${JAVA_HOME}
/bin/javah
ifneq
($(OS), Darwin)
SOURCES
=
salibelf.c
\
SOURCES
=
salibelf.c
\
symtab.c
\
symtab.c
\
libproc_impl.c
\
libproc_impl.c
\
ps_proc.c
\
ps_proc.c
\
ps_core.c
\
ps_core.c
\
BsdDebuggerLocal.c
BsdDebuggerLocal.c
OBJS
=
$(SOURCES:.c=.o)
OBJSPLUS
=
$(OBJS)
sadis.o
LIBSA
=
$(ARCH)
/libsaproc.so
INCLUDES
=
-I
${JAVA_HOME}
/include
-I
${JAVA_HOME}
/include/
$(
shell
uname
-s
|
tr
"[:upper:]"
"[:lower:]"
)
LIBS
=
-lutil
-lthread_db
OBJS
=
$(SOURCES:.c=.o)
else
LIBS
=
-lutil
-lthread_db
SOURCES
=
symtab.c
\
libproc_impl.c
\
ps_core.c
OBJS
=
$(SOURCES:.c=.o)
OBJSPLUS
=
MacosxDebuggerLocal.o sadis.o
$(OBJS)
EXTINCLUDE
=
-I
/System/Library/Frameworks/JavaVM.framework/Headers
-I
.
EXTCFLAGS
=
-m64
-D__APPLE__
-framework
JavaNativeFoundation
FOUNDATIONFLAGS
=
-framework
Foundation
-F
/System/Library/Frameworks/JavaVM.framework/Frameworks
-framework
JavaNativeFoundation
-framework
Security
-framework
CoreFoundation
LIBSA
=
$(ARCH)
/libsaproc.dylib
endif
# Darwin
INCLUDES
=
-I
${JAVA_HOME}
/include
-I
${JAVA_HOME}
/include/
$(
shell
uname
-s
|
tr
"[:upper:]"
"[:lower:]"
)
$(EXTINCLUDE)
CFLAGS
=
-c
-fPIC
-g
-Wall
-D_ALLBSD_SOURCE
-D_GNU_SOURCE
-D
$(ARCH)
$(INCLUDES)
$(EXTCFLAGS)
CFLAGS
=
-c
-fPIC
-g
-Wall
-D_ALLBSD_SOURCE
-D_GNU_SOURCE
-D
$(ARCH)
$(INCLUDES)
LIBSA
=
$(ARCH)
/libsaproc.so
all
:
$(LIBSA)
all
:
$(LIBSA)
BsdDebuggerLocal.o
:
BsdDebuggerLocal.c
MacosxDebuggerLocal.o
:
MacosxDebuggerLocal.m
$(JAVAH)
-jni
-classpath
../../../../../build/bsd-i586/hotspot/outputdir/bsd_i486_compiler2/generated/saclasses
\
echo
"OS="
$(OS)
$(JAVAH)
-jni
-classpath
../../../build/classes
\
sun.jvm.hotspot.debugger.x86.X86ThreadContext
\
sun.jvm.hotspot.debugger.x86.X86ThreadContext
\
sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext
sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext
$(GCC)
$(CFLAGS)
$(FOUNDATIONFLAGS)
$<
sadis.o
:
../../share/native/sadis.c
$(JAVAH)
-jni
-classpath
../../../build/classes
\
sun.jvm.hotspot.asm.Disassembler
$(GCC)
$(CFLAGS)
$<
$(GCC)
$(CFLAGS)
$<
.c.obj
:
.c.obj
:
...
@@ -59,9 +85,9 @@ ifndef LDNOMAP
...
@@ -59,9 +85,9 @@ ifndef LDNOMAP
LFLAGS_LIBSA
=
-Xlinker
--version-script
=
mapfile
LFLAGS_LIBSA
=
-Xlinker
--version-script
=
mapfile
endif
endif
$(LIBSA)
:
$(OBJS
) mapfile
$(LIBSA)
:
$(OBJS
PLUS) mapfile
if
[
!
-d
$(ARCH)
]
;
then
mkdir
$(ARCH)
;
fi
if
[
!
-d
$(ARCH)
]
;
then
mkdir
$(ARCH)
;
fi
$(GCC)
-shared
$(LFLAGS_LIBSA)
-o
$(LIBSA)
$(
OBJS)
$(
LIBS)
$(GCC)
-shared
$(LFLAGS_LIBSA)
-o
$(LIBSA)
$(
FOUNDATIONFLAGS)
$(OBJSPLUS)
$(LIBS)
$(SA
LIBS)
test.o
:
$(LIBSA) test.c
test.o
:
$(LIBSA) test.c
$(GCC)
-c
-o
test.o
-g
-D_GNU_SOURCE
-D
$(ARCH)
$(INCLUDES)
test.c
$(GCC)
-c
-o
test.o
-g
-D_GNU_SOURCE
-D
$(ARCH)
$(INCLUDES)
test.c
...
@@ -71,7 +97,6 @@ test: test.o
...
@@ -71,7 +97,6 @@ test: test.o
clean
:
clean
:
rm
-f
$(LIBSA)
rm
-f
$(LIBSA)
rm
-f
$(OBJS)
rm
-f
*
.o
rm
-f
test.o
rm
-f
test.o
-
rmdir
$(ARCH)
-
rmdir
$(ARCH)
agent/src/os/bsd/libproc.h
浏览文件 @
9d011637
/*
/*
* Copyright (c) 2003, 20
07
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 20
13
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -27,9 +27,38 @@
...
@@ -27,9 +27,38 @@
#include <unistd.h>
#include <unistd.h>
#include <stdint.h>
#include <stdint.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#ifdef __APPLE__
typedef
enum
ps_err_e
{
PS_OK
,
PS_ERR
,
PS_BADPID
,
PS_BADLID
,
PS_BADADDR
,
PS_NOSYM
,
PS_NOFREGS
}
ps_err_e
;
#ifndef psaddr_t
#define psaddr_t uintptr_t
#endif
#ifndef bool
typedef
int
bool
;
#define true 1
#define false 0
#endif // bool
#ifndef lwpid_t
#define lwpid_t uintptr_t
#endif
#include <mach/thread_status.h>
#else // __APPLE__
#include <elf.h>
#include <link.h>
#include <machine/reg.h>
#include <machine/reg.h>
#include <proc_service.h>
#include <proc_service.h>
#if defined(sparc) || defined(sparcv9)
#if defined(sparc) || defined(sparcv9)
/*
/*
If _LP64 is defined ptrace.h should be taken from /usr/include/asm-sparc64
If _LP64 is defined ptrace.h should be taken from /usr/include/asm-sparc64
...
@@ -44,6 +73,14 @@
...
@@ -44,6 +73,14 @@
#endif //sparc or sparcv9
#endif //sparc or sparcv9
// This C bool type must be int for compatibility with BSD calls and
// it would be a mistake to equivalence it to C++ bool on many platforms
typedef
int
bool
;
#define true 1
#define false 0
#endif // __APPLE__
/************************************************************************************
/************************************************************************************
0. This is very minimal subset of Solaris libproc just enough for current application.
0. This is very minimal subset of Solaris libproc just enough for current application.
...
@@ -72,13 +109,7 @@ combination of ptrace and /proc calls.
...
@@ -72,13 +109,7 @@ combination of ptrace and /proc calls.
*************************************************************************************/
*************************************************************************************/
// This C bool type must be int for compatibility with BSD calls and
struct
reg
;
// it would be a mistake to equivalence it to C++ bool on many platforms
typedef
int
bool
;
#define true 1
#define false 0
struct
ps_prochandle
;
struct
ps_prochandle
;
// attach to a process
// attach to a process
...
...
agent/src/os/bsd/libproc_impl.c
浏览文件 @
9d011637
...
@@ -21,12 +21,6 @@
...
@@ -21,12 +21,6 @@
* questions.
* questions.
*
*
*/
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <thread_db.h>
#include "libproc_impl.h"
#include "libproc_impl.h"
static
const
char
*
alt_root
=
NULL
;
static
const
char
*
alt_root
=
NULL
;
...
@@ -34,61 +28,65 @@ static int alt_root_len = -1;
...
@@ -34,61 +28,65 @@ static int alt_root_len = -1;
#define SA_ALTROOT "SA_ALTROOT"
#define SA_ALTROOT "SA_ALTROOT"
off_t
ltell
(
int
fd
)
{
return
lseek
(
fd
,
0
,
SEEK_CUR
);
}
static
void
init_alt_root
()
{
static
void
init_alt_root
()
{
if
(
alt_root_len
==
-
1
)
{
if
(
alt_root_len
==
-
1
)
{
alt_root
=
getenv
(
SA_ALTROOT
);
alt_root
=
getenv
(
SA_ALTROOT
);
if
(
alt_root
)
{
if
(
alt_root
)
{
alt_root_len
=
strlen
(
alt_root
);
alt_root_len
=
strlen
(
alt_root
);
}
else
{
}
else
{
alt_root_len
=
0
;
alt_root_len
=
0
;
}
}
}
}
}
}
int
pathmap_open
(
const
char
*
name
)
{
int
pathmap_open
(
const
char
*
name
)
{
int
fd
;
int
fd
;
char
alt_path
[
PATH_MAX
+
1
];
char
alt_path
[
PATH_MAX
+
1
];
init_alt_root
();
init_alt_root
();
if
(
alt_root_len
>
0
)
{
fd
=
open
(
name
,
O_RDONLY
);
strcpy
(
alt_path
,
alt_root
);
if
(
fd
>=
0
)
{
strcat
(
alt_path
,
name
);
fd
=
open
(
alt_path
,
O_RDONLY
);
if
(
fd
>=
0
)
{
print_debug
(
"path %s substituted for %s
\n
"
,
alt_path
,
name
);
return
fd
;
return
fd
;
}
}
if
(
alt_root_len
>
0
)
{
if
(
strrchr
(
name
,
'/'
)
)
{
strcpy
(
alt_path
,
alt_root
);
strcpy
(
alt_path
,
alt_root
);
strcat
(
alt_path
,
name
);
strcat
(
alt_path
,
strrchr
(
name
,
'/'
)
);
fd
=
open
(
alt_path
,
O_RDONLY
);
fd
=
open
(
alt_path
,
O_RDONLY
);
if
(
fd
>=
0
)
{
if
(
fd
>=
0
)
{
print_debug
(
"path %s substituted for %s
\n
"
,
alt_path
,
name
);
print_debug
(
"path %s substituted for %s
\n
"
,
alt_path
,
name
);
return
fd
;
return
fd
;
}
if
(
strrchr
(
name
,
'/'
))
{
strcpy
(
alt_path
,
alt_root
);
strcat
(
alt_path
,
strrchr
(
name
,
'/'
));
fd
=
open
(
alt_path
,
O_RDONLY
);
if
(
fd
>=
0
)
{
print_debug
(
"path %s substituted for %s
\n
"
,
alt_path
,
name
);
return
fd
;
}
}
}
}
}
}
else
{
return
-
1
;
fd
=
open
(
name
,
O_RDONLY
);
if
(
fd
>=
0
)
{
return
fd
;
}
}
return
-
1
;
}
}
static
bool
_libsaproc_debug
;
static
bool
_libsaproc_debug
;
void
print_debug
(
const
char
*
format
,...)
{
void
print_debug
(
const
char
*
format
,...)
{
if
(
_libsaproc_debug
)
{
if
(
_libsaproc_debug
)
{
va_list
alist
;
va_list
alist
;
va_start
(
alist
,
format
);
va_start
(
alist
,
format
);
fputs
(
"libsaproc DEBUG: "
,
stderr
);
fputs
(
"libsaproc DEBUG: "
,
stderr
);
vfprintf
(
stderr
,
format
,
alist
);
vfprintf
(
stderr
,
format
,
alist
);
va_end
(
alist
);
va_end
(
alist
);
}
}
}
}
void
print_error
(
const
char
*
format
,...)
{
void
print_error
(
const
char
*
format
,...)
{
...
@@ -100,172 +98,235 @@ void print_error(const char* format,...) {
...
@@ -100,172 +98,235 @@ void print_error(const char* format,...) {
}
}
bool
is_debug
()
{
bool
is_debug
()
{
return
_libsaproc_debug
;
return
_libsaproc_debug
;
}
}
#ifdef __APPLE__
// get arch offset in file
bool
get_arch_off
(
int
fd
,
cpu_type_t
cputype
,
off_t
*
offset
)
{
struct
fat_header
fatheader
;
struct
fat_arch
fatarch
;
off_t
img_start
=
0
;
off_t
pos
=
ltell
(
fd
);
if
(
read
(
fd
,
(
void
*
)
&
fatheader
,
sizeof
(
struct
fat_header
))
!=
sizeof
(
struct
fat_header
))
{
return
false
;
}
if
(
fatheader
.
magic
==
FAT_CIGAM
)
{
int
i
;
for
(
i
=
0
;
i
<
ntohl
(
fatheader
.
nfat_arch
);
i
++
)
{
if
(
read
(
fd
,
(
void
*
)
&
fatarch
,
sizeof
(
struct
fat_arch
))
!=
sizeof
(
struct
fat_arch
))
{
return
false
;
}
if
(
ntohl
(
fatarch
.
cputype
)
==
cputype
)
{
print_debug
(
"fat offset=%x
\n
"
,
ntohl
(
fatarch
.
offset
));
img_start
=
ntohl
(
fatarch
.
offset
);
break
;
}
}
if
(
img_start
==
0
)
{
return
false
;
}
}
lseek
(
fd
,
pos
,
SEEK_SET
);
*
offset
=
img_start
;
return
true
;
}
bool
is_macho_file
(
int
fd
)
{
mach_header_64
fhdr
;
off_t
x86_64_off
;
if
(
fd
<
0
)
{
print_debug
(
"Invalid file handle passed to is_macho_file
\n
"
);
return
false
;
}
off_t
pos
=
ltell
(
fd
);
// check fat header
if
(
!
get_arch_off
(
fd
,
CPU_TYPE_X86_64
,
&
x86_64_off
))
{
print_debug
(
"failed to get fat header
\n
"
);
return
false
;
}
lseek
(
fd
,
x86_64_off
,
SEEK_SET
);
if
(
read
(
fd
,
(
void
*
)
&
fhdr
,
sizeof
(
mach_header_64
))
!=
sizeof
(
mach_header_64
))
{
return
false
;
}
lseek
(
fd
,
pos
,
SEEK_SET
);
// restore
print_debug
(
"fhdr.magic %x
\n
"
,
fhdr
.
magic
);
return
(
fhdr
.
magic
==
MH_MAGIC_64
||
fhdr
.
magic
==
MH_CIGAM_64
);
}
#endif //__APPLE__
// initialize libproc
// initialize libproc
bool
init_libproc
(
bool
debug
)
{
bool
init_libproc
(
bool
debug
)
{
// init debug mode
_libsaproc_debug
=
debug
;
_libsaproc_debug
=
debug
;
#ifndef __APPLE__
// initialize the thread_db library
// initialize the thread_db library
if
(
td_init
()
!=
TD_OK
)
{
if
(
td_init
()
!=
TD_OK
)
{
print_debug
(
"libthread_db's td_init failed
\n
"
);
print_debug
(
"libthread_db's td_init failed
\n
"
);
return
false
;
return
false
;
}
}
#endif // __APPLE__
return
true
;
return
true
;
}
}
static
void
destroy_lib_info
(
struct
ps_prochandle
*
ph
)
{
void
destroy_lib_info
(
struct
ps_prochandle
*
ph
)
{
lib_info
*
lib
=
ph
->
libs
;
lib_info
*
lib
=
ph
->
libs
;
while
(
lib
)
{
while
(
lib
)
{
lib_info
*
next
=
lib
->
next
;
lib_info
*
next
=
lib
->
next
;
if
(
lib
->
symtab
)
{
if
(
lib
->
symtab
)
{
destroy_symtab
(
lib
->
symtab
);
destroy_symtab
(
lib
->
symtab
);
}
}
free
(
lib
);
free
(
lib
);
lib
=
next
;
lib
=
next
;
}
}
}
}
static
void
destroy_thread_info
(
struct
ps_prochandle
*
ph
)
{
void
destroy_thread_info
(
struct
ps_prochandle
*
ph
)
{
thread_info
*
thr
=
ph
->
threads
;
sa_
thread_info
*
thr
=
ph
->
threads
;
while
(
thr
)
{
while
(
thr
)
{
thread_info
*
next
=
thr
->
next
;
sa_thread_info
*
n
=
thr
->
next
;
free
(
thr
);
free
(
thr
);
thr
=
next
;
thr
=
n
;
}
}
}
}
// ps_prochandle cleanup
// ps_prochandle cleanup
// ps_prochandle cleanup
void
Prelease
(
struct
ps_prochandle
*
ph
)
{
void
Prelease
(
struct
ps_prochandle
*
ph
)
{
// do the "derived class" clean-up first
// do the "derived class" clean-up first
ph
->
ops
->
release
(
ph
);
ph
->
ops
->
release
(
ph
);
destroy_lib_info
(
ph
);
destroy_lib_info
(
ph
);
destroy_thread_info
(
ph
);
destroy_thread_info
(
ph
);
free
(
ph
);
free
(
ph
);
}
}
lib_info
*
add_lib_info
(
struct
ps_prochandle
*
ph
,
const
char
*
libname
,
uintptr_t
base
)
{
lib_info
*
add_lib_info
(
struct
ps_prochandle
*
ph
,
const
char
*
libname
,
uintptr_t
base
)
{
return
add_lib_info_fd
(
ph
,
libname
,
-
1
,
base
);
return
add_lib_info_fd
(
ph
,
libname
,
-
1
,
base
);
}
}
lib_info
*
add_lib_info_fd
(
struct
ps_prochandle
*
ph
,
const
char
*
libname
,
int
fd
,
uintptr_t
base
)
{
lib_info
*
add_lib_info_fd
(
struct
ps_prochandle
*
ph
,
const
char
*
libname
,
int
fd
,
uintptr_t
base
)
{
lib_info
*
newlib
;
lib_info
*
newlib
;
print_debug
(
"add_lib_info_fd %s
\n
"
,
libname
);
if
(
(
newlib
=
(
lib_info
*
)
calloc
(
1
,
sizeof
(
struct
lib_info
)))
==
NULL
)
{
if
(
(
newlib
=
(
lib_info
*
)
calloc
(
1
,
sizeof
(
struct
lib_info
)))
==
NULL
)
{
print_debug
(
"can't allocate memory for lib_info
\n
"
);
print_debug
(
"can't allocate memory for lib_info
\n
"
);
return
NULL
;
return
NULL
;
}
}
strncpy
(
newlib
->
name
,
libname
,
sizeof
(
newlib
->
name
));
strncpy
(
newlib
->
name
,
libname
,
sizeof
(
newlib
->
name
));
newlib
->
base
=
base
;
newlib
->
base
=
base
;
if
(
fd
==
-
1
)
{
if
(
fd
==
-
1
)
{
if
(
(
newlib
->
fd
=
pathmap_open
(
newlib
->
name
))
<
0
)
{
if
(
(
newlib
->
fd
=
pathmap_open
(
newlib
->
name
))
<
0
)
{
print_debug
(
"can't open shared object %s
\n
"
,
newlib
->
name
);
print_debug
(
"can't open shared object %s
\n
"
,
newlib
->
name
);
free
(
newlib
);
return
NULL
;
}
}
else
{
newlib
->
fd
=
fd
;
}
// check whether we have got an ELF file. /proc/<pid>/map
// gives out all file mappings and not just shared objects
if
(
is_elf_file
(
newlib
->
fd
)
==
false
)
{
close
(
newlib
->
fd
);
free
(
newlib
);
free
(
newlib
);
return
NULL
;
return
NULL
;
}
}
}
else
{
newlib
->
fd
=
fd
;
}
newlib
->
symtab
=
build_symtab
(
newlib
->
fd
);
#ifdef __APPLE__
if
(
newlib
->
symtab
==
NULL
)
{
// check whether we have got an Macho file.
print_debug
(
"symbol table build failed for %s
\n
"
,
newlib
->
name
);
if
(
is_macho_file
(
newlib
->
fd
)
==
false
)
{
}
close
(
newlib
->
fd
);
else
{
free
(
newlib
);
print_debug
(
"built symbol table for %s
\n
"
,
newlib
->
name
);
print_debug
(
"not a mach-o file
\n
"
);
}
return
NULL
;
}
#else
// check whether we have got an ELF file. /proc/<pid>/map
// gives out all file mappings and not just shared objects
if
(
is_elf_file
(
newlib
->
fd
)
==
false
)
{
close
(
newlib
->
fd
);
free
(
newlib
);
return
NULL
;
}
#endif // __APPLE__
// even if symbol table building fails, we add the lib_info.
newlib
->
symtab
=
build_symtab
(
newlib
->
fd
);
// This is because we may need to read from the ELF file for core file
if
(
newlib
->
symtab
==
NULL
)
{
// address read functionality. lookup_symbol checks for NULL symtab.
print_debug
(
"symbol table build failed for %s
\n
"
,
newlib
->
name
);
if
(
ph
->
libs
)
{
}
else
{
ph
->
lib_tail
->
next
=
newlib
;
print_debug
(
"built symbol table for %s
\n
"
,
newlib
->
name
);
ph
->
lib_tail
=
newlib
;
}
}
else
{
ph
->
libs
=
ph
->
lib_tail
=
newlib
;
}
ph
->
num_libs
++
;
return
newlib
;
// even if symbol table building fails, we add the lib_info.
// This is because we may need to read from the ELF file or MachO file for core file
// address read functionality. lookup_symbol checks for NULL symtab.
if
(
ph
->
libs
)
{
ph
->
lib_tail
->
next
=
newlib
;
ph
->
lib_tail
=
newlib
;
}
else
{
ph
->
libs
=
ph
->
lib_tail
=
newlib
;
}
ph
->
num_libs
++
;
return
newlib
;
}
}
// lookup for a specific symbol
// lookup for a specific symbol
uintptr_t
lookup_symbol
(
struct
ps_prochandle
*
ph
,
const
char
*
object_name
,
uintptr_t
lookup_symbol
(
struct
ps_prochandle
*
ph
,
const
char
*
object_name
,
const
char
*
sym_name
)
{
const
char
*
sym_name
)
{
// ignore object_name. search in all libraries
// ignore object_name. search in all libraries
// FIXME: what should we do with object_name?? The library names are obtained
// FIXME: what should we do with object_name?? The library names are obtained
// by parsing /proc/<pid>/maps, which may not be the same as object_name.
// by parsing /proc/<pid>/maps, which may not be the same as object_name.
// What we need is a utility to map object_name to real file name, something
// What we need is a utility to map object_name to real file name, something
// dlopen() does by looking at LD_LIBRARY_PATH and /etc/ld.so.cache. For
// dlopen() does by looking at LD_LIBRARY_PATH and /etc/ld.so.cache. For
// now, we just ignore object_name and do a global search for the symbol.
// now, we just ignore object_name and do a global search for the symbol.
lib_info
*
lib
=
ph
->
libs
;
lib_info
*
lib
=
ph
->
libs
;
while
(
lib
)
{
while
(
lib
)
{
if
(
lib
->
symtab
)
{
if
(
lib
->
symtab
)
{
uintptr_t
res
=
search_symbol
(
lib
->
symtab
,
lib
->
base
,
sym_name
,
NULL
);
uintptr_t
res
=
search_symbol
(
lib
->
symtab
,
lib
->
base
,
sym_name
,
NULL
);
if
(
res
)
return
res
;
if
(
res
)
return
res
;
}
}
lib
=
lib
->
next
;
lib
=
lib
->
next
;
}
}
print_debug
(
"lookup failed for symbol '%s' in obj '%s'
\n
"
,
print_debug
(
"lookup failed for symbol '%s' in obj '%s'
\n
"
,
sym_name
,
object_name
);
sym_name
,
object_name
);
return
(
uintptr_t
)
NULL
;
return
(
uintptr_t
)
NULL
;
}
}
const
char
*
symbol_for_pc
(
struct
ps_prochandle
*
ph
,
uintptr_t
addr
,
uintptr_t
*
poffset
)
{
const
char
*
symbol_for_pc
(
struct
ps_prochandle
*
ph
,
uintptr_t
addr
,
uintptr_t
*
poffset
)
{
const
char
*
res
=
NULL
;
const
char
*
res
=
NULL
;
lib_info
*
lib
=
ph
->
libs
;
lib_info
*
lib
=
ph
->
libs
;
while
(
lib
)
{
while
(
lib
)
{
if
(
lib
->
symtab
&&
addr
>=
lib
->
base
)
{
if
(
lib
->
symtab
&&
addr
>=
lib
->
base
)
{
res
=
nearest_symbol
(
lib
->
symtab
,
addr
-
lib
->
base
,
poffset
);
res
=
nearest_symbol
(
lib
->
symtab
,
addr
-
lib
->
base
,
poffset
);
if
(
res
)
return
res
;
if
(
res
)
return
res
;
}
}
lib
=
lib
->
next
;
lib
=
lib
->
next
;
}
}
return
NULL
;
return
NULL
;
}
}
// add a thread to ps_prochandle
// add a thread to ps_prochandle
thread_info
*
add_thread_info
(
struct
ps_prochandle
*
ph
,
pthread_t
pthread_id
,
lwpid_t
lwp_id
)
{
sa_
thread_info
*
add_thread_info
(
struct
ps_prochandle
*
ph
,
pthread_t
pthread_id
,
lwpid_t
lwp_id
)
{
thread_info
*
newthr
;
sa_
thread_info
*
newthr
;
if
(
(
newthr
=
(
thread_info
*
)
calloc
(
1
,
sizeof
(
thread_info
)))
==
NULL
)
{
if
(
(
newthr
=
(
sa_thread_info
*
)
calloc
(
1
,
sizeof
(
sa_
thread_info
)))
==
NULL
)
{
print_debug
(
"can't allocate memory for thread_info
\n
"
);
print_debug
(
"can't allocate memory for thread_info
\n
"
);
return
NULL
;
return
NULL
;
}
}
// initialize thread info
// initialize thread info
newthr
->
pthread_id
=
pthread_id
;
newthr
->
pthread_id
=
pthread_id
;
newthr
->
lwp_id
=
lwp_id
;
newthr
->
lwp_id
=
lwp_id
;
// add new thread to the list
// add new thread to the list
newthr
->
next
=
ph
->
threads
;
newthr
->
next
=
ph
->
threads
;
ph
->
threads
=
newthr
;
ph
->
threads
=
newthr
;
ph
->
num_threads
++
;
ph
->
num_threads
++
;
return
newthr
;
return
newthr
;
}
}
#ifndef __APPLE__
// struct used for client data from thread_db callback
// struct used for client data from thread_db callback
struct
thread_db_client_data
{
struct
thread_db_client_data
{
struct
ps_prochandle
*
ph
;
struct
ps_prochandle
*
ph
;
thread_info_callback
callback
;
thread_info_callback
callback
;
};
};
// callback function for libthread_db
// callback function for libthread_db
...
@@ -314,6 +375,7 @@ bool read_thread_info(struct ps_prochandle* ph, thread_info_callback cb) {
...
@@ -314,6 +375,7 @@ bool read_thread_info(struct ps_prochandle* ph, thread_info_callback cb) {
return
true
;
return
true
;
}
}
#endif // __APPLE__
// get number of threads
// get number of threads
int
get_num_threads
(
struct
ps_prochandle
*
ph
)
{
int
get_num_threads
(
struct
ps_prochandle
*
ph
)
{
...
@@ -322,18 +384,54 @@ int get_num_threads(struct ps_prochandle* ph) {
...
@@ -322,18 +384,54 @@ int get_num_threads(struct ps_prochandle* ph) {
// get lwp_id of n'th thread
// get lwp_id of n'th thread
lwpid_t
get_lwp_id
(
struct
ps_prochandle
*
ph
,
int
index
)
{
lwpid_t
get_lwp_id
(
struct
ps_prochandle
*
ph
,
int
index
)
{
int
count
=
0
;
int
count
=
0
;
thread_info
*
thr
=
ph
->
threads
;
sa_
thread_info
*
thr
=
ph
->
threads
;
while
(
thr
)
{
while
(
thr
)
{
if
(
count
==
index
)
{
if
(
count
==
index
)
{
return
thr
->
lwp_id
;
return
thr
->
lwp_id
;
}
}
count
++
;
count
++
;
thr
=
thr
->
next
;
thr
=
thr
->
next
;
}
}
return
-
1
;
return
0
;
}
}
#ifdef __APPLE__
// set lwp_id of n'th thread
bool
set_lwp_id
(
struct
ps_prochandle
*
ph
,
int
index
,
lwpid_t
lwpid
)
{
int
count
=
0
;
sa_thread_info
*
thr
=
ph
->
threads
;
while
(
thr
)
{
if
(
count
==
index
)
{
thr
->
lwp_id
=
lwpid
;
return
true
;
}
count
++
;
thr
=
thr
->
next
;
}
return
false
;
}
// get regs of n-th thread, only used in fillThreads the first time called
bool
get_nth_lwp_regs
(
struct
ps_prochandle
*
ph
,
int
index
,
struct
reg
*
regs
)
{
int
count
=
0
;
sa_thread_info
*
thr
=
ph
->
threads
;
while
(
thr
)
{
if
(
count
==
index
)
{
break
;
}
count
++
;
thr
=
thr
->
next
;
}
if
(
thr
!=
NULL
)
{
memcpy
(
regs
,
&
thr
->
regs
,
sizeof
(
struct
reg
));
return
true
;
}
return
false
;
}
#endif // __APPLE__
// get regs for a given lwp
// get regs for a given lwp
bool
get_lwp_regs
(
struct
ps_prochandle
*
ph
,
lwpid_t
lwp_id
,
struct
reg
*
regs
)
{
bool
get_lwp_regs
(
struct
ps_prochandle
*
ph
,
lwpid_t
lwp_id
,
struct
reg
*
regs
)
{
return
ph
->
ops
->
get_lwp_regs
(
ph
,
lwp_id
,
regs
);
return
ph
->
ops
->
get_lwp_regs
(
ph
,
lwp_id
,
regs
);
...
@@ -341,35 +439,35 @@ bool get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id, struct reg* regs) {
...
@@ -341,35 +439,35 @@ bool get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id, struct reg* regs) {
// get number of shared objects
// get number of shared objects
int
get_num_libs
(
struct
ps_prochandle
*
ph
)
{
int
get_num_libs
(
struct
ps_prochandle
*
ph
)
{
return
ph
->
num_libs
;
return
ph
->
num_libs
;
}
}
// get name of n'th solib
// get name of n'th solib
const
char
*
get_lib_name
(
struct
ps_prochandle
*
ph
,
int
index
)
{
const
char
*
get_lib_name
(
struct
ps_prochandle
*
ph
,
int
index
)
{
int
count
=
0
;
int
count
=
0
;
lib_info
*
lib
=
ph
->
libs
;
lib_info
*
lib
=
ph
->
libs
;
while
(
lib
)
{
while
(
lib
)
{
if
(
count
==
index
)
{
if
(
count
==
index
)
{
return
lib
->
name
;
return
lib
->
name
;
}
}
count
++
;
count
++
;
lib
=
lib
->
next
;
lib
=
lib
->
next
;
}
}
return
NULL
;
return
NULL
;
}
}
// get base address of a lib
// get base address of a lib
uintptr_t
get_lib_base
(
struct
ps_prochandle
*
ph
,
int
index
)
{
uintptr_t
get_lib_base
(
struct
ps_prochandle
*
ph
,
int
index
)
{
int
count
=
0
;
int
count
=
0
;
lib_info
*
lib
=
ph
->
libs
;
lib_info
*
lib
=
ph
->
libs
;
while
(
lib
)
{
while
(
lib
)
{
if
(
count
==
index
)
{
if
(
count
==
index
)
{
return
lib
->
base
;
return
lib
->
base
;
}
}
count
++
;
count
++
;
lib
=
lib
->
next
;
lib
=
lib
->
next
;
}
}
return
(
uintptr_t
)
NULL
;
return
(
uintptr_t
)
NULL
;
}
}
bool
find_lib
(
struct
ps_prochandle
*
ph
,
const
char
*
lib_name
)
{
bool
find_lib
(
struct
ps_prochandle
*
ph
,
const
char
*
lib_name
)
{
...
@@ -425,6 +523,7 @@ ps_plog (const char *format, ...)
...
@@ -425,6 +523,7 @@ ps_plog (const char *format, ...)
va_end
(
alist
);
va_end
(
alist
);
}
}
#ifndef __APPLE__
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// Functions below this point are not yet implemented. They are here only
// Functions below this point are not yet implemented. They are here only
// to make the linker happy.
// to make the linker happy.
...
@@ -458,3 +557,4 @@ ps_err_e ps_pcontinue(struct ps_prochandle *ph) {
...
@@ -458,3 +557,4 @@ ps_err_e ps_pcontinue(struct ps_prochandle *ph) {
print_debug
(
"ps_pcontinue not implemented
\n
"
);
print_debug
(
"ps_pcontinue not implemented
\n
"
);
return
PS_OK
;
return
PS_OK
;
}
}
#endif // __APPLE__
agent/src/os/bsd/libproc_impl.h
浏览文件 @
9d011637
...
@@ -30,6 +30,60 @@
...
@@ -30,6 +30,60 @@
#include "libproc.h"
#include "libproc.h"
#include "symtab.h"
#include "symtab.h"
#ifdef __APPLE__
#include <inttypes.h> // for PRIx64, 32, ...
#include <pthread.h>
#include <mach-o/loader.h>
#include <mach-o/nlist.h>
#include <mach-o/fat.h>
#ifndef register_t
#define register_t uint64_t
#endif
/*** registers copied from bsd/amd64 */
typedef
struct
reg
{
register_t
r_r15
;
register_t
r_r14
;
register_t
r_r13
;
register_t
r_r12
;
register_t
r_r11
;
register_t
r_r10
;
register_t
r_r9
;
register_t
r_r8
;
register_t
r_rdi
;
register_t
r_rsi
;
register_t
r_rbp
;
register_t
r_rbx
;
register_t
r_rdx
;
register_t
r_rcx
;
register_t
r_rax
;
uint32_t
r_trapno
;
// not used
uint16_t
r_fs
;
uint16_t
r_gs
;
uint32_t
r_err
;
// not used
uint16_t
r_es
;
// not used
uint16_t
r_ds
;
// not used
register_t
r_rip
;
register_t
r_cs
;
register_t
r_rflags
;
register_t
r_rsp
;
register_t
r_ss
;
// not used
}
reg
;
// convenient defs
typedef
struct
mach_header_64
mach_header_64
;
typedef
struct
load_command
load_command
;
typedef
struct
segment_command_64
segment_command_64
;
typedef
struct
thread_command
thread_command
;
typedef
struct
dylib_command
dylib_command
;
typedef
struct
symtab_command
symtab_command
;
typedef
struct
nlist_64
nlist_64
;
#else
#include <thread_db.h>
#include "salibelf.h"
#endif // __APPLE__
// data structures in this file mimic those of Solaris 8.0 - libproc's Pcontrol.h
// data structures in this file mimic those of Solaris 8.0 - libproc's Pcontrol.h
#define BUF_SIZE (PATH_MAX + NAME_MAX + 1)
#define BUF_SIZE (PATH_MAX + NAME_MAX + 1)
...
@@ -44,12 +98,12 @@ typedef struct lib_info {
...
@@ -44,12 +98,12 @@ typedef struct lib_info {
}
lib_info
;
}
lib_info
;
// list of threads
// list of threads
typedef
struct
thread_info
{
typedef
struct
sa_
thread_info
{
lwpid_t
lwp_id
;
lwpid_t
lwp_id
;
// same as pthread_t
pthread_t
pthread_id
;
//
not used cores, always -1
pthread_t
pthread_id
;
//
struct
reg
regs
;
// not for process, core uses for caching regset
struct
reg
regs
;
// not for process, core uses for caching regset
struct
thread_info
*
next
;
struct
sa_thread_info
*
next
;
}
thread_info
;
}
sa_
thread_info
;
// list of virtual memory maps
// list of virtual memory maps
typedef
struct
map_info
{
typedef
struct
map_info
{
...
@@ -91,6 +145,7 @@ struct core_data {
...
@@ -91,6 +145,7 @@ struct core_data {
// part of the class sharing workaround
// part of the class sharing workaround
map_info
*
class_share_maps
;
// class share maps in a linked list
map_info
*
class_share_maps
;
// class share maps in a linked list
map_info
**
map_array
;
// sorted (by vaddr) array of map_info pointers
map_info
**
map_array
;
// sorted (by vaddr) array of map_info pointers
char
exec_path
[
4096
];
// file name java
};
};
struct
ps_prochandle
{
struct
ps_prochandle
{
...
@@ -100,12 +155,11 @@ struct ps_prochandle {
...
@@ -100,12 +155,11 @@ struct ps_prochandle {
lib_info
*
libs
;
// head of lib list
lib_info
*
libs
;
// head of lib list
lib_info
*
lib_tail
;
// tail of lib list - to append at the end
lib_info
*
lib_tail
;
// tail of lib list - to append at the end
int
num_threads
;
int
num_threads
;
thread_info
*
threads
;
// head of thread list
sa_thread_info
*
threads
;
// head of thread list
struct
core_data
*
core
;
// data only used for core dumps, NULL for process
struct
core_data
*
core
;
// data only used for core dumps, NULL for process
};
};
int
pathmap_open
(
const
char
*
name
);
int
pathmap_open
(
const
char
*
name
);
void
print_debug
(
const
char
*
format
,...);
void
print_debug
(
const
char
*
format
,...);
void
print_error
(
const
char
*
format
,...);
void
print_error
(
const
char
*
format
,...);
bool
is_debug
();
bool
is_debug
();
...
@@ -122,10 +176,45 @@ lib_info* add_lib_info(struct ps_prochandle* ph, const char* libname, uintptr_t
...
@@ -122,10 +176,45 @@ lib_info* add_lib_info(struct ps_prochandle* ph, const char* libname, uintptr_t
lib_info
*
add_lib_info_fd
(
struct
ps_prochandle
*
ph
,
const
char
*
libname
,
int
fd
,
lib_info
*
add_lib_info_fd
(
struct
ps_prochandle
*
ph
,
const
char
*
libname
,
int
fd
,
uintptr_t
base
);
uintptr_t
base
);
// adds a new thread to threads list, returns NULL on failure
sa_thread_info
*
add_thread_info
(
struct
ps_prochandle
*
ph
,
pthread_t
pthread_id
,
lwpid_t
lwp_id
);
thread_info
*
add_thread_info
(
struct
ps_prochandle
*
ph
,
pthread_t
pthread_id
,
lwpid_t
lwp_id
);
// a test for ELF signature without using libelf
// a test for ELF signature without using libelf
#ifdef __APPLE__
// a test for Mach-O signature
bool
is_macho_file
(
int
fd
);
// skip fat head to get image start offset of cpu_type_t
// return false if any error happens, else value in offset.
bool
get_arch_off
(
int
fd
,
cpu_type_t
cputype
,
off_t
*
offset
);
#else
bool
is_elf_file
(
int
fd
);
bool
is_elf_file
(
int
fd
);
#endif // __APPLE__
lwpid_t
get_lwp_id
(
struct
ps_prochandle
*
ph
,
int
index
);
bool
set_lwp_id
(
struct
ps_prochandle
*
ph
,
int
index
,
lwpid_t
lwpid
);
bool
get_nth_lwp_regs
(
struct
ps_prochandle
*
ph
,
int
index
,
struct
reg
*
regs
);
// ps_pglobal_lookup() looks up the symbol sym_name in the symbol table
// of the load object object_name in the target process identified by ph.
// It returns the symbol's value as an address in the target process in
// *sym_addr.
ps_err_e
ps_pglobal_lookup
(
struct
ps_prochandle
*
ph
,
const
char
*
object_name
,
const
char
*
sym_name
,
psaddr_t
*
sym_addr
);
// read "size" bytes info "buf" from address "addr"
ps_err_e
ps_pread
(
struct
ps_prochandle
*
ph
,
psaddr_t
addr
,
void
*
buf
,
size_t
size
);
// write "size" bytes of data to debuggee at address "addr"
ps_err_e
ps_pwrite
(
struct
ps_prochandle
*
ph
,
psaddr_t
addr
,
const
void
*
buf
,
size_t
size
);
// fill in ptrace_lwpinfo for lid
ps_err_e
ps_linfo
(
struct
ps_prochandle
*
ph
,
lwpid_t
lwp_id
,
void
*
linfo
);
// needed for when libthread_db is compiled with TD_DEBUG defined
void
ps_plog
(
const
char
*
format
,
...);
// untility, tells the position in file
off_t
ltell
(
int
fd
);
#endif //_LIBPROC_IMPL_H_
#endif //_LIBPROC_IMPL_H_
agent/src/os/bsd/ps_core.c
浏览文件 @
9d011637
此差异已折叠。
点击以展开。
agent/src/os/bsd/symtab.c
浏览文件 @
9d011637
/*
/*
* Copyright (c) 2003, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -28,32 +28,182 @@
...
@@ -28,32 +28,182 @@
#include <string.h>
#include <string.h>
#include <db.h>
#include <db.h>
#include <fcntl.h>
#include <fcntl.h>
#include "libproc_impl.h"
#include "symtab.h"
#include "symtab.h"
#ifndef __APPLE__
#include "salibelf.h"
#include "salibelf.h"
#endif // __APPLE__
// ----------------------------------------------------
// ----------------------------------------------------
// functions for symbol lookups
// functions for symbol lookups
// ----------------------------------------------------
// ----------------------------------------------------
struct
elf_section
{
typedef
struct
symtab_symbol
{
ELF_SHDR
*
c_shdr
;
char
*
name
;
// name like __ZThread_...
void
*
c_data
;
uintptr_t
offset
;
// to loaded address
};
uintptr_t
size
;
// size strlen
}
symtab_symbol
;
struct
elf_symbol
{
char
*
name
;
uintptr_t
offset
;
uintptr_t
size
;
};
typedef
struct
symtab
{
typedef
struct
symtab
{
char
*
strs
;
char
*
strs
;
// all symbols "__symbol1__'\0'__symbol2__...."
size_t
num_symbols
;
size_t
num_symbols
;
struct
elf_symbol
*
symbols
;
DB
*
hash_table
;
DB
*
hash_table
;
symtab_symbol
*
symbols
;
}
symtab_t
;
}
symtab_t
;
#ifdef __APPLE__
void
build_search_table
(
symtab_t
*
symtab
)
{
int
i
;
for
(
i
=
0
;
i
<
symtab
->
num_symbols
;
i
++
)
{
DBT
key
,
value
;
key
.
data
=
symtab
->
symbols
[
i
].
name
;
key
.
size
=
strlen
(
key
.
data
)
+
1
;
value
.
data
=
&
(
symtab
->
symbols
[
i
]);
value
.
size
=
sizeof
(
symtab_symbol
);
(
*
symtab
->
hash_table
->
put
)(
symtab
->
hash_table
,
&
key
,
&
value
,
0
);
// check result
if
(
is_debug
())
{
DBT
rkey
,
rvalue
;
char
*
tmp
=
(
char
*
)
malloc
(
strlen
(
symtab
->
symbols
[
i
].
name
)
+
1
);
strcpy
(
tmp
,
symtab
->
symbols
[
i
].
name
);
rkey
.
data
=
tmp
;
rkey
.
size
=
strlen
(
tmp
)
+
1
;
(
*
symtab
->
hash_table
->
get
)(
symtab
->
hash_table
,
&
rkey
,
&
rvalue
,
0
);
// we may get a copy back so compare contents
symtab_symbol
*
res
=
(
symtab_symbol
*
)
rvalue
.
data
;
if
(
strcmp
(
res
->
name
,
symtab
->
symbols
[
i
].
name
)
||
res
->
offset
!=
symtab
->
symbols
[
i
].
offset
||
res
->
size
!=
symtab
->
symbols
[
i
].
size
)
{
print_debug
(
"error to get hash_table value!
\n
"
);
}
free
(
tmp
);
}
}
}
// read symbol table from given fd.
struct
symtab
*
build_symtab
(
int
fd
)
{
symtab_t
*
symtab
=
NULL
;
int
i
;
mach_header_64
header
;
off_t
image_start
;
if
(
!
get_arch_off
(
fd
,
CPU_TYPE_X86_64
,
&
image_start
))
{
print_debug
(
"failed in get fat header
\n
"
);
return
NULL
;
}
lseek
(
fd
,
image_start
,
SEEK_SET
);
if
(
read
(
fd
,
(
void
*
)
&
header
,
sizeof
(
mach_header_64
))
!=
sizeof
(
mach_header_64
))
{
print_debug
(
"reading header failed!
\n
"
);
return
NULL
;
}
// header
if
(
header
.
magic
!=
MH_MAGIC_64
)
{
print_debug
(
"not a valid .dylib file
\n
"
);
return
NULL
;
}
load_command
lcmd
;
symtab_command
symtabcmd
;
nlist_64
lentry
;
bool
lcsymtab_exist
=
false
;
long
filepos
=
ltell
(
fd
);
for
(
i
=
0
;
i
<
header
.
ncmds
;
i
++
)
{
lseek
(
fd
,
filepos
,
SEEK_SET
);
if
(
read
(
fd
,
(
void
*
)
&
lcmd
,
sizeof
(
load_command
))
!=
sizeof
(
load_command
))
{
print_debug
(
"read load_command failed for file
\n
"
);
return
NULL
;
}
filepos
+=
lcmd
.
cmdsize
;
// next command position
if
(
lcmd
.
cmd
==
LC_SYMTAB
)
{
lseek
(
fd
,
-
sizeof
(
load_command
),
SEEK_CUR
);
lcsymtab_exist
=
true
;
break
;
}
}
if
(
!
lcsymtab_exist
)
{
print_debug
(
"No symtab command found!
\n
"
);
return
NULL
;
}
if
(
read
(
fd
,
(
void
*
)
&
symtabcmd
,
sizeof
(
symtab_command
))
!=
sizeof
(
symtab_command
))
{
print_debug
(
"read symtab_command failed for file"
);
return
NULL
;
}
symtab
=
(
symtab_t
*
)
malloc
(
sizeof
(
symtab_t
));
if
(
symtab
==
NULL
)
{
print_debug
(
"out of memory: allocating symtab
\n
"
);
return
NULL
;
}
// create hash table, we use berkeley db to
// manipulate the hash table.
symtab
->
hash_table
=
dbopen
(
NULL
,
O_CREAT
|
O_RDWR
,
0600
,
DB_HASH
,
NULL
);
if
(
symtab
->
hash_table
==
NULL
)
goto
quit
;
symtab
->
num_symbols
=
symtabcmd
.
nsyms
;
symtab
->
symbols
=
(
symtab_symbol
*
)
malloc
(
sizeof
(
symtab_symbol
)
*
symtab
->
num_symbols
);
symtab
->
strs
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
symtabcmd
.
strsize
);
if
(
symtab
->
symbols
==
NULL
||
symtab
->
strs
==
NULL
)
{
print_debug
(
"out of memory: allocating symtab.symbol or symtab.strs
\n
"
);
goto
quit
;
}
lseek
(
fd
,
image_start
+
symtabcmd
.
symoff
,
SEEK_SET
);
for
(
i
=
0
;
i
<
symtab
->
num_symbols
;
i
++
)
{
if
(
read
(
fd
,
(
void
*
)
&
lentry
,
sizeof
(
nlist_64
))
!=
sizeof
(
nlist_64
))
{
print_debug
(
"read nlist_64 failed at %i
\n
"
,
i
);
goto
quit
;
}
symtab
->
symbols
[
i
].
offset
=
lentry
.
n_value
;
symtab
->
symbols
[
i
].
size
=
lentry
.
n_un
.
n_strx
;
// index
}
// string table
lseek
(
fd
,
image_start
+
symtabcmd
.
stroff
,
SEEK_SET
);
int
size
=
read
(
fd
,
(
void
*
)(
symtab
->
strs
),
symtabcmd
.
strsize
*
sizeof
(
char
));
if
(
size
!=
symtabcmd
.
strsize
*
sizeof
(
char
))
{
print_debug
(
"reading string table failed
\n
"
);
goto
quit
;
}
for
(
i
=
0
;
i
<
symtab
->
num_symbols
;
i
++
)
{
symtab
->
symbols
[
i
].
name
=
symtab
->
strs
+
symtab
->
symbols
[
i
].
size
;
if
(
i
>
0
)
{
// fix size
symtab
->
symbols
[
i
-
1
].
size
=
symtab
->
symbols
[
i
].
size
-
symtab
->
symbols
[
i
-
1
].
size
;
print_debug
(
"%s size = %d
\n
"
,
symtab
->
symbols
[
i
-
1
].
name
,
symtab
->
symbols
[
i
-
1
].
size
);
}
if
(
i
==
symtab
->
num_symbols
-
1
)
{
// last index
symtab
->
symbols
[
i
].
size
=
symtabcmd
.
strsize
-
symtab
->
symbols
[
i
].
size
;
print_debug
(
"%s size = %d
\n
"
,
symtab
->
symbols
[
i
].
name
,
symtab
->
symbols
[
i
].
size
);
}
}
// build a hashtable for fast query
build_search_table
(
symtab
);
return
symtab
;
quit:
if
(
symtab
)
destroy_symtab
(
symtab
);
return
NULL
;
}
#else // __APPLE__
struct
elf_section
{
ELF_SHDR
*
c_shdr
;
void
*
c_data
;
};
// read symbol table from given fd.
// read symbol table from given fd.
struct
symtab
*
build_symtab
(
int
fd
)
{
struct
symtab
*
build_symtab
(
int
fd
)
{
ELF_EHDR
ehdr
;
ELF_EHDR
ehdr
;
...
@@ -176,7 +326,7 @@ struct symtab* build_symtab(int fd) {
...
@@ -176,7 +326,7 @@ struct symtab* build_symtab(int fd) {
key
.
data
=
sym_name
;
key
.
data
=
sym_name
;
key
.
size
=
strlen
(
sym_name
)
+
1
;
key
.
size
=
strlen
(
sym_name
)
+
1
;
value
.
data
=
&
(
symtab
->
symbols
[
j
]);
value
.
data
=
&
(
symtab
->
symbols
[
j
]);
value
.
size
=
sizeof
(
void
*
);
value
.
size
=
sizeof
(
symtab_symbol
);
(
*
symtab
->
hash_table
->
put
)(
symtab
->
hash_table
,
&
key
,
&
value
,
0
);
(
*
symtab
->
hash_table
->
put
)(
symtab
->
hash_table
,
&
key
,
&
value
,
0
);
}
}
}
}
...
@@ -201,30 +351,29 @@ quit:
...
@@ -201,30 +351,29 @@ quit:
return
symtab
;
return
symtab
;
}
}
void
destroy_symtab
(
struct
symtab
*
symtab
)
{
#endif // __APPLE__
void
destroy_symtab
(
symtab_t
*
symtab
)
{
if
(
!
symtab
)
return
;
if
(
!
symtab
)
return
;
if
(
symtab
->
strs
)
free
(
symtab
->
strs
);
free
(
symtab
->
strs
);
if
(
symtab
->
symbols
)
free
(
symtab
->
symbols
);
free
(
symtab
->
symbols
);
if
(
symtab
->
hash_table
)
{
(
*
symtab
->
hash_table
->
close
)(
symtab
->
hash_table
);
}
free
(
symtab
);
free
(
symtab
);
}
}
uintptr_t
search_symbol
(
struct
symtab
*
symtab
,
uintptr_t
base
,
uintptr_t
search_symbol
(
struct
symtab
*
symtab
,
uintptr_t
base
,
const
char
*
sym_name
,
int
*
sym_size
)
{
const
char
*
sym_name
,
int
*
sym_size
)
{
DBT
key
,
value
;
DBT
key
,
value
;
int
ret
;
int
ret
;
// library does not have symbol table
// library does not have symbol table
if
(
!
symtab
||
!
symtab
->
hash_table
)
if
(
!
symtab
||
!
symtab
->
hash_table
)
{
return
0
;
return
0
;
}
key
.
data
=
(
char
*
)(
uintptr_t
)
sym_name
;
key
.
data
=
(
char
*
)(
uintptr_t
)
sym_name
;
key
.
size
=
strlen
(
sym_name
)
+
1
;
key
.
size
=
strlen
(
sym_name
)
+
1
;
ret
=
(
*
symtab
->
hash_table
->
get
)(
symtab
->
hash_table
,
&
key
,
&
value
,
0
);
ret
=
(
*
symtab
->
hash_table
->
get
)(
symtab
->
hash_table
,
&
key
,
&
value
,
0
);
if
(
ret
==
0
)
{
if
(
ret
==
0
)
{
s
truct
elf
_symbol
*
sym
=
value
.
data
;
s
ymtab
_symbol
*
sym
=
value
.
data
;
uintptr_t
rslt
=
(
uintptr_t
)
((
char
*
)
base
+
sym
->
offset
);
uintptr_t
rslt
=
(
uintptr_t
)
((
char
*
)
base
+
sym
->
offset
);
if
(
sym_size
)
*
sym_size
=
sym
->
size
;
if
(
sym_size
)
*
sym_size
=
sym
->
size
;
return
rslt
;
return
rslt
;
...
@@ -238,7 +387,7 @@ const char* nearest_symbol(struct symtab* symtab, uintptr_t offset,
...
@@ -238,7 +387,7 @@ const char* nearest_symbol(struct symtab* symtab, uintptr_t offset,
int
n
=
0
;
int
n
=
0
;
if
(
!
symtab
)
return
NULL
;
if
(
!
symtab
)
return
NULL
;
for
(;
n
<
symtab
->
num_symbols
;
n
++
)
{
for
(;
n
<
symtab
->
num_symbols
;
n
++
)
{
s
truct
elf
_symbol
*
sym
=
&
(
symtab
->
symbols
[
n
]);
s
ymtab
_symbol
*
sym
=
&
(
symtab
->
symbols
[
n
]);
if
(
sym
->
name
!=
NULL
&&
if
(
sym
->
name
!=
NULL
&&
offset
>=
sym
->
offset
&&
offset
<
sym
->
offset
+
sym
->
size
)
{
offset
>=
sym
->
offset
&&
offset
<
sym
->
offset
+
sym
->
size
)
{
if
(
poffset
)
*
poffset
=
(
offset
-
sym
->
offset
);
if
(
poffset
)
*
poffset
=
(
offset
-
sym
->
offset
);
...
...
agent/src/os/bsd/symtab.h
浏览文件 @
9d011637
/*
/*
* Copyright (c) 2003, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -27,11 +27,11 @@
...
@@ -27,11 +27,11 @@
#include <stdint.h>
#include <stdint.h>
// interface to manage ELF symbol tables
// interface to manage ELF
or MachO
symbol tables
struct
symtab
;
struct
symtab
;
// build symbol table for a given ELF
file d
escriptor
// build symbol table for a given ELF
or MachO file
escriptor
struct
symtab
*
build_symtab
(
int
fd
);
struct
symtab
*
build_symtab
(
int
fd
);
// destroy the symbol table
// destroy the symbol table
...
...
agent/src/share/classes/sun/jvm/hotspot/BsdVtblAccess.java
浏览文件 @
9d011637
/*
/*
* Copyright (c) 2002, 20
0
3, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 20
1
3, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -34,11 +34,18 @@ public class BsdVtblAccess extends BasicVtblAccess {
...
@@ -34,11 +34,18 @@ public class BsdVtblAccess extends BasicVtblAccess {
public
BsdVtblAccess
(
SymbolLookup
symbolLookup
,
public
BsdVtblAccess
(
SymbolLookup
symbolLookup
,
String
[]
dllNames
)
{
String
[]
dllNames
)
{
super
(
symbolLookup
,
dllNames
);
super
(
symbolLookup
,
dllNames
);
boolean
oldVT
=
false
;
if
(
symbolLookup
.
lookup
(
"libjvm.so"
,
"__vt_10JavaThread"
)
!=
null
||
boolean
isDarwin
=
dllNames
[
0
].
lastIndexOf
(
".dylib"
)
!=
-
1
;
symbolLookup
.
lookup
(
"libjvm_g.so"
,
"__vt_10JavaThread"
)
!=
null
)
{
String
vtJavaThread
=
isDarwin
?
"_vt_10JavaThread"
:
"__vt_10JavaThread"
;
for
(
String
dllName
:
dllNames
)
{
if
(
symbolLookup
.
lookup
(
dllName
,
vtJavaThread
)
!=
null
)
{
oldVT
=
true
;
break
;
}
}
if
(
oldVT
)
{
// old C++ ABI
// old C++ ABI
vt
=
"__vt_"
;
vt
=
isDarwin
?
"_vt_"
:
"__vt_"
;
}
else
{
}
else
{
// new C++ ABI
// new C++ ABI
vt
=
"_ZTV"
;
vt
=
"_ZTV"
;
...
...
agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java
浏览文件 @
9d011637
...
@@ -1517,7 +1517,7 @@ public class CommandProcessor {
...
@@ -1517,7 +1517,7 @@ public class CommandProcessor {
ByteArrayOutputStream
bos
=
new
ByteArrayOutputStream
();
ByteArrayOutputStream
bos
=
new
ByteArrayOutputStream
();
thread
.
printThreadIDOn
(
new
PrintStream
(
bos
));
thread
.
printThreadIDOn
(
new
PrintStream
(
bos
));
if
(
all
||
bos
.
toString
().
equals
(
name
))
{
if
(
all
||
bos
.
toString
().
equals
(
name
))
{
out
.
println
(
bos
.
toString
()
+
" =
"
+
thread
.
getAddress
());
out
.
println
(
"Thread "
+
bos
.
toString
()
+
" Address:
"
+
thread
.
getAddress
());
HTMLGenerator
gen
=
new
HTMLGenerator
(
false
);
HTMLGenerator
gen
=
new
HTMLGenerator
(
false
);
try
{
try
{
out
.
println
(
gen
.
genHTMLForJavaStackTrace
(
thread
));
out
.
println
(
gen
.
genHTMLForJavaStackTrace
(
thread
));
...
@@ -1546,7 +1546,7 @@ public class CommandProcessor {
...
@@ -1546,7 +1546,7 @@ public class CommandProcessor {
ByteArrayOutputStream
bos
=
new
ByteArrayOutputStream
();
ByteArrayOutputStream
bos
=
new
ByteArrayOutputStream
();
thread
.
printThreadIDOn
(
new
PrintStream
(
bos
));
thread
.
printThreadIDOn
(
new
PrintStream
(
bos
));
if
(
all
||
bos
.
toString
().
equals
(
name
))
{
if
(
all
||
bos
.
toString
().
equals
(
name
))
{
out
.
println
(
bos
.
toString
()
+
" =
"
+
thread
.
getAddress
());
out
.
println
(
"Thread "
+
bos
.
toString
()
+
" Address
"
+
thread
.
getAddress
());
if
(!
all
)
return
;
if
(!
all
)
return
;
}
}
}
}
...
...
agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java
浏览文件 @
9d011637
/*
/*
* Copyright (c) 2000, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -311,6 +311,8 @@ public class HotSpotAgent {
...
@@ -311,6 +311,8 @@ public class HotSpotAgent {
setupDebuggerLinux
();
setupDebuggerLinux
();
}
else
if
(
os
.
equals
(
"bsd"
))
{
}
else
if
(
os
.
equals
(
"bsd"
))
{
setupDebuggerBsd
();
setupDebuggerBsd
();
}
else
if
(
os
.
equals
(
"darwin"
))
{
setupDebuggerDarwin
();
}
else
{
}
else
{
// Add support for more operating systems here
// Add support for more operating systems here
throw
new
DebuggerException
(
"Operating system "
+
os
+
" not yet supported"
);
throw
new
DebuggerException
(
"Operating system "
+
os
+
" not yet supported"
);
...
@@ -370,6 +372,10 @@ public class HotSpotAgent {
...
@@ -370,6 +372,10 @@ public class HotSpotAgent {
db
=
new
HotSpotTypeDataBase
(
machDesc
,
db
=
new
HotSpotTypeDataBase
(
machDesc
,
new
BsdVtblAccess
(
debugger
,
jvmLibNames
),
new
BsdVtblAccess
(
debugger
,
jvmLibNames
),
debugger
,
jvmLibNames
);
debugger
,
jvmLibNames
);
}
else
if
(
os
.
equals
(
"darwin"
))
{
db
=
new
HotSpotTypeDataBase
(
machDesc
,
new
BsdVtblAccess
(
debugger
,
jvmLibNames
),
debugger
,
jvmLibNames
);
}
else
{
}
else
{
throw
new
DebuggerException
(
"OS \""
+
os
+
"\" not yet supported (no VtblAccess yet)"
);
throw
new
DebuggerException
(
"OS \""
+
os
+
"\" not yet supported (no VtblAccess yet)"
);
}
}
...
@@ -459,6 +465,8 @@ public class HotSpotAgent {
...
@@ -459,6 +465,8 @@ public class HotSpotAgent {
setupJVMLibNamesLinux
();
setupJVMLibNamesLinux
();
}
else
if
(
os
.
equals
(
"bsd"
))
{
}
else
if
(
os
.
equals
(
"bsd"
))
{
setupJVMLibNamesBsd
();
setupJVMLibNamesBsd
();
}
else
if
(
os
.
equals
(
"darwin"
))
{
setupJVMLibNamesDarwin
();
}
else
{
}
else
{
throw
new
RuntimeException
(
"Unknown OS type"
);
throw
new
RuntimeException
(
"Unknown OS type"
);
}
}
...
@@ -567,6 +575,29 @@ public class HotSpotAgent {
...
@@ -567,6 +575,29 @@ public class HotSpotAgent {
jvmLibNames
=
new
String
[]
{
"libjvm.so"
,
"libjvm_g.so"
};
jvmLibNames
=
new
String
[]
{
"libjvm.so"
,
"libjvm_g.so"
};
}
}
//
// Darwin
//
private
void
setupDebuggerDarwin
()
{
setupJVMLibNamesDarwin
();
if
(
cpu
.
equals
(
"amd64"
)
||
cpu
.
equals
(
"x86_64"
))
{
machDesc
=
new
MachineDescriptionAMD64
();
}
else
{
throw
new
DebuggerException
(
"Darwin only supported on x86_64. Current arch: "
+
cpu
);
}
BsdDebuggerLocal
dbg
=
new
BsdDebuggerLocal
(
machDesc
,
!
isServer
);
debugger
=
dbg
;
attachDebugger
();
}
private
void
setupJVMLibNamesDarwin
()
{
jvmLibNames
=
new
String
[]
{
"libjvm.dylib"
,
"libjvm_g.dylib"
};
}
/** Convenience routine which should be called by per-platform
/** Convenience routine which should be called by per-platform
debugger setup. Should not be called when startupMode is
debugger setup. Should not be called when startupMode is
REMOTE_MODE. */
REMOTE_MODE. */
...
...
agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java
浏览文件 @
9d011637
/*
/*
* Copyright (c) 2002, 20
08
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 20
13
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -31,6 +31,9 @@ import sun.jvm.hotspot.debugger.*;
...
@@ -31,6 +31,9 @@ import sun.jvm.hotspot.debugger.*;
import
sun.jvm.hotspot.debugger.x86.*
;
import
sun.jvm.hotspot.debugger.x86.*
;
import
sun.jvm.hotspot.debugger.cdbg.*
;
import
sun.jvm.hotspot.debugger.cdbg.*
;
import
sun.jvm.hotspot.utilities.*
;
import
sun.jvm.hotspot.utilities.*
;
import
sun.jvm.hotspot.runtime.VM
;
import
sun.jvm.hotspot.runtime.Threads
;
import
sun.jvm.hotspot.runtime.JavaThread
;
import
java.lang.reflect.*
;
import
java.lang.reflect.*
;
/** <P> An implementation of the JVMDebugger interface. The basic debug
/** <P> An implementation of the JVMDebugger interface. The basic debug
...
@@ -51,10 +54,11 @@ import java.lang.reflect.*;
...
@@ -51,10 +54,11 @@ import java.lang.reflect.*;
public
class
BsdDebuggerLocal
extends
DebuggerBase
implements
BsdDebugger
{
public
class
BsdDebuggerLocal
extends
DebuggerBase
implements
BsdDebugger
{
private
boolean
useGCC32ABI
;
private
boolean
useGCC32ABI
;
private
boolean
attached
;
private
boolean
attached
;
private
long
p_ps_prochandle
;
// native debugger handle
private
long
p_ps_prochandle
;
// native debugger handle
private
long
symbolicator
;
// macosx symbolicator handle
private
long
symbolicator
;
// macosx symbolicator handle
private
long
task
;
// macosx task handle
private
long
task
;
// macosx task handle
private
boolean
isCore
;
private
boolean
isCore
;
private
boolean
isDarwin
;
// variant for bsd
// CDebugger support
// CDebugger support
private
BsdCDebugger
cdbg
;
private
BsdCDebugger
cdbg
;
...
@@ -208,6 +212,7 @@ public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger {
...
@@ -208,6 +212,7 @@ public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger {
}
}
}
}
isDarwin
=
getOS
().
equals
(
"darwin"
);
workerThread
=
new
BsdDebuggerLocalWorkerThread
(
this
);
workerThread
=
new
BsdDebuggerLocalWorkerThread
(
this
);
workerThread
.
start
();
workerThread
.
start
();
}
}
...
@@ -240,8 +245,11 @@ public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger {
...
@@ -240,8 +245,11 @@ public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger {
/* called from attach methods */
/* called from attach methods */
private
void
findABIVersion
()
throws
DebuggerException
{
private
void
findABIVersion
()
throws
DebuggerException
{
if
(
lookupByName0
(
"libjvm.so"
,
"__vt_10JavaThread"
)
!=
0
||
String
libjvmName
=
isDarwin
?
"libjvm.dylib"
:
"libjvm.so"
;
lookupByName0
(
"libjvm_g.so"
,
"__vt_10JavaThread"
)
!=
0
)
{
String
libjvm_gName
=
isDarwin
?
"libjvm_g.dylib"
:
"libjvm_g.so"
;
String
javaThreadVt
=
isDarwin
?
"_vt_10JavaThread"
:
"__vt_10JavaThread"
;
if
(
lookupByName0
(
libjvmName
,
javaThreadVt
)
!=
0
||
lookupByName0
(
libjvm_gName
,
javaThreadVt
)
!=
0
)
{
// old C++ ABI
// old C++ ABI
useGCC32ABI
=
false
;
useGCC32ABI
=
false
;
}
else
{
}
else
{
...
@@ -360,7 +368,8 @@ public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger {
...
@@ -360,7 +368,8 @@ public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger {
}
}
if
(
isCore
)
{
if
(
isCore
)
{
long
addr
=
lookupByName0
(
objectName
,
symbol
);
// MacOSX symbol with "_" as leading
long
addr
=
lookupByName0
(
objectName
,
isDarwin
?
"_"
+
symbol
:
symbol
);
return
(
addr
==
0
)?
null
:
new
BsdAddress
(
this
,
handleGCC32ABI
(
addr
,
symbol
));
return
(
addr
==
0
)?
null
:
new
BsdAddress
(
this
,
handleGCC32ABI
(
addr
,
symbol
));
}
else
{
}
else
{
class
LookupByNameTask
implements
WorkerThreadTask
{
class
LookupByNameTask
implements
WorkerThreadTask
{
...
@@ -403,12 +412,12 @@ public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger {
...
@@ -403,12 +412,12 @@ public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger {
public
ThreadProxy
getThreadForIdentifierAddress
(
Address
threadIdAddr
,
Address
uniqueThreadIdAddr
)
{
public
ThreadProxy
getThreadForIdentifierAddress
(
Address
threadIdAddr
,
Address
uniqueThreadIdAddr
)
{
return
new
BsdThread
(
this
,
threadIdAddr
,
uniqueThreadIdAddr
);
return
new
BsdThread
(
this
,
threadIdAddr
,
uniqueThreadIdAddr
);
}
}
@Override
@Override
public
ThreadProxy
getThreadForIdentifierAddress
(
Address
addr
)
{
public
ThreadProxy
getThreadForIdentifierAddress
(
Address
addr
)
{
throw
new
RuntimeException
(
"unimplemented"
);
throw
new
RuntimeException
(
"unimplemented"
);
}
}
/** From the ThreadAccess interface via Debugger and JVMDebugger */
/** From the ThreadAccess interface via Debugger and JVMDebugger */
public
ThreadProxy
getThreadForThreadId
(
long
id
)
{
public
ThreadProxy
getThreadForThreadId
(
long
id
)
{
return
new
BsdThread
(
this
,
id
);
return
new
BsdThread
(
this
,
id
);
...
@@ -601,6 +610,33 @@ public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger {
...
@@ -601,6 +610,33 @@ public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger {
throw
new
DebuggerException
(
"Unimplemented"
);
throw
new
DebuggerException
(
"Unimplemented"
);
}
}
/** this functions used for core file reading and called from native attach0,
it returns an array of long integers as
[thread_id, stack_start, stack_end, thread_id, stack_start, stack_end, ....] for
all java threads recorded in Threads. Also adds the ThreadProxy to threadList */
public
long
[]
getJavaThreadsInfo
()
{
requireAttach
();
Threads
threads
=
VM
.
getVM
().
getThreads
();
int
len
=
threads
.
getNumberOfThreads
();
long
[]
result
=
new
long
[
len
*
3
];
// triple
JavaThread
t
=
threads
.
first
();
long
beg
,
end
;
int
i
=
0
;
while
(
t
!=
null
)
{
end
=
t
.
getStackBaseValue
();
beg
=
end
-
t
.
getStackSize
();
BsdThread
bsdt
=
(
BsdThread
)
t
.
getThreadProxy
();
long
uid
=
bsdt
.
getUniqueThreadId
();
if
(
threadList
!=
null
)
threadList
.
add
(
bsdt
);
result
[
i
]
=
uid
;
result
[
i
+
1
]
=
beg
;
result
[
i
+
2
]
=
end
;
t
=
t
.
next
();
i
+=
3
;
}
return
result
;
}
static
{
static
{
System
.
loadLibrary
(
"saproc"
);
System
.
loadLibrary
(
"saproc"
);
init0
();
init0
();
...
...
agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java
浏览文件 @
9d011637
/*
/*
* Copyright (c) 2002, 20
0
3, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 20
1
3, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -44,7 +44,8 @@ class BsdThread implements ThreadProxy {
...
@@ -44,7 +44,8 @@ class BsdThread implements ThreadProxy {
BsdThread
(
BsdDebugger
debugger
,
long
id
)
{
BsdThread
(
BsdDebugger
debugger
,
long
id
)
{
this
.
debugger
=
debugger
;
this
.
debugger
=
debugger
;
this
.
thread_id
=
(
int
)
id
;
// use unique_thread_id to identify thread
this
.
unique_thread_id
=
id
;
}
}
public
boolean
equals
(
Object
obj
)
{
public
boolean
equals
(
Object
obj
)
{
...
@@ -52,7 +53,7 @@ class BsdThread implements ThreadProxy {
...
@@ -52,7 +53,7 @@ class BsdThread implements ThreadProxy {
return
false
;
return
false
;
}
}
return
(((
BsdThread
)
obj
).
thread_id
==
thread_id
);
return
(((
BsdThread
)
obj
).
unique_thread_id
==
unique_
thread_id
);
}
}
public
int
hashCode
()
{
public
int
hashCode
()
{
...
@@ -80,4 +81,9 @@ class BsdThread implements ThreadProxy {
...
@@ -80,4 +81,9 @@ class BsdThread implements ThreadProxy {
throws
IllegalThreadStateException
,
DebuggerException
{
throws
IllegalThreadStateException
,
DebuggerException
{
throw
new
DebuggerException
(
"Unimplemented"
);
throw
new
DebuggerException
(
"Unimplemented"
);
}
}
/** this is not interface function, used in core file to get unique thread id on Macosx*/
public
long
getUniqueThreadId
()
{
return
unique_thread_id
;
}
}
}
agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java
浏览文件 @
9d011637
/*
/*
* Copyright (c) 2000, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -320,6 +320,10 @@ public class JavaThread extends Thread {
...
@@ -320,6 +320,10 @@ public class JavaThread extends Thread {
return
stackBaseField
.
getValue
(
addr
);
return
stackBaseField
.
getValue
(
addr
);
}
}
public
long
getStackBaseValue
()
{
return
VM
.
getVM
().
getAddressValue
(
getStackBase
());
}
public
long
getStackSize
()
{
public
long
getStackSize
()
{
return
stackSizeField
.
getValue
(
addr
);
return
stackSizeField
.
getValue
(
addr
);
}
}
...
...
agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java
浏览文件 @
9d011637
/*
/*
* Copyright (c) 2000, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -42,6 +42,7 @@ import sun.jvm.hotspot.utilities.*;
...
@@ -42,6 +42,7 @@ import sun.jvm.hotspot.utilities.*;
public
class
Threads
{
public
class
Threads
{
private
static
JavaThreadFactory
threadFactory
;
private
static
JavaThreadFactory
threadFactory
;
private
static
AddressField
threadListField
;
private
static
AddressField
threadListField
;
private
static
CIntegerField
numOfThreadsField
;
private
static
VirtualConstructor
virtualConstructor
;
private
static
VirtualConstructor
virtualConstructor
;
private
static
JavaThreadPDAccess
access
;
private
static
JavaThreadPDAccess
access
;
...
@@ -57,6 +58,7 @@ public class Threads {
...
@@ -57,6 +58,7 @@ public class Threads {
Type
type
=
db
.
lookupType
(
"Threads"
);
Type
type
=
db
.
lookupType
(
"Threads"
);
threadListField
=
type
.
getAddressField
(
"_thread_list"
);
threadListField
=
type
.
getAddressField
(
"_thread_list"
);
numOfThreadsField
=
type
.
getCIntegerField
(
"_number_of_threads"
);
// Instantiate appropriate platform-specific JavaThreadFactory
// Instantiate appropriate platform-specific JavaThreadFactory
String
os
=
VM
.
getVM
().
getOS
();
String
os
=
VM
.
getVM
().
getOS
();
...
@@ -102,6 +104,10 @@ public class Threads {
...
@@ -102,6 +104,10 @@ public class Threads {
}
else
if
(
cpu
.
equals
(
"amd64"
)
||
cpu
.
equals
(
"x86_64"
))
{
}
else
if
(
cpu
.
equals
(
"amd64"
)
||
cpu
.
equals
(
"x86_64"
))
{
access
=
new
BsdAMD64JavaThreadPDAccess
();
access
=
new
BsdAMD64JavaThreadPDAccess
();
}
}
}
else
if
(
os
.
equals
(
"darwin"
))
{
if
(
cpu
.
equals
(
"amd64"
)
||
cpu
.
equals
(
"x86_64"
))
{
access
=
new
BsdAMD64JavaThreadPDAccess
();
}
}
}
if
(
access
==
null
)
{
if
(
access
==
null
)
{
...
@@ -144,6 +150,10 @@ public class Threads {
...
@@ -144,6 +150,10 @@ public class Threads {
return
createJavaThreadWrapper
(
threadAddr
);
return
createJavaThreadWrapper
(
threadAddr
);
}
}
public
int
getNumberOfThreads
()
{
return
(
int
)
numOfThreadsField
.
getValue
();
}
/** Routine for instantiating appropriately-typed wrapper for a
/** Routine for instantiating appropriately-typed wrapper for a
JavaThread. Currently needs to be public for OopUtilities to
JavaThread. Currently needs to be public for OopUtilities to
access it. */
access it. */
...
...
agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java
浏览文件 @
9d011637
/*
/*
* Copyright (c) 2003, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -32,6 +32,7 @@ import sun.jvm.hotspot.debugger.*;
...
@@ -32,6 +32,7 @@ import sun.jvm.hotspot.debugger.*;
import
sun.jvm.hotspot.debugger.cdbg.*
;
import
sun.jvm.hotspot.debugger.cdbg.*
;
import
sun.jvm.hotspot.oops.*
;
import
sun.jvm.hotspot.oops.*
;
import
sun.jvm.hotspot.runtime.*
;
import
sun.jvm.hotspot.runtime.*
;
import
sun.jvm.hotspot.utilities.PlatformInfo
;
public
class
PStack
extends
Tool
{
public
class
PStack
extends
Tool
{
// in non-verbose mode, Method*s are not printed in java frames
// in non-verbose mode, Method*s are not printed in java frames
...
@@ -54,6 +55,11 @@ public class PStack extends Tool {
...
@@ -54,6 +55,11 @@ public class PStack extends Tool {
}
}
public
void
run
(
PrintStream
out
,
Debugger
dbg
)
{
public
void
run
(
PrintStream
out
,
Debugger
dbg
)
{
if
(
PlatformInfo
.
getOS
().
equals
(
"darwin"
))
{
out
.
println
(
"Not available on Darwin"
);
return
;
}
CDebugger
cdbg
=
dbg
.
getCDebugger
();
CDebugger
cdbg
=
dbg
.
getCDebugger
();
if
(
cdbg
!=
null
)
{
if
(
cdbg
!=
null
)
{
ConcurrentLocksPrinter
concLocksPrinter
=
null
;
ConcurrentLocksPrinter
concLocksPrinter
=
null
;
...
...
agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java
浏览文件 @
9d011637
/*
/*
* Copyright (c) 2000, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -43,8 +43,8 @@ public class PlatformInfo {
...
@@ -43,8 +43,8 @@ public class PlatformInfo {
return
"bsd"
;
return
"bsd"
;
}
else
if
(
os
.
equals
(
"OpenBSD"
))
{
}
else
if
(
os
.
equals
(
"OpenBSD"
))
{
return
"bsd"
;
return
"bsd"
;
}
else
if
(
os
.
equal
s
(
"Darwin"
)
||
os
.
contains
(
"OS X"
))
{
}
else
if
(
os
.
contain
s
(
"Darwin"
)
||
os
.
contains
(
"OS X"
))
{
return
"
bsd
"
;
return
"
darwin
"
;
}
else
if
(
os
.
startsWith
(
"Windows"
))
{
}
else
if
(
os
.
startsWith
(
"Windows"
))
{
return
"win32"
;
return
"win32"
;
}
else
{
}
else
{
...
...
agent/src/share/native/sadis.c
浏览文件 @
9d011637
/*
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012,
2013,
Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -48,7 +48,10 @@
...
@@ -48,7 +48,10 @@
#include <string.h>
#include <string.h>
#include <dlfcn.h>
#include <dlfcn.h>
#ifndef __APPLE__
#include <link.h>
#include <link.h>
#endif
#endif
#endif
...
@@ -109,9 +112,7 @@ JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_asm_Disassembler_load_1library(JNIE
...
@@ -109,9 +112,7 @@ JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_asm_Disassembler_load_1library(JNIE
jstring
libname_s
)
{
jstring
libname_s
)
{
uintptr_t
func
=
0
;
uintptr_t
func
=
0
;
const
char
*
error_message
=
NULL
;
const
char
*
error_message
=
NULL
;
const
char
*
java_home
;
jboolean
isCopy
;
jboolean
isCopy
;
uintptr_t
*
handle
=
NULL
;
const
char
*
jrepath
=
(
*
env
)
->
GetStringUTFChars
(
env
,
jrepath_s
,
&
isCopy
);
// like $JAVA_HOME/jre/lib/sparc/
const
char
*
jrepath
=
(
*
env
)
->
GetStringUTFChars
(
env
,
jrepath_s
,
&
isCopy
);
// like $JAVA_HOME/jre/lib/sparc/
const
char
*
libname
=
(
*
env
)
->
GetStringUTFChars
(
env
,
libname_s
,
&
isCopy
);
const
char
*
libname
=
(
*
env
)
->
GetStringUTFChars
(
env
,
libname_s
,
&
isCopy
);
...
@@ -167,7 +168,8 @@ typedef void* (*decode_func)(uintptr_t start_va, uintptr_t end_va,
...
@@ -167,7 +168,8 @@ typedef void* (*decode_func)(uintptr_t start_va, uintptr_t end_va,
void
*
event_stream
,
void
*
event_stream
,
int
(
*
printf_callback
)(
void
*
,
const
char
*
,
...),
int
(
*
printf_callback
)(
void
*
,
const
char
*
,
...),
void
*
printf_stream
,
void
*
printf_stream
,
const
char
*
options
);
const
char
*
options
,
int
newline
);
/* container for call back state when decoding instructions */
/* container for call back state when decoding instructions */
typedef
struct
{
typedef
struct
{
...
@@ -281,7 +283,7 @@ JNIEXPORT void JNICALL Java_sun_jvm_hotspot_asm_Disassembler_decode(JNIEnv * env
...
@@ -281,7 +283,7 @@ JNIEXPORT void JNICALL Java_sun_jvm_hotspot_asm_Disassembler_decode(JNIEnv * env
end
-
start
,
end
-
start
,
&
event_to_env
,
(
void
*
)
&
denv
,
&
event_to_env
,
(
void
*
)
&
denv
,
&
printf_to_env
,
(
void
*
)
&
denv
,
&
printf_to_env
,
(
void
*
)
&
denv
,
options
);
options
,
0
/* newline */
);
/* cleanup */
/* cleanup */
(
*
env
)
->
ReleaseByteArrayElements
(
env
,
code
,
start
,
JNI_ABORT
);
(
*
env
)
->
ReleaseByteArrayElements
(
env
,
code
,
start
,
JNI_ABORT
);
...
...
make/bsd/makefiles/saproc.make
浏览文件 @
9d011637
#
#
# Copyright (c) 2005, 201
2
, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2005, 201
3
, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
#
# This code is free software; you can redistribute it and/or modify it
# This code is free software; you can redistribute it and/or modify it
...
@@ -24,7 +24,7 @@
...
@@ -24,7 +24,7 @@
# Rules to build serviceability agent library, used by vm.make
# Rules to build serviceability agent library, used by vm.make
# libsaproc.so: serviceability agent
# libsaproc.so
(dylib)
: serviceability agent
SAPROC
=
saproc
SAPROC
=
saproc
ifeq
($(OS_VENDOR), Darwin)
ifeq
($(OS_VENDOR), Darwin)
...
@@ -37,7 +37,7 @@ AGENT_DIR = $(GAMMADIR)/agent
...
@@ -37,7 +37,7 @@ AGENT_DIR = $(GAMMADIR)/agent
SASRCDIR
=
$(AGENT_DIR)
/src/os/
$(Platform_os_family)
SASRCDIR
=
$(AGENT_DIR)
/src/os/
$(Platform_os_family)
NON_STUB_SASRCFILES
=
$(SASRCDIR)
/salibelf.c
\
BSD_NON_STUB_SASRCFILES
=
$(SASRCDIR)
/salibelf.c
\
$(SASRCDIR)
/symtab.c
\
$(SASRCDIR)
/symtab.c
\
$(SASRCDIR)
/libproc_impl.c
\
$(SASRCDIR)
/libproc_impl.c
\
$(SASRCDIR)
/ps_proc.c
\
$(SASRCDIR)
/ps_proc.c
\
...
@@ -45,13 +45,19 @@ NON_STUB_SASRCFILES = $(SASRCDIR)/salibelf.c \
...
@@ -45,13 +45,19 @@ NON_STUB_SASRCFILES = $(SASRCDIR)/salibelf.c \
$(SASRCDIR)
/BsdDebuggerLocal.c
\
$(SASRCDIR)
/BsdDebuggerLocal.c
\
$(AGENT_DIR)
/src/share/native/sadis.c
$(AGENT_DIR)
/src/share/native/sadis.c
DARWIN_NON_STUB_SASRCFILES
=
$(SASRCDIR)
/symtab.c
\
$(SASRCDIR)
/libproc_impl.c
\
$(SASRCDIR)
/ps_core.c
\
$(SASRCDIR)
/MacosxDebuggerLocal.m
\
$(AGENT_DIR)
/src/share/native/sadis.c
ifeq
($(OS_VENDOR), FreeBSD)
ifeq
($(OS_VENDOR), FreeBSD)
SASRCFILES
=
$(NON_STUB_SASRCFILES)
SASRCFILES
=
$(
BSD_
NON_STUB_SASRCFILES)
SALIBS
=
-lutil
-lthread_db
SALIBS
=
-lutil
-lthread_db
SAARCH
=
$(ARCHFLAG)
SAARCH
=
$(ARCHFLAG)
else
else
ifeq
($(OS_VENDOR), Darwin)
ifeq
($(OS_VENDOR), Darwin)
SASRCFILES
=
$(
SASRCDIR)
/MacosxDebuggerLocal.m
SASRCFILES
=
$(
DARWIN_NON_STUB_SASRCFILES)
SALIBS
=
-g
-framework
Foundation
-F
/System/Library/Frameworks/JavaVM.framework/Frameworks
-framework
JavaNativeFoundation
-framework
Security
-framework
CoreFoundation
SALIBS
=
-g
-framework
Foundation
-F
/System/Library/Frameworks/JavaVM.framework/Frameworks
-framework
JavaNativeFoundation
-framework
Security
-framework
CoreFoundation
#objc compiler blows up on -march=i586, perhaps it should not be included in the macosx intel 32-bit C++ compiles?
#objc compiler blows up on -march=i586, perhaps it should not be included in the macosx intel 32-bit C++ compiles?
SAARCH
=
$(
subst
-march
=
i586,,
$(ARCHFLAG)
)
SAARCH
=
$(
subst
-march
=
i586,,
$(ARCHFLAG)
)
...
@@ -102,7 +108,7 @@ $(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE)
...
@@ -102,7 +108,7 @@ $(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE)
fi
fi
@
echo
Making SA debugger back-end...
@
echo
Making SA debugger back-end...
$(QUIETLY)
$(CC)
-D
$(BUILDARCH)
-D_GNU_SOURCE
\
$(QUIETLY)
$(CC)
-D
$(BUILDARCH)
-D_GNU_SOURCE
\
$(SYMFLAG)
$(SAARCH)
$(SHARED_FLAG)
$(PICFLAG)
\
$(SYMFLAG)
$(SAARCH)
$(SHARED_FLAG)
$(PICFLAG)
\
-I
$(SASRCDIR)
\
-I
$(SASRCDIR)
\
-I
$(GENERATED)
\
-I
$(GENERATED)
\
$(BOOT_JAVA_INCLUDES)
\
$(BOOT_JAVA_INCLUDES)
\
...
...
src/share/vm/classfile/classLoaderData.cpp
浏览文件 @
9d011637
...
@@ -105,6 +105,7 @@ void ClassLoaderData::oops_do(OopClosure* f, KlassClosure* klass_closure, bool m
...
@@ -105,6 +105,7 @@ void ClassLoaderData::oops_do(OopClosure* f, KlassClosure* klass_closure, bool m
void
ClassLoaderData
::
classes_do
(
KlassClosure
*
klass_closure
)
{
void
ClassLoaderData
::
classes_do
(
KlassClosure
*
klass_closure
)
{
for
(
Klass
*
k
=
_klasses
;
k
!=
NULL
;
k
=
k
->
next_link
())
{
for
(
Klass
*
k
=
_klasses
;
k
!=
NULL
;
k
=
k
->
next_link
())
{
klass_closure
->
do_klass
(
k
);
klass_closure
->
do_klass
(
k
);
assert
(
k
!=
k
->
next_link
(),
"no loops!"
);
}
}
}
}
...
@@ -113,6 +114,7 @@ void ClassLoaderData::classes_do(void f(InstanceKlass*)) {
...
@@ -113,6 +114,7 @@ void ClassLoaderData::classes_do(void f(InstanceKlass*)) {
if
(
k
->
oop_is_instance
())
{
if
(
k
->
oop_is_instance
())
{
f
(
InstanceKlass
::
cast
(
k
));
f
(
InstanceKlass
::
cast
(
k
));
}
}
assert
(
k
!=
k
->
next_link
(),
"no loops!"
);
}
}
}
}
...
@@ -258,6 +260,7 @@ void ClassLoaderData::remove_class(Klass* scratch_class) {
...
@@ -258,6 +260,7 @@ void ClassLoaderData::remove_class(Klass* scratch_class) {
return
;
return
;
}
}
prev
=
k
;
prev
=
k
;
assert
(
k
!=
k
->
next_link
(),
"no loops!"
);
}
}
ShouldNotReachHere
();
// should have found this class!!
ShouldNotReachHere
();
// should have found this class!!
}
}
...
@@ -439,6 +442,7 @@ void ClassLoaderData::dump(outputStream * const out) {
...
@@ -439,6 +442,7 @@ void ClassLoaderData::dump(outputStream * const out) {
while
(
k
!=
NULL
)
{
while
(
k
!=
NULL
)
{
out
->
print_cr
(
"klass "
PTR_FORMAT
", %s, CT: %d, MUT: %d"
,
k
,
k
->
name
()
->
as_C_string
(),
out
->
print_cr
(
"klass "
PTR_FORMAT
", %s, CT: %d, MUT: %d"
,
k
,
k
->
name
()
->
as_C_string
(),
k
->
has_modified_oops
(),
k
->
has_accumulated_modified_oops
());
k
->
has_modified_oops
(),
k
->
has_accumulated_modified_oops
());
assert
(
k
!=
k
->
next_link
(),
"no loops!"
);
k
=
k
->
next_link
();
k
=
k
->
next_link
();
}
}
}
}
...
@@ -465,6 +469,7 @@ void ClassLoaderData::verify() {
...
@@ -465,6 +469,7 @@ void ClassLoaderData::verify() {
for
(
Klass
*
k
=
_klasses
;
k
!=
NULL
;
k
=
k
->
next_link
())
{
for
(
Klass
*
k
=
_klasses
;
k
!=
NULL
;
k
=
k
->
next_link
())
{
guarantee
(
k
->
class_loader_data
()
==
this
,
"Must be the same"
);
guarantee
(
k
->
class_loader_data
()
==
this
,
"Must be the same"
);
k
->
verify
();
k
->
verify
();
assert
(
k
!=
k
->
next_link
(),
"no loops!"
);
}
}
}
}
...
...
src/share/vm/classfile/systemDictionary.cpp
浏览文件 @
9d011637
...
@@ -804,6 +804,32 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
...
@@ -804,6 +804,32 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
}
}
}
// load_instance_class loop
}
// load_instance_class loop
if
(
HAS_PENDING_EXCEPTION
)
{
// An exception, such as OOM could have happened at various places inside
// load_instance_class. We might have partially initialized a shared class
// and need to clean it up.
if
(
class_loader
.
is_null
())
{
// In some cases k may be null. Let's find the shared class again.
instanceKlassHandle
ik
(
THREAD
,
find_shared_class
(
name
));
if
(
ik
.
not_null
())
{
if
(
ik
->
class_loader_data
()
==
NULL
)
{
// We didn't go as far as Klass::restore_unshareable_info(),
// so nothing to clean up.
}
else
{
MutexLocker
mu
(
SystemDictionary_lock
,
THREAD
);
Klass
*
kk
=
find_class
(
name
,
ik
->
class_loader_data
());
if
(
kk
!=
NULL
)
{
// No clean up is needed if the shared class has been entered
// into system dictionary, as load_shared_class() won't be called
// again.
}
else
{
clean_up_shared_class
(
ik
,
class_loader
,
THREAD
);
}
}
}
}
}
if
(
load_instance_added
==
true
)
{
if
(
load_instance_added
==
true
)
{
// clean up placeholder entries for LOAD_INSTANCE success or error
// clean up placeholder entries for LOAD_INSTANCE success or error
// This brackets the SystemDictionary updates for both defining
// This brackets the SystemDictionary updates for both defining
...
@@ -1140,11 +1166,6 @@ instanceKlassHandle SystemDictionary::load_shared_class(
...
@@ -1140,11 +1166,6 @@ instanceKlassHandle SystemDictionary::load_shared_class(
return
load_shared_class
(
ik
,
class_loader
,
THREAD
);
return
load_shared_class
(
ik
,
class_loader
,
THREAD
);
}
}
// Note well! Changes to this method may affect oop access order
// in the shared archive. Please take care to not make changes that
// adversely affect cold start time by changing the oop access order
// that is specified in dump.cpp MarkAndMoveOrderedReadOnly and
// MarkAndMoveOrderedReadWrite closures.
instanceKlassHandle
SystemDictionary
::
load_shared_class
(
instanceKlassHandle
SystemDictionary
::
load_shared_class
(
instanceKlassHandle
ik
,
Handle
class_loader
,
TRAPS
)
{
instanceKlassHandle
ik
,
Handle
class_loader
,
TRAPS
)
{
assert
(
class_loader
.
is_null
(),
"non-null classloader for shared class?"
);
assert
(
class_loader
.
is_null
(),
"non-null classloader for shared class?"
);
...
@@ -1205,6 +1226,19 @@ instanceKlassHandle SystemDictionary::load_shared_class(
...
@@ -1205,6 +1226,19 @@ instanceKlassHandle SystemDictionary::load_shared_class(
return
ik
;
return
ik
;
}
}
void
SystemDictionary
::
clean_up_shared_class
(
instanceKlassHandle
ik
,
Handle
class_loader
,
TRAPS
)
{
// Updating methods must be done under a lock so multiple
// threads don't update these in parallel
// Shared classes are all currently loaded by the bootstrap
// classloader, so this will never cause a deadlock on
// a custom class loader lock.
{
Handle
lockObject
=
compute_loader_lock_object
(
class_loader
,
THREAD
);
check_loader_lock_contention
(
lockObject
,
THREAD
);
ObjectLocker
ol
(
lockObject
,
THREAD
,
true
);
ik
->
remove_unshareable_info
();
}
}
instanceKlassHandle
SystemDictionary
::
load_instance_class
(
Symbol
*
class_name
,
Handle
class_loader
,
TRAPS
)
{
instanceKlassHandle
SystemDictionary
::
load_instance_class
(
Symbol
*
class_name
,
Handle
class_loader
,
TRAPS
)
{
instanceKlassHandle
nh
=
instanceKlassHandle
();
// null Handle
instanceKlassHandle
nh
=
instanceKlassHandle
();
// null Handle
...
...
src/share/vm/classfile/systemDictionary.hpp
浏览文件 @
9d011637
...
@@ -621,6 +621,7 @@ private:
...
@@ -621,6 +621,7 @@ private:
Handle
class_loader
,
TRAPS
);
Handle
class_loader
,
TRAPS
);
static
instanceKlassHandle
load_shared_class
(
instanceKlassHandle
ik
,
static
instanceKlassHandle
load_shared_class
(
instanceKlassHandle
ik
,
Handle
class_loader
,
TRAPS
);
Handle
class_loader
,
TRAPS
);
static
void
clean_up_shared_class
(
instanceKlassHandle
ik
,
Handle
class_loader
,
TRAPS
);
static
instanceKlassHandle
load_instance_class
(
Symbol
*
class_name
,
Handle
class_loader
,
TRAPS
);
static
instanceKlassHandle
load_instance_class
(
Symbol
*
class_name
,
Handle
class_loader
,
TRAPS
);
static
Handle
compute_loader_lock_object
(
Handle
class_loader
,
TRAPS
);
static
Handle
compute_loader_lock_object
(
Handle
class_loader
,
TRAPS
);
static
void
check_loader_lock_contention
(
Handle
loader_lock
,
TRAPS
);
static
void
check_loader_lock_contention
(
Handle
loader_lock
,
TRAPS
);
...
...
src/share/vm/memory/metaspace.cpp
浏览文件 @
9d011637
...
@@ -334,6 +334,9 @@ class VirtualSpaceNode : public CHeapObj<mtClass> {
...
@@ -334,6 +334,9 @@ class VirtualSpaceNode : public CHeapObj<mtClass> {
// byte_size is the size of the associated virtualspace.
// byte_size is the size of the associated virtualspace.
VirtualSpaceNode
::
VirtualSpaceNode
(
size_t
byte_size
)
:
_top
(
NULL
),
_next
(
NULL
),
_rs
(
0
)
{
VirtualSpaceNode
::
VirtualSpaceNode
(
size_t
byte_size
)
:
_top
(
NULL
),
_next
(
NULL
),
_rs
(
0
)
{
// align up to vm allocation granularity
byte_size
=
align_size_up
(
byte_size
,
os
::
vm_allocation_granularity
());
// This allocates memory with mmap. For DumpSharedspaces, allocate the
// This allocates memory with mmap. For DumpSharedspaces, allocate the
// space at low memory so that other shared images don't conflict.
// space at low memory so that other shared images don't conflict.
// This is the same address as memory needed for UseCompressedOops but
// This is the same address as memory needed for UseCompressedOops but
...
...
src/share/vm/oops/klass.cpp
浏览文件 @
9d011637
...
@@ -486,6 +486,12 @@ void Klass::oops_do(OopClosure* cl) {
...
@@ -486,6 +486,12 @@ void Klass::oops_do(OopClosure* cl) {
}
}
void
Klass
::
remove_unshareable_info
()
{
void
Klass
::
remove_unshareable_info
()
{
if
(
!
DumpSharedSpaces
)
{
// Clean up after OOM during class loading
if
(
class_loader_data
()
!=
NULL
)
{
class_loader_data
()
->
remove_class
(
this
);
}
}
set_subklass
(
NULL
);
set_subklass
(
NULL
);
set_next_sibling
(
NULL
);
set_next_sibling
(
NULL
);
// Clear the java mirror
// Clear the java mirror
...
...
src/share/vm/oops/method.cpp
浏览文件 @
9d011637
...
@@ -798,7 +798,15 @@ void Method::unlink_method() {
...
@@ -798,7 +798,15 @@ void Method::unlink_method() {
backedge_counter
()
->
reset
();
backedge_counter
()
->
reset
();
_adapter
=
NULL
;
_adapter
=
NULL
;
_from_compiled_entry
=
NULL
;
_from_compiled_entry
=
NULL
;
assert
(
_method_data
==
NULL
,
"unexpected method data?"
);
// In case of DumpSharedSpaces, _method_data should always be NULL.
//
// During runtime (!DumpSharedSpaces), when we are cleaning a
// shared class that failed to load, this->link_method() may
// have already been called (before an exception happened), so
// this->_method_data may not be NULL.
assert
(
!
DumpSharedSpaces
||
_method_data
==
NULL
,
"unexpected method data?"
);
set_method_data
(
NULL
);
set_method_data
(
NULL
);
set_interpreter_throwout_count
(
0
);
set_interpreter_throwout_count
(
0
);
set_interpreter_invocation_count
(
0
);
set_interpreter_invocation_count
(
0
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录