Skip to content

Commit 6e84d85

Browse files
committed
Merge pull request #106 from scouter-project/master
Merge for release
2 parents 9d2c180 + 57cb56e commit 6e84d85

File tree

22 files changed

+632
-607
lines changed

22 files changed

+632
-607
lines changed

scouter.agent.java/src/scouter/agent/asm/JDBCResultSetASM.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
* limitations under the License.
1616
*/
1717
package scouter.agent.asm;
18-
import java.util.HashSet;
1918
import scouter.agent.ClassDesc;
2019
import scouter.agent.Configure;
2120
import scouter.agent.Logger;
@@ -25,6 +24,8 @@
2524
import scouter.org.objectweb.asm.ClassVisitor;
2625
import scouter.org.objectweb.asm.MethodVisitor;
2726
import scouter.org.objectweb.asm.Opcodes;
27+
28+
import java.util.HashSet;
2829
public class JDBCResultSetASM implements IASM, Opcodes {
2930
public final HashSet<String> target = HookingSet.getHookingClassSet(Configure.getInstance().hook_jdbc_rs_classes);
3031
public JDBCResultSetASM() {
@@ -40,6 +41,7 @@ public JDBCResultSetASM() {
4041
target.add("oracle/jdbc/driver/InsensitiveScrollableResultSet");
4142
target.add("oracle/jdbc/driver/SensitiveScrollableResultSet");
4243
target.add("org/hsqldb/jdbc/JDBCResultSet");
44+
target.add("cubrid/jdbc/driver/CUBRIDResultSet");
4345
}
4446

4547
public ClassVisitor transform(ClassVisitor cv, String className, ClassDesc classDesc) {

scouter.agent.java/src/scouter/agent/asm/jdbc/RsCloseMV.java

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,29 @@
1-
/*
2-
* Copyright 2015 Scouter Project.
3-
*
4-
* Licensed under the Apache License, Version 2.0 (the "License");
5-
* you may not use this file except in compliance with the License.
6-
* You may obtain a copy of the License at
7-
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
15-
*/
16-
1+
/*
2+
* Copyright 2015 Scouter Project.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
1716
package scouter.agent.asm.jdbc;
1817

1918

20-
import scouter.agent.trace.TraceSQL;
21-
import scouter.org.objectweb.asm.MethodVisitor;
22-
import scouter.org.objectweb.asm.Opcodes;
19+
import scouter.agent.trace.TraceSQL;
20+
import scouter.org.objectweb.asm.MethodVisitor;
21+
import scouter.org.objectweb.asm.Opcodes;
2322

2423
public class RsCloseMV extends MethodVisitor implements Opcodes {
2524
private static final String TRACESQL = TraceSQL.class.getName().replace('.', '/');
2625
private static final String METHOD = "rsclose";
27-
private static final String SIGNATURE = "()V";
26+
private static final String SIGNATURE = "(Ljava/lang/Object;)V";
2827

2928
public RsCloseMV(MethodVisitor mv) {
3029
super(ASM4, mv);

scouter.agent.java/src/scouter/agent/trace/TraceSQL.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ private static void fetch(TraceContext c) {
312312
ServiceSummary.getInstance().process(tooManyFetch, hash, c.serviceHash, c.txid, 0, 0);
313313
}
314314
}
315-
public static void rsclose() {
315+
public static void rsclose(Object rs) {
316316
TraceContext c = TraceContextManager.getLocalContext();
317317
if (c != null) {
318318
if (c.rs_start != 0) {

scouter.agent.java/src/scouter/agent/util/AsyncRunner.java

Lines changed: 93 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* limitations under the License.
1616
*/
1717
package scouter.agent.util;
18-
import java.lang.instrument.ClassDefinition;
18+
1919
import scouter.agent.JavaAgent;
2020
import scouter.agent.Logger;
2121
import scouter.agent.netio.data.DataProxy;
@@ -24,83 +24,97 @@
2424
import scouter.util.RequestQueue;
2525
import scouter.util.SystemUtil;
2626
import scouter.util.ThreadUtil;
27+
28+
import java.lang.instrument.ClassDefinition;
29+
2730
public class AsyncRunner extends Thread {
28-
private static AsyncRunner instance = null;
29-
public final static synchronized AsyncRunner getInstance() {
30-
if (instance == null) {
31-
instance = new AsyncRunner();
32-
instance.setDaemon(true);
33-
instance.setName(ThreadUtil.getName(instance));
34-
instance.start();
35-
}
36-
return instance;
37-
}
38-
private RequestQueue<Object> queue = new RequestQueue<Object>(1024);
39-
private static class Hook {
40-
public Hook(ClassLoader loader, String classname, byte[] body) {
41-
super();
42-
this.loader = loader;
43-
this.classname = classname.replace('/', '.');
44-
this.body = body;
45-
}
46-
ClassLoader loader;
47-
String classname;
48-
byte[] body;
49-
}
50-
public void add(ClassLoader loader, String classname, byte[] body) {
51-
queue.put(new Hook(loader, classname, body));
52-
}
53-
public void add(LeakData data) {
54-
queue.put(data);
55-
}
56-
public void add(Runnable r) {
57-
queue.put(r);
58-
}
59-
public void run() {
60-
while (true) {
61-
Object m = queue.get(1000);
62-
try {
63-
if (m instanceof Hook) {
64-
hooking((Hook) m);
65-
} else if (m instanceof LeakData) {
66-
alert((LeakData) m);
67-
} else if (m instanceof Runnable) {
68-
process((Runnable) m);
69-
}
70-
} catch (Throwable t) {
71-
}
72-
}
73-
}
74-
private void process(Runnable m) {
75-
m.run();
76-
}
77-
private void alert(LeakData m) {
78-
ServiceSummary summary = ServiceSummary.getInstance();
79-
if (m.fullstack) {
80-
ErrorData d = summary.process(m.error, 0, m.service, m.txid, 0, 0);
81-
Logger.println("A156", m.error + " " + m.inner);
82-
if (d != null && d.fullstack == 0) {
83-
String fullstack = ThreadUtil.getStackTrace(m.error.getStackTrace(), 2);
84-
d.fullstack = DataProxy.sendError(fullstack);
85-
Logger.println("A157", fullstack);
86-
}
87-
} else {
88-
summary.process(m.error, 0, m.service, m.txid, 0, 0);
89-
Logger.println("A179", m.error + " " + m.inner);
90-
}
91-
}
92-
private void hooking(Hook m) {
93-
// AIX JDK1.5에서는 Dynamic Hooking을 사용하면 안됨
94-
if (SystemUtil.IS_AIX && SystemUtil.IS_JAVA_1_5) {
95-
return;
96-
}
97-
try {
98-
Class cls = Class.forName(m.classname, false, m.loader);
99-
ClassDefinition[] cd = new ClassDefinition[1];
100-
cd[0] = new ClassDefinition(cls, m.body);
101-
JavaAgent.getInstrumentation().redefineClasses(cd);
102-
} catch (Throwable t) {
103-
Logger.println("A149", "async hook fail:" + m.classname + " " + t);
104-
}
105-
}
31+
32+
private static AsyncRunner instance = null;
33+
private RequestQueue<Object> queue = new RequestQueue<Object>(1024);
34+
35+
public final static synchronized AsyncRunner getInstance() {
36+
if (instance == null) {
37+
instance = new AsyncRunner();
38+
instance.setDaemon(true);
39+
instance.setName(ThreadUtil.getName(instance));
40+
instance.start();
41+
}
42+
return instance;
43+
}
44+
45+
private static class Hook {
46+
public Hook(ClassLoader loader, String classname, byte[] body) {
47+
super();
48+
this.loader = loader;
49+
this.classname = classname.replace('/', '.');
50+
this.body = body;
51+
}
52+
ClassLoader loader;
53+
String classname;
54+
byte[] body;
55+
}
56+
57+
public void add(ClassLoader loader, String classname, byte[] body) {
58+
queue.put(new Hook(loader, classname, body));
59+
}
60+
61+
public void add(LeakInfo data) {
62+
queue.put(data);
63+
}
64+
65+
public void add(Runnable r) {
66+
queue.put(r);
67+
}
68+
69+
public void run() {
70+
while (true) {
71+
Object m = queue.get(1000);
72+
try {
73+
if (m instanceof Hook) {
74+
hooking((Hook) m);
75+
} else if (m instanceof LeakInfo) {
76+
alert((LeakInfo) m);
77+
} else if (m instanceof Runnable) {
78+
process((Runnable) m);
79+
}
80+
} catch (Throwable t) {
81+
}
82+
}
83+
}
84+
85+
private void process(Runnable r) {
86+
r.run();
87+
}
88+
89+
private void alert(LeakInfo leakInfo) {
90+
ServiceSummary summary = ServiceSummary.getInstance();
91+
92+
if (leakInfo.fullstack) {
93+
ErrorData d = summary.process(leakInfo.error, 0, leakInfo.serviceHash, leakInfo.txid, 0, 0);
94+
Logger.println("A156", leakInfo.error + " " + leakInfo.inner);
95+
if (d != null && d.fullstack == 0) {
96+
String fullstack = ThreadUtil.getStackTrace(leakInfo.error.getStackTrace(), 2);
97+
d.fullstack = DataProxy.sendError(fullstack);
98+
Logger.println("A157", fullstack);
99+
}
100+
} else {
101+
summary.process(leakInfo.error, 0, leakInfo.serviceHash, leakInfo.txid, 0, 0);
102+
Logger.println("A179", leakInfo.error + " " + leakInfo.inner);
103+
}
104+
}
105+
106+
private void hooking(Hook m) {
107+
// Never use dynamic hooking on AIX with JDK1.5
108+
if (SystemUtil.IS_AIX && SystemUtil.IS_JAVA_1_5) {
109+
return;
110+
}
111+
try {
112+
Class cls = Class.forName(m.classname, false, m.loader);
113+
ClassDefinition[] cd = new ClassDefinition[1];
114+
cd[0] = new ClassDefinition(cls, m.body);
115+
JavaAgent.getInstrumentation().redefineClasses(cd);
116+
} catch (Throwable t) {
117+
Logger.println("A149", "async hook fail:" + m.classname + " " + t);
118+
}
119+
}
106120
}

scouter.agent.java/src/scouter/agent/util/LeakData.java

Lines changed: 0 additions & 24 deletions
This file was deleted.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package scouter.agent.util;
2+
3+
public class LeakInfo {
4+
public Error error;
5+
public String inner;
6+
public int serviceHash;
7+
public long txid;
8+
public boolean fullstack;
9+
10+
public LeakInfo(Error error, String inner, int serviceHash, long txid, boolean fullstack) {
11+
super();
12+
this.error = error;
13+
this.inner = inner;
14+
this.serviceHash = serviceHash;
15+
this.txid = txid;
16+
this.fullstack = fullstack;
17+
}
18+
19+
@Override
20+
public String toString() {
21+
return "LeakInfo [error=" + error + ", inner=" + inner + ", serviceHash=" + serviceHash + ", txid=" + txid
22+
+ ", fullstack=" + fullstack + "]";
23+
}
24+
}

scouter.agent.java/src/scouter/agent/util/LeakTracer.java renamed to scouter.agent.java/src/scouter/agent/util/LeakableContainer.java

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,28 @@
1717
package scouter.agent.util;
1818

1919

20-
public class LeakTracer {
21-
private final static int MAX_BUCKET = 10;
22-
private int pos = 0;
23-
public LeakableObject[] bucket = new LeakableObject[MAX_BUCKET];
20+
public class LeakableContainer {
21+
private final static int MAX_BUCKET = 10;
22+
private int pos = 0;
2423

25-
protected void finalize() throws Throwable {
26-
for (int i = 0; i < MAX_BUCKET; i++) {
27-
if (bucket[i] != null) {
28-
AsyncRunner.getInstance().add(bucket[i].info);
29-
}
30-
}
31-
}
24+
private static LeakableContainer container = new LeakableContainer();
25+
public LeakableObject[] bucket = new LeakableObject[MAX_BUCKET];
3226

33-
private static LeakTracer trace = new LeakTracer();
27+
protected void finalize() throws Throwable {
28+
for (int i = 0; i < MAX_BUCKET; i++) {
29+
if (bucket[i] != null) {
30+
AsyncRunner.getInstance().add(bucket[i].info);
31+
}
32+
}
33+
}
3434

35-
public synchronized static void add(LeakableObject obj) {
36-
trace.bucket[trace.pos] = obj;
37-
obj.parent = trace;
38-
obj.pidx = trace.pos;
39-
trace.pos++;
40-
if (trace.pos >= MAX_BUCKET) {
41-
trace = new LeakTracer();
42-
}
43-
}
35+
public synchronized static void add(LeakableObject obj) {
36+
container.bucket[container.pos] = obj;
37+
obj.container = container;
38+
obj.pidx = container.pos;
39+
container.pos++;
40+
if (container.pos >= MAX_BUCKET) {
41+
container = new LeakableContainer();
42+
}
43+
}
4444
}

scouter.agent.java/src/scouter/agent/util/LeakableObject.java

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,16 @@
1818

1919
public class LeakableObject {
2020

21-
public LeakTracer parent;
22-
public int pidx;
21+
public LeakableContainer container;
22+
public int pidx;
23+
public LeakInfo info;
2324

24-
public LeakData info;
25-
26-
public LeakableObject(Error error, String inner, int service, long txid, boolean fullstack) {
27-
LeakTracer.add(this);
28-
this.info=new LeakData(error, inner, service, txid, fullstack);
29-
}
25+
public LeakableObject(Error error, String inner, int serviceHash, long txid, boolean fullstack) {
26+
LeakableContainer.add(this);
27+
this.info = new LeakInfo(error, inner, serviceHash, txid, fullstack);
28+
}
3029

31-
public void close() {
32-
parent.bucket[pidx] = null;
33-
}
30+
public void close() {
31+
container.bucket[pidx] = null;
32+
}
3433
}

0 commit comments

Comments
 (0)