Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
f71d6ce9
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看板
提交
f71d6ce9
编写于
6月 17, 2019
作者:
A
andrew
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
76168a85
9cda9649
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
140 addition
and
30 deletion
+140
-30
.hgtags
.hgtags
+1
-0
agent/src/os/linux/libproc_impl.c
agent/src/os/linux/libproc_impl.c
+26
-1
agent/src/os/linux/libproc_impl.h
agent/src/os/linux/libproc_impl.h
+4
-1
agent/src/os/linux/ps_proc.c
agent/src/os/linux/ps_proc.c
+109
-28
未找到文件。
.hgtags
浏览文件 @
f71d6ce9
...
...
@@ -1267,3 +1267,4 @@ b2000ea410b0aa80d94a89105ba3dc8bdebd80b7 jdk8u212-b04
af43bab3c5d022f0e0b7890f732d8b365b4364cc jdk8u222-b03
d690709cc3398f8cfd6ffebb89a229105fb3e69a jdk8u222-b04
1ec20e8a3d8a7a29e9113b14567abec9f0240e9d jdk8u222-b05
17778f8991c83d794897f05210dce2d2a7b4eb2d jdk8u222-b06
agent/src/os/linux/libproc_impl.c
浏览文件 @
f71d6ce9
/*
* Copyright (c) 2003, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
9
, 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
...
...
@@ -256,6 +256,26 @@ thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwp
return
newthr
;
}
void
delete_thread_info
(
struct
ps_prochandle
*
ph
,
thread_info
*
thr_to_be_removed
)
{
thread_info
*
current_thr
=
ph
->
threads
;
if
(
thr_to_be_removed
==
ph
->
threads
)
{
ph
->
threads
=
ph
->
threads
->
next
;
}
else
{
thread_info
*
previous_thr
;
while
(
current_thr
&&
current_thr
!=
thr_to_be_removed
)
{
previous_thr
=
current_thr
;
current_thr
=
current_thr
->
next
;
}
if
(
current_thr
==
NULL
)
{
print_error
(
"Could not find the thread to be removed"
);
return
;
}
previous_thr
->
next
=
current_thr
->
next
;
}
ph
->
num_threads
--
;
free
(
current_thr
);
}
// struct used for client data from thread_db callback
struct
thread_db_client_data
{
...
...
@@ -278,6 +298,11 @@ static int thread_db_callback(const td_thrhandle_t *th_p, void *data) {
print_debug
(
"thread_db : pthread %d (lwp %d)
\n
"
,
ti
.
ti_tid
,
ti
.
ti_lid
);
if
(
ti
.
ti_state
==
TD_THR_UNKNOWN
||
ti
.
ti_state
==
TD_THR_ZOMBIE
)
{
print_debug
(
"Skipping pthread %d (lwp %d)
\n
"
,
ti
.
ti_tid
,
ti
.
ti_lid
);
return
TD_OK
;
}
if
(
ptr
->
callback
(
ptr
->
ph
,
ti
.
ti_tid
,
ti
.
ti_lid
)
!=
true
)
return
TD_ERR
;
...
...
agent/src/os/linux/libproc_impl.h
浏览文件 @
f71d6ce9
/*
* Copyright (c) 2003, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
9
, 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
...
...
@@ -113,6 +113,9 @@ typedef bool (*thread_info_callback)(struct ps_prochandle* ph, pthread_t pid, lw
// reads thread info using libthread_db and calls above callback for each thread
bool
read_thread_info
(
struct
ps_prochandle
*
ph
,
thread_info_callback
cb
);
// deletes a thread from the thread list
void
delete_thread_info
(
struct
ps_prochandle
*
ph
,
thread_info
*
thr
);
// adds a new shared object to lib list, returns NULL on failure
lib_info
*
add_lib_info
(
struct
ps_prochandle
*
ph
,
const
char
*
libname
,
uintptr_t
base
);
...
...
agent/src/os/linux/ps_proc.c
浏览文件 @
f71d6ce9
...
...
@@ -28,6 +28,7 @@
#include <signal.h>
#include <errno.h>
#include <elf.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
...
...
@@ -45,6 +46,12 @@
// This file has the libproc implementation specific to live process
// For core files, refer to ps_core.c
typedef
enum
{
ATTACH_SUCCESS
,
ATTACH_FAIL
,
ATTACH_THREAD_DEAD
}
attach_state_t
;
static
inline
uintptr_t
align
(
uintptr_t
ptr
,
size_t
size
)
{
return
(
ptr
&
~
(
size
-
1
));
}
...
...
@@ -167,9 +174,10 @@ static bool ptrace_continue(pid_t pid, int signal) {
// waits until the ATTACH has stopped the process
// by signal SIGSTOP
static
bool
ptrace_waitpid
(
pid_t
pid
)
{
static
attach_state_t
ptrace_waitpid
(
pid_t
pid
)
{
int
ret
;
int
status
;
errno
=
0
;
while
(
true
)
{
// Wait for debuggee to stop.
ret
=
waitpid
(
pid
,
&
status
,
0
);
...
...
@@ -184,15 +192,15 @@ static bool ptrace_waitpid(pid_t pid) {
// will go to sleep.
if
(
WSTOPSIG
(
status
)
==
SIGSTOP
)
{
// Debuggee stopped by SIGSTOP.
return
true
;
return
ATTACH_SUCCESS
;
}
if
(
!
ptrace_continue
(
pid
,
WSTOPSIG
(
status
)))
{
print_error
(
"Failed to correctly attach to VM. VM might HANG! [PTRACE_CONT failed, stopped by %d]
\n
"
,
WSTOPSIG
(
status
));
return
false
;
return
ATTACH_FAIL
;
}
}
else
{
print_debug
(
"waitpid(): Child process
exited/terminated (status = 0x%x)
\n
"
,
status
);
return
false
;
print_debug
(
"waitpid(): Child process
%d exited/terminated (status = 0x%x)
\n
"
,
pid
,
status
);
return
ATTACH_THREAD_DEAD
;
}
}
else
{
switch
(
errno
)
{
...
...
@@ -201,29 +209,89 @@ static bool ptrace_waitpid(pid_t pid) {
break
;
case
ECHILD
:
print_debug
(
"waitpid() failed. Child process pid (%d) does not exist
\n
"
,
pid
);
break
;
return
ATTACH_THREAD_DEAD
;
case
EINVAL
:
print_
debug
(
"waitpid() failed. Invalid options argument.
\n
"
);
break
;
print_
error
(
"waitpid() failed. Invalid options argument.
\n
"
);
return
ATTACH_FAIL
;
default:
print_
debug
(
"waitpid() failed. Unexpected error %d
\n
"
,
errno
);
break
;
print_
error
(
"waitpid() failed. Unexpected error %d
\n
"
,
errno
);
return
ATTACH_FAIL
;
}
return
false
;
}
// else
}
// while
}
// checks the state of the thread/process specified by "pid", by reading
// in the 'State:' value from the /proc/<pid>/status file. From the proc
// man page, "Current state of the process. One of "R (running)",
// "S (sleeping)", "D (disk sleep)", "T (stopped)", "T (tracing stop)",
// "Z (zombie)", or "X (dead)"." Assumes that the thread is dead if we
// don't find the status file or if the status is 'X' or 'Z'.
static
bool
process_doesnt_exist
(
pid_t
pid
)
{
char
fname
[
32
];
char
buf
[
30
];
FILE
*
fp
=
NULL
;
const
char
state_string
[]
=
"State:"
;
sprintf
(
fname
,
"/proc/%d/status"
,
pid
);
fp
=
fopen
(
fname
,
"r"
);
if
(
fp
==
NULL
)
{
print_debug
(
"can't open /proc/%d/status file
\n
"
,
pid
);
// Assume the thread does not exist anymore.
return
true
;
}
bool
found_state
=
false
;
size_t
state_len
=
strlen
(
state_string
);
while
(
fgets
(
buf
,
sizeof
(
buf
),
fp
)
!=
NULL
)
{
char
*
state
=
NULL
;
if
(
strncmp
(
buf
,
state_string
,
state_len
)
==
0
)
{
found_state
=
true
;
state
=
buf
+
state_len
;
// Skip the spaces
while
(
isspace
(
*
state
))
{
state
++
;
}
// A state value of 'X' indicates that the thread is dead. 'Z'
// indicates that the thread is a zombie.
if
(
*
state
==
'X'
||
*
state
==
'Z'
)
{
fclose
(
fp
);
return
true
;
}
break
;
}
}
// If the state value is not 'X' or 'Z', the thread exists.
if
(
!
found_state
)
{
// We haven't found the line beginning with 'State:'.
// Assuming the thread exists.
print_error
(
"Could not find the 'State:' string in the /proc/%d/status file
\n
"
,
pid
);
}
fclose
(
fp
);
return
false
;
}
// attach to a process/thread specified by "pid"
static
bool
ptrace_attach
(
pid_t
pid
,
char
*
err_buf
,
size_t
err_buf_len
)
{
static
attach_state_t
ptrace_attach
(
pid_t
pid
,
char
*
err_buf
,
size_t
err_buf_len
)
{
errno
=
0
;
if
(
ptrace
(
PTRACE_ATTACH
,
pid
,
NULL
,
NULL
)
<
0
)
{
if
(
errno
==
EPERM
||
errno
==
ESRCH
)
{
// Check if the process/thread is exiting or is a zombie
if
(
process_doesnt_exist
(
pid
))
{
print_debug
(
"Thread with pid %d does not exist
\n
"
,
pid
);
return
ATTACH_THREAD_DEAD
;
}
}
char
buf
[
200
];
char
*
msg
=
strerror_r
(
errno
,
buf
,
sizeof
(
buf
));
snprintf
(
err_buf
,
err_buf_len
,
"ptrace(PTRACE_ATTACH, ..) failed for %d: %s"
,
pid
,
msg
);
print_
debug
(
"%s
\n
"
,
err_buf
);
return
false
;
print_
error
(
"%s
\n
"
,
err_buf
);
return
ATTACH_FAIL
;
}
else
{
return
ptrace_waitpid
(
pid
);
attach_state_t
wait_ret
=
ptrace_waitpid
(
pid
);
if
(
wait_ret
==
ATTACH_THREAD_DEAD
)
{
print_debug
(
"Thread with pid %d does not exist
\n
"
,
pid
);
}
return
wait_ret
;
}
}
...
...
@@ -345,16 +413,20 @@ static ps_prochandle_ops process_ops = {
struct
ps_prochandle
*
Pgrab
(
pid_t
pid
,
char
*
err_buf
,
size_t
err_buf_len
)
{
struct
ps_prochandle
*
ph
=
NULL
;
thread_info
*
thr
=
NULL
;
attach_state_t
attach_status
=
ATTACH_SUCCESS
;
if
(
(
ph
=
(
struct
ps_prochandle
*
)
calloc
(
1
,
sizeof
(
struct
ps_prochandle
)))
==
NULL
)
{
snprintf
(
err_buf
,
err_buf_len
,
"can't allocate memory for ps_prochandle"
);
print_debug
(
"%s
\n
"
,
err_buf
);
return
NULL
;
snprintf
(
err_buf
,
err_buf_len
,
"can't allocate memory for ps_prochandle"
);
print_debug
(
"%s
\n
"
,
err_buf
);
return
NULL
;
}
if
(
ptrace_attach
(
pid
,
err_buf
,
err_buf_len
)
!=
true
)
{
free
(
ph
);
return
NULL
;
if
((
attach_status
=
ptrace_attach
(
pid
,
err_buf
,
err_buf_len
))
!=
ATTACH_SUCCESS
)
{
if
(
attach_status
==
ATTACH_THREAD_DEAD
)
{
print_error
(
"The process with pid %d does not exist.
\n
"
,
pid
);
}
free
(
ph
);
return
NULL
;
}
// initialize ps_prochandle
...
...
@@ -373,14 +445,23 @@ struct ps_prochandle* Pgrab(pid_t pid, char* err_buf, size_t err_buf_len) {
// attach to the threads
thr
=
ph
->
threads
;
while
(
thr
)
{
// don't attach to the main thread again
if
(
ph
->
pid
!=
thr
->
lwp_id
&&
ptrace_attach
(
thr
->
lwp_id
,
err_buf
,
err_buf_len
)
!=
true
)
{
// even if one attach fails, we get return NULL
Prelease
(
ph
);
return
NULL
;
}
thr
=
thr
->
next
;
thread_info
*
current_thr
=
thr
;
thr
=
thr
->
next
;
// don't attach to the main thread again
if
(
ph
->
pid
!=
current_thr
->
lwp_id
)
{
if
((
attach_status
=
ptrace_attach
(
current_thr
->
lwp_id
,
err_buf
,
err_buf_len
))
!=
ATTACH_SUCCESS
)
{
if
(
attach_status
==
ATTACH_THREAD_DEAD
)
{
// Remove this thread from the threads list
delete_thread_info
(
ph
,
current_thr
);
}
else
{
Prelease
(
ph
);
return
NULL
;
}
// ATTACH_THREAD_DEAD
}
// !ATTACH_SUCCESS
}
}
return
ph
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录