Web-разработка, иностранные языки, Eclipse и разные разности

Zygo Profile

Санскрит - словоформы

Verbos Irregulares

6. Интеграция точек останова и отладчика

06.11.2015

После того, как мы уже реализовали возможность работы с точками останова из UI, нам нужно научить нашу модель отладчика (debug model) и отладчик их использовать.

Шаг 1. Добавление точек останова в модель.


Отладчики как правило временно приостанавливаются, когда загружается новый файл с исходными кодами. Затем модель может привязать точки останова к отладчику, после чего возобновить работу.

Модель отладчика (debug model) может оказывать воздействие и устанавливать точки останова до того, как выполнение продолжится. Помимо того нам необходимо улавливать изменения, касающиеся точек останова, чтобы добавлять новые точки останова в отладчик или удалять их, когда они отключаются или удаляются пользователем.

Давайте начнем с реализации слушателя событий (listener):



 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
package com.codeandme.textinterpreter.debugger.model;  
  
public class TextDebugTarget extends TextDebugElement implements IDebugTarget, IEventProcessor {  
  
 @Override  
 public boolean supportsBreakpoint(final IBreakpoint breakpoint) {  
  if (mFile.equals(breakpoint.getMarker().getResource())) {  
   // breakpoint on our source file  
   return true;  
  }  
  
  return false;  
 }  
  
 private boolean isEnabledBreakpoint(IBreakpoint breakpoint) {  
  try {  
   return breakpoint.isEnabled() && DebugPlugin.getDefault().getBreakpointManager().isEnabled();  
  } catch (CoreException e) {  
   // ignore invalid breakpoint  
  }  
  
  return false;  
 }  
  
 // ************************************************************  
 // IBreakpointListener  
 // ************************************************************  
  
 @Override  
 public void breakpointAdded(final IBreakpoint breakpoint) {  
  if ((supportsBreakpoint(breakpoint)) && (isEnabledBreakpoint(breakpoint)))  
   fireModelEvent(new BreakpointRequest(breakpoint, BreakpointRequest.ADDED));  
 }  
  
 @Override  
 public void breakpointRemoved(final IBreakpoint breakpoint, final IMarkerDelta delta) {  
  if (supportsBreakpoint(breakpoint))  
   fireModelEvent(new BreakpointRequest(breakpoint, BreakpointRequest.REMOVED));  
 }  
  
 @Override  
 public void breakpointChanged(final IBreakpoint breakpoint, final IMarkerDelta delta) {  
  breakpointRemoved(breakpoint, delta);  
  breakpointAdded(breakpoint);  
 }  

Поскольку точки останова могут быть предназначены незначащим файлам с исходными кодами или даже другим языками, нам надо удостовериться, что точка останова относится к нашем файлу с исходником. Если да, мы посылаем соответствующее событие отладчику.

Пока нет дальнейших проверок для удаления точек останова, мы добавляем только активные точки останова. Существует две различных возможности включения/отключения точек останова, которые нам надо проверить: может ли быть отключена сама точка останова и/или менеджер точек останова (BreakpointManager) может быть отключен глобально.

Сейчас нам необходимо позаботиться о том, что мы отслеживаем изменения, связанные в точках останова согласно тому, что указано в менеджере точек останова (BreakpointManager).



 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
package com.codeandme.textinterpreter.debugger.model;  
  
public class TextDebugTarget extends TextDebugElement implements IDebugTarget, IEventProcessor {  
  
 @Override  
 public void handleEvent(final IDebugEvent event) {  
  
  if (!isDisconnected()) {  
   System.out.println("Target.handleEvent() " + event);  
  
   if (event instanceof DebuggerStartedEvent) {  
    // create debug thread  
    TextThread thread = new TextThread(this);  
    mThreads.add(thread);  
    thread.fireCreationEvent();  
  
    // debugger got started and waits in suspended mode  
    setState(State.SUSPENDED);  
  
    // add breakpoint listener  
    DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener(this);  
  
    // attach deferred breakpoints to debugger  
    IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(getModelIdentifier());  
    for (IBreakpoint breakpoint : breakpoints)  
     breakpointAdded(breakpoint);  
  
    // resume execution after setting breakpoints  
    resume();  
  
   [...]  
  
   } else if (event instanceof TerminatedEvent) {  
    // debugger is terminated  
    setState(State.TERMINATED);  
  
    // unregister breakpoint listener  
    DebugPlugin.getDefault().getBreakpointManager().removeBreakpointListener(this);  
  
    // we do not need our dispatcher anymore  
    mDispatcher.terminate();  
  
    // inform eclipse of terminated state  
    fireTerminateEvent();  
   }  
  }  
 }  
}  

В событии DebuggerStartedEvent нам необходимо указать все значимые точки останова. После чего мы сможем продолжить, поскольку нам будет доступна полная поддержка точек останова.

Шаг 2. Добавление поддержки точек останова в отладчик.


Нашему отладчику нужно закешировать точки останова и проверить их в событии изменения строки. В нашем случае мы будем только отслеживать номера строк, на которых мы хотим задержаться:



 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
package com.codeandme.textinterpreter.debugger;  
  
public class TextDebugger implements IDebugger, IEventProcessor {  
  
 private final Set<integer> mBreakpoints = new HashSet<integer>();  
  
 @Override  
 public boolean isBreakpoint(final int lineNumber) {  
  if (mBreakpoints.contains(lineNumber))  
   return true;  
  
  return mIsStepping;  
 }  
  
 @Override  
 public void handleEvent(final IDebugEvent event) {  
  System.out.println("Debugger.handleEvent() " + event);  
  
  [...]  
  
  } else if (event instanceof BreakpointRequest) {  
   int line = ((BreakpointRequest) event).getBreakpoint().getMarker().getAttribute(IMarker.LINE_NUMBER, -1);  
   if (line != -1) {  
    if (((BreakpointRequest) event).getType() == BreakpointRequest.ADDED)  
     mBreakpoints.add(line);  
  
    else if (((BreakpointRequest) event).getType() == BreakpointRequest.REMOVED)  
     mBreakpoints.remove(line);  
   }  
  }  
 }  
}

Механизм установки и кеширования точек останова может быть немного более сложным в реальной жизни, поскольку вы имеете возможность поддерживать различные типы точек останова наподобие точек останова в функциях (function breakpoints) и контрольных точек (watchpoints).
Облако тегов
Меню
Архив
© Psytronica.ru. Блог существа SherZa. 2015-2017 Наверх