-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathstackWnd.xcsm
369 lines (301 loc) · 11.9 KB
/
stackWnd.xcsm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
//xlang Source, Name:stackWnd.xcsm
//Date: Tue Sep 15:46:31 2018
class XStackInfor : QDockWidget{
public static const int XDBG_STATE_UPDATE = 0; //状态更新
public static const int XDBG_STATE_CREATE = 1; //线程创建
public static const int XDBG_STATE_EXIT = 2; //线程退出
public static const int XDBG_STATE_EXCEPTION = 4; //捕获异常
public static const int XDBG_STATE_REIGGEBP = 8; //触发断点
public static bool bOutputThreadStatus = true;
public QTreeWidget _listview;
private JsonObject root;
private Object rootLock = new Object();
public static XStackInfor stackWnd;
public static class BreakPosition{
public BreakPosition(String f, int l, int r, bool a){
file = f;
line = l;
row = r;
active = a;
}
public String file;
public int line;
public int row;
public bool active;
};
public static class ThreadInfo{
public long item;
public int serial;
public bool bInterrupt;
};
public onTreeViewItemEvent listlistener = new onTreeViewItemEvent(){
public void onItemClicked(QTreeWidget tree,long item, int column)override{
queryAuto(item, column);
}
};
public void queryAuto(long item, int column){
long parent_item = _listview.getParentItem(item);
if (parent_item != 0){
String tid = _listview.getItemText(parent_item, 1);
String fid = _listview.getItemText(item, 1);
if (tid.length() > 0 && fid.length() > 0){
long threadId = tid.parseLong();
int frameId = fid.parseInt();
ThreadManager.setCurrentThread(threadId, frameId);
String filepath = _listview.getItemText(item, 4);
String lr = _listview.getItemText(item, 2);
String []lrs = lr.split(',');
if (lrs.length == 2 && filepath.length() > 0){
XSourceEditor.openForFileInfo(XWorkspace.workspace, filepath, lrs[0].parseInt() + 1, lrs[1].parseInt(),nilptr, nilptr);
}
}
}else{
String tid = _listview.getItemText(item, 1);
if (tid.length() > 0){
long threadId = tid.parseLong();
if (threadId != 0){
ThreadManager.setCurrentThread(threadId, 0);
}
}
}
}
public void onAttach(){
_listview = (QTreeWidget)attachByName(new QTreeWidget(), "stacklist");
/*setOnLayoutEventListener(new onLayoutEventListener(){
void onResize(QObject obj, int w, int h, int oldw, int oldh)override {
if (_listview != nilptr){
_listview.resize(w, h - 20);
}
}
});*/
String [] columns = {"名称", "ID", "状态", "位置", "源文件"};
_listview.setColumns(columns);
_listview.setColumnWidth(0, 100);
_listview.setColumnWidth(1, 50);
_listview.setColumnWidth(2, 50);
_listview.setColumnWidth(3, 300);
_listview.setColumnWidth(4, 400);
_listview.setOnTreeViewItemEvent(listlistener);
stackWnd = this;
}
public static void updateThread(long tid, int action){
stackWnd.runOnUi(new Runnable(){
public void run()override{
stackWnd.onNotification(tid, action);
}
});
}
Map<long,long> threadlist = new Map<long,long>();
Map<long, BreakPosition> breakList = new Map<long, BreakPosition>();
bool isWord(byte c){
return c >= 'a' && c <= 'z' ||c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c== '_';
}
String convertPathToMethod(@NotNilptr String path){
byte [] bppath = path.getBytes();
for (int i = 0; i < bppath.length; i++){
if (bppath[i] == '/'){
bool pw = false;
if (i > 0 ){
pw = isWord(bppath[i - 1]);
}
bppath[i] = pw ? '.' : '`';
}else{
if (bppath[i] =='@'){
bppath[i] = ' ';
}
}
}
return new String(bppath).trim(true).replace("`", "");
}
void updateToItem(long item,@NotNilptr ThreadManager.ThreadObject to, bool bLocate){
_listview.setItemText(item, 0, to.name);
_listview.setItemText(item, 1, "" + to.id);
bool bCurrentThread = false;
if (to.id == ThreadManager.currentThreadId){
bCurrentThread = true;
}
_listview.setItemSelected(item, false);
_listview.setItemBackColor(item,0,bCurrentThread ? 0xffcccccc : 0x00000000);
_listview.setItemBackColor(item,1,bCurrentThread ? 0xffcccccc : 0x00000000);
_listview.setItemBackColor(item,2,bCurrentThread ? 0xffcccccc : 0x00000000);
if (to.bInterrupt){
_listview.setItemIcon(item, 0, "res/toolbar/break.png");
_listview.setItemText(item, 2, "中断");
}else
if (to.frames == nilptr){
_listview.setItemIcon(item, 0, "res/toolbar/run.png");
_listview.setItemText(item, 2, "运行");
}else{
_listview.setItemIcon(item, 0, "res/toolbar/wait.png");
_listview.setItemText(item, 2, "未知");
}
if (to.frames != nilptr){
for (int i = 0; i < to.frames.length; i++){
ThreadManager.StackFrame sf = to.frames[i];
if (sf == nilptr){
continue;
}
String ip = String.format("0x%p", sf.ip);
long fitem = _listview.insertItem(item, nilptr, "#frame:" + i);
_listview.setItemText(fitem, 1, "" + i);
if (sf.source == nilptr){
_listview.setItemText(fitem, 3, ip + "<无调试信息>");
}else{
_listview.setItemText(fitem, 2, "" + sf.line + "," + sf.column);
String path = sf.path;
if (path != nilptr && path.length() > 0){
path = convertPathToMethod(path);
}
if (path == nilptr){
path = "<找不到方法>";
}
if (sf.method != nilptr){
String shortname = sf.source.findFilenameAndExtension();
if (shortname.length() != 0){
_listview.setItemText(fitem, 3, sf.method + " - [" + path + "@" + shortname + " + " + String.format("0x%08X", sf.moffset) + "]");
}else{
_listview.setItemText(fitem, 3, sf.method);
}
}else{
_listview.setItemText(fitem, 3, ip);
}
_listview.setItemText(fitem, 4, sf.source);
if (i == 0){
if (sf.source != nilptr && sf.source.length() > 0){
BreakPosition bp = new BreakPosition(sf.source, sf.line, sf.column, bLocate);
Map.Iterator<long, BreakPosition> iter = breakList.find(to.id);
if (iter != nilptr){
BreakPosition old_bp = iter.getValue();
if (old_bp != nilptr){
if (old_bp.file.equals(sf.source) && old_bp.line == sf.line && old_bp.row == sf.column){
if (old_bp.active == false){
XSourceEditor.setBreak(bp, true, to.bSender);
}
continue;
//onlyActive = true;
}else{
XSourceEditor.removeBreak(old_bp);
iter.setValue(bp);
}
}
}
breakList.put(to.id ,bp);
XSourceEditor.setBreak(bp, false, to.bSender);
}
}
}
}
}
}
public void update(long tid, bool bLocate){
long item = 0;
Map.Iterator<long,long> iter = threadlist.find(tid);
if (iter == nilptr){
item = _listview.addItem(nilptr, "");
threadlist.put(tid, item);
}else{
item = iter.getValue();
_listview.removeAllchild(item);
}
ThreadManager.ThreadObject to = ThreadManager.getThread(tid);
if (to != nilptr){
updateToItem(item, to, bLocate);
}
}
public void createThread(long tid){
long item = _listview.addItem(nilptr, "");
threadlist.put(tid, item);
ThreadManager.ThreadObject to = ThreadManager.getThread(tid);
if (to != nilptr){
updateToItem(item, to, false);
}
}
public void exitThread(long tid){
Map.Iterator<long,long> iter = threadlist.find(tid);
if (iter != nilptr){
_listview.removeItem(iter.getValue());
threadlist.remove(iter);
breakList.remove(tid);
}
}
public void onException(long tid){
String msgInfo = nilptr;
long item = 0;
Map.Iterator<long,long> iter = threadlist.find(tid);
if (iter == nilptr){
item = _listview.addItem(nilptr, "");
threadlist.put(tid, item);
}else{
item = iter.getValue();
_listview.removeAllchild(item);
}
ThreadManager.ThreadObject to = ThreadManager.getThread(tid);
if (to != nilptr){
updateToItem(item, to, true);
if (to.bException){
msgInfo = "调试器捕获了一个未处理的异常[" + to.except_name + "]在地址:" + to.except_addr + "产生的中断,该异常将使程序停止运行.<br /><br />" +
"详细信息:<br />" +
"<strong style=\"color:#ff0000\">异常:" + to.except_name +"</strong><br />" +
"<strong style=\"color:#80b0f0\">消息:" + to.except_msg + "</strong><br />" +
"<strong style=\"color:#bde0ac\">地址:" + to.except_addr + "</strong><br />";
XWorkspace.Caution();
raise();
QMessageBox.Warning("异常中断", msgInfo, QMessageBox.Ok, QMessageBox.Ok);
}
}
}
public static void setThreadOuputStatus(bool b){
bOutputThreadStatus = b;
}
public void onNotification(long tid, int action){
synchronized(threadlist){
switch(action){
case XDBG_STATE_REIGGEBP:
case XDBG_STATE_UPDATE:
update(tid, true);
break;
case XDBG_STATE_CREATE:
createThread(tid);
if (bOutputThreadStatus){
XWndOutput.Output("线程:" + tid + " 已创建/启动.\n", 1);
}
break;
case XDBG_STATE_EXIT:
exitThread(tid);
if (bOutputThreadStatus){
XWndOutput.Output("线程:" + tid + " 已退出/休眠.\n", 1);
}
break;
case XDBG_STATE_EXCEPTION:
onException(tid);
break;
}
}
}
public static void clearBreak(long tid){
stackWnd.removeBreak(tid);
}
void removeBreak(long tid){
Map.Iterator<long, BreakPosition> iter = breakList.find(tid);
if (iter != nilptr){
BreakPosition bp = iter.getValue();
if (bp != nilptr){
XSourceEditor.removeBreak(bp);
}
breakList.remove(iter);
}
}
/*static void resetBreakPoint(){
XSourceEditor.clearBreakInfo(stackWnd.breakList);
stackWnd.breakList.clear();
stackWnd.threadlist.clear();
}*/
public static void reset(){
synchronized(stackWnd.threadlist){
stackWnd.threadlist.clear();
stackWnd._listview.clear();
XSourceEditor.clearBreakInfo(stackWnd.breakList);
stackWnd.breakList.clear();
}
}
};