Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
9f3c4fca
提交
9f3c4fca
authored
11 年前
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ABBA deadlock detection via code instrumentation
上级
cf602925
显示空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
228 行增加
和
0 行删除
+228
-0
AbbaDetector.java
h2/src/main/org/h2/util/AbbaDetector.java
+131
-0
AbbaDetect.java
h2/src/tools/org/h2/build/code/AbbaDetect.java
+97
-0
没有找到文件。
h2/src/main/org/h2/util/AbbaDetector.java
0 → 100644
浏览文件 @
9f3c4fca
/*
* Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
util
;
import
java.util.ArrayDeque
;
import
java.util.Deque
;
import
java.util.HashSet
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.WeakHashMap
;
/**
* Utility to detect AB-BA deadlocks.
*/
public
class
AbbaDetector
{
private
static
final
boolean
TRACE
=
false
;
private
static
final
ThreadLocal
<
Deque
<
Object
>>
STACK
=
new
ThreadLocal
<
Deque
<
Object
>>()
{
@Override
protected
Deque
<
Object
>
initialValue
()
{
return
new
ArrayDeque
<
Object
>();
}
};
private
static
final
Map
<
Object
,
Map
<
Object
,
Exception
>>
ORDER
=
new
WeakHashMap
<
Object
,
Map
<
Object
,
Exception
>>();
private
static
final
Set
<
String
>
KNOWN
=
new
HashSet
<
String
>();
public
static
Object
begin
(
Object
o
)
{
if
(
o
==
null
)
{
o
=
new
SecurityManager
()
{
Class
<?>
clazz
=
getClassContext
()[
2
];
}.
clazz
;
}
Deque
<
Object
>
stack
=
STACK
.
get
();
if
(!
stack
.
isEmpty
())
{
if
(
stack
.
contains
(
o
))
{
// already synchronized on this
return
o
;
}
while
(!
stack
.
isEmpty
())
{
Object
last
=
stack
.
peek
();
if
(
Thread
.
holdsLock
(
last
))
{
break
;
}
stack
.
pop
();
}
}
if
(
TRACE
)
{
String
thread
=
"[thread "
+
Thread
.
currentThread
().
getId
()
+
"]"
;
String
ident
=
new
String
(
new
char
[
stack
.
size
()
*
2
]).
replace
((
char
)
0
,
' '
);
System
.
out
.
println
(
thread
+
" "
+
ident
+
"sync "
+
getName
(
o
));
}
if
(
stack
.
size
()
>
0
)
{
markHigher
(
o
,
stack
);
}
stack
.
push
(
o
);
return
o
;
}
private
static
Object
getTest
(
Object
o
)
{
// return o.getClass();
return
o
;
}
private
static
String
getName
(
Object
o
)
{
return
o
.
getClass
().
getSimpleName
()
+
":"
+
System
.
identityHashCode
(
o
);
}
public
static
synchronized
void
markHigher
(
Object
o
,
Deque
<
Object
>
older
)
{
Object
test
=
getTest
(
o
);
Map
<
Object
,
Exception
>
map
=
ORDER
.
get
(
test
);
if
(
map
==
null
)
{
map
=
new
WeakHashMap
<
Object
,
Exception
>();
ORDER
.
put
(
test
,
map
);
}
Exception
oldException
=
null
;
for
(
Object
old
:
older
)
{
Object
oldTest
=
getTest
(
old
);
if
(
oldTest
==
test
)
{
continue
;
}
Map
<
Object
,
Exception
>
oldMap
=
ORDER
.
get
(
oldTest
);
if
(
oldMap
!=
null
)
{
Exception
e
=
oldMap
.
get
(
test
);
if
(
e
!=
null
)
{
String
deadlockType
=
test
.
getClass
()
+
" "
+
oldTest
.
getClass
();
if
(!
KNOWN
.
contains
(
deadlockType
))
{
String
message
=
getName
(
test
)
+
" synchronized after \n "
+
getName
(
oldTest
)
+
", but in the past before"
;
RuntimeException
ex
=
new
RuntimeException
(
message
);
ex
.
initCause
(
e
);
ex
.
printStackTrace
(
System
.
out
);
// throw ex;
KNOWN
.
add
(
deadlockType
);
}
}
}
if
(!
map
.
containsKey
(
oldTest
))
{
if
(
oldException
==
null
)
{
oldException
=
new
Exception
(
"Before"
);
}
map
.
put
(
oldTest
,
oldException
);
}
}
}
public
static
void
main
(
String
...
args
)
{
Integer
a
=
1
;
Float
b
=
2.0f
;
synchronized
(
a
)
{
synchronized
(
b
)
{
System
.
out
.
println
(
"a, then b"
);
}
}
synchronized
(
b
)
{
synchronized
(
a
)
{
System
.
out
.
println
(
"b, then a"
);
}
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/tools/org/h2/build/code/AbbaDetect.java
0 → 100644
浏览文件 @
9f3c4fca
/*
* Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
build
.
code
;
import
java.io.File
;
import
java.io.IOException
;
import
java.io.RandomAccessFile
;
/**
* Enable / disable AB-BA deadlock detector code.
*/
public
class
AbbaDetect
{
/**
* This method is called when executing this application from the command
* line.
*
* @param args the command line parameters
*/
public
static
void
main
(
String
...
args
)
throws
Exception
{
String
baseDir
=
"src/main"
;
process
(
new
File
(
baseDir
),
true
);
}
private
static
void
process
(
File
file
,
boolean
enable
)
throws
IOException
{
String
name
=
file
.
getName
();
if
(
file
.
isDirectory
())
{
if
(
name
.
equals
(
"CVS"
)
||
name
.
equals
(
".svn"
))
{
return
;
}
for
(
File
f
:
file
.
listFiles
())
{
process
(
f
,
enable
);
}
return
;
}
if
(!
name
.
endsWith
(
".java"
))
{
return
;
}
if
(
name
.
endsWith
(
"AbbaDetector.java"
))
{
return
;
}
RandomAccessFile
in
=
new
RandomAccessFile
(
file
,
"r"
);
byte
[]
data
=
new
byte
[(
int
)
file
.
length
()];
in
.
readFully
(
data
);
in
.
close
();
String
source
=
new
String
(
data
,
"UTF-8"
);
String
original
=
source
;
source
=
disable
(
source
);
if
(
enable
)
{
String
s2
=
enable
(
source
);
if
(!
source
.
equals
(
disable
(
s2
)))
{
throw
new
IOException
(
"Could not revert changes for file "
+
file
);
}
source
=
s2
;
}
if
(
source
.
equals
(
original
))
{
return
;
}
File
newFile
=
new
File
(
file
+
".new"
);
RandomAccessFile
out
=
new
RandomAccessFile
(
newFile
,
"rw"
);
out
.
write
(
source
.
getBytes
(
"UTF-8"
));
out
.
close
();
File
oldFile
=
new
File
(
file
+
".old"
);
file
.
renameTo
(
oldFile
);
newFile
.
renameTo
(
file
);
oldFile
.
delete
();
}
private
static
String
disable
(
String
source
)
{
source
=
source
.
replaceAll
(
"\\{org.h2.util.AbbaDetector.begin\\(.*\\);"
,
"{"
);
source
=
source
.
replaceAll
(
"org.h2.util.AbbaDetector.begin\\((.*\\(\\))\\)"
,
"$1"
);
source
=
source
.
replaceAll
(
"org.h2.util.AbbaDetector.begin\\((.*)\\)"
,
"$1"
);
source
=
source
.
replaceAll
(
"synchronized "
,
"synchronized "
);
return
source
;
}
private
static
String
enable
(
String
source
)
{
// the word synchronized within single line comments comments
source
=
source
.
replaceAll
(
"(// .* synchronized )([^ ])"
,
"$1 $2"
);
source
=
source
.
replaceAll
(
"synchronized \\((.*)\\(\\)\\)"
,
"synchronized \\(org.h2.util.AbbaDetector.begin\\($1\\(\\)\\)\\)"
);
source
=
source
.
replaceAll
(
"synchronized \\((.*)\\)"
,
"synchronized \\(org.h2.util.AbbaDetector.begin\\($1\\)\\)"
);
source
=
source
.
replaceAll
(
"static synchronized ([^ (].*)\\{"
,
"static synchronized $1{org.h2.util.AbbaDetector.begin\\(null\\);"
);
source
=
source
.
replaceAll
(
"synchronized ([^ (].*)\\{"
,
"synchronized $1{org.h2.util.AbbaDetector.begin\\(this\\);"
);
return
source
;
}
}
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论