The Fanuc SDK lets you add, remove, and manage breakpoints on TP and Karel programs. You can also step through code line by line, making it a powerful tool for remote debugging and prototyping a custom TP editor.

## Breakpoints

**C# : TelnetDebuggingBreakpoints**
```csharp
using UnderAutomation.Fanuc;
using UnderAutomation.Fanuc.Telnet;

public class TelnetDebuggingBreakpoints
{
    static void Main()
    {
        FanucRobot robot = new FanucRobot();
        var parameters = new ConnectionParameters("192.168.0.1");
        parameters.Telnet.Enable = true;
        parameters.Telnet.TelnetKclPassword = "TELNET_PASS";
        robot.Connect(parameters);

        /**/
        // Add a breakpoint at line 10
        robot.Telnet.AddBreakpoint("MyProgram", 10);

        // List breakpoints
        BreakpointsResult result = robot.Telnet.GetBreakpoints("MyProgram");
        foreach (Breakpoint bp in result.Breakpoints)
        {
            Console.WriteLine($"Breakpoint at line {bp.Line}");
        }

        // Remove a single breakpoint
        robot.Telnet.RemoveBreakpoint("MyProgram", 10);

        // Remove all breakpoints of a program
        robot.Telnet.RemoveAllBreakpoints("MyProgram");
        /**/
    }
}
```

**Python : TelnetDebuggingBreakpoints**
```python
from underautomation.fanuc.fanuc_robot import FanucRobot
from underautomation.fanuc.connection_parameters import ConnectionParameters

robot = FanucRobot()
parameters = ConnectionParameters("192.168.0.1")
parameters.telnet.enable = True
parameters.telnet.telnet_kcl_password = "TELNET_PASS"
robot.connect(parameters)

##
# Add a breakpoint at line 10
robot.telnet.add_breakpoint("MyProgram", 10)

# List breakpoints
result = robot.telnet.get_breakpoints("MyProgram")
for bp in result.breakpoints:
    print(f"Breakpoint at line {bp.line}")

# Remove a single breakpoint
robot.telnet.remove_breakpoint("MyProgram", 10)

# Remove all breakpoints of a program
robot.telnet.remove_all_breakpoints("MyProgram")
##
```

## Step-by-step execution and task info

When step mode is enabled, the program pauses after each line execution, allowing you to inspect state between instructions.

**C# : TelnetDebuggingStep**
```csharp
using UnderAutomation.Fanuc;
using UnderAutomation.Fanuc.Telnet;

public class TelnetDebuggingStep
{
    static void Main()
    {
        FanucRobot robot = new FanucRobot();
        var parameters = new ConnectionParameters("192.168.0.1");
        parameters.Telnet.Enable = true;
        parameters.Telnet.TelnetKclPassword = "TELNET_PASS";
        robot.Connect(parameters);

        /**/
        // Enable step mode for a task
        robot.Telnet.StepOn("MyProgram");

        // Disable step mode
        robot.Telnet.StepOff();

        // Get task information (current line, status, etc.)
        TaskInformationResult info = robot.Telnet.GetTaskInformation("MyProgram");
        /**/
    }
}
```

**Python : TelnetDebuggingStep**
```python
from underautomation.fanuc.fanuc_robot import FanucRobot
from underautomation.fanuc.connection_parameters import ConnectionParameters

robot = FanucRobot()
parameters = ConnectionParameters("192.168.0.1")
parameters.telnet.enable = True
parameters.telnet.telnet_kcl_password = "TELNET_PASS"
robot.connect(parameters)

##
# Enable step mode for a task
robot.telnet.step_on("MyProgram")

# Disable step mode
robot.telnet.step_off()

# Get task information (current line, status, etc.)
info = robot.telnet.get_task_information("MyProgram")
##
```

## Complete example

**C# : TelnetDebugging**
```csharp
using UnderAutomation.Fanuc;
using UnderAutomation.Fanuc.Telnet;

public class TelnetDebugging
{
  static void Main()
  {
    FanucRobot robot = new FanucRobot();
    ConnectionParameters parameters = new ConnectionParameters("192.168.0.1");
    parameters.Telnet.Enable = true;
    parameters.Telnet.TelnetKclPassword = "TELNET_PASS";
    robot.Connect(parameters);

    /**/
    // Add a breakpoint at line 10 of MyProgram
    robot.Telnet.AddBreakpoint("MyProgram", 10);

    // List all breakpoints
    BreakpointsResult result = robot.Telnet.GetBreakpoints("MyProgram");
    foreach (Breakpoint bp in result.Breakpoints)
    {
      Console.WriteLine($"Breakpoint at line {bp.Line}");
    }

    // Remove a single breakpoint
    robot.Telnet.RemoveBreakpoint("MyProgram", 10);

    // Remove all breakpoints
    robot.Telnet.RemoveAllBreakpoints("MyProgram");

    // Enable step-by-step execution
    robot.Telnet.StepOn("MyProgram");

    // Disable step mode
    robot.Telnet.StepOff();
    /**/
  }
}
```

**Python : TelnetDebugging**
```python
from underautomation.fanuc.fanuc_robot import FanucRobot
from underautomation.fanuc.connection_parameters import ConnectionParameters

robot = FanucRobot()
parameters = ConnectionParameters("192.168.0.1")
parameters.telnet.enable = True
parameters.telnet.telnet_kcl_password = "TELNET_PASS"
robot.connect(parameters)

##
# Add a breakpoint at line 10 of MyProgram
robot.telnet.add_breakpoint("MyProgram", 10)

# List all breakpoints
result = robot.telnet.get_breakpoints("MyProgram")
for bp in result.breakpoints:
    print(f"Breakpoint at line {bp.line}")

# Remove a single breakpoint
robot.telnet.remove_breakpoint("MyProgram", 10)

# Remove all breakpoints
robot.telnet.remove_all_breakpoints("MyProgram")

# Enable step-by-step execution
robot.telnet.step_on("MyProgram")

# Disable step mode
robot.telnet.step_off()
##
```

## See also

- [TP editor with breakpoints](/fanuc/documentation/tp-editor-with-breakpoints) : Build a custom TP editor with syntax highlighting and breakpoints

## API reference

**Members of Common.Kcl.BreakpointsResult**
```csharp
public class BreakpointsResult : Result {
    public BreakpointsResult()

    // Gets the breakpoints set on the task.
    public Breakpoint[] Breakpoints { get; }

    // Indicates that responses have been completed and received
    protected override void EndReceive()

    // During implementation, return true if it is assumed that the frame has finished being received.
    protected override bool FromResult(string data)

    // Controls whether the result should be finalized when an empty answer is received (i.e. a frame consisting only of VT100 escape sequences and whitespace).
    // Override and return false until meaningful data has been accumulated, to prevent premature finalization caused by intermediate display-update frames.
    // Default is true (backward compatible: finalize immediately on empty answer).
    protected override bool ShouldCompleteOnEmptyAnswer()
}
```

**Members of Common.Kcl.Breakpoint**
```csharp
public class Breakpoint {
    public Breakpoint()

    public override bool Equals(object obj)

    public override int GetHashCode()

    // Gets the line number where the breakpoint is set.
    public int Line { get; }

    public override string ToString()
}
```

**Members of Common.Kcl.AddBreakpointResult**
```csharp
public class AddBreakpointResult : Result {
    public AddBreakpointResult()

    // During implementation, return true if it is assumed that the frame has finished being received.
    protected override bool FromResult(string data)
}
```

**Members of Common.Kcl.RemoveBreakpointResult**
```csharp
public class RemoveBreakpointResult : Result {
    public RemoveBreakpointResult()

    // During implementation, return true if it is assumed that the frame has finished being received.
    protected override bool FromResult(string data)
}
```

**Members of Common.Kcl.StepOnResult**
```csharp
public class StepOnResult : Result {
    public StepOnResult()

    // During implementation, return true if it is assumed that the frame has finished being received.
    protected override bool FromResult(string data)
}
```

**Members of Common.Kcl.TaskInformationResult**
```csharp
public class TaskInformationResult : Result {
    public TaskInformationResult()

    // Gets the current line number.
    public int CurrentLine { get; }

    // Parses the result data and populates the properties of the class.
    protected override bool FromResult(string data)

    // Gets the hold conditions.
    public string HoldConditions { get; }

    // Gets a value indicating whether the task is invisible.
    public bool InvisibleTask { get; }

    // Gets the type of the program.
    public ProgramType ProgramType { get; }

    // Gets the name of the routine.
    public string RoutineName { get; }

    // Gets a value indicating whether the task is a system task.
    public bool SystemTask { get; }

    // Gets the name of the task.
    public string TaskName { get; }

    // Gets the task number.
    public int TaskNumber { get; }

    // Gets the task status.
    public TaskStatus TaskStatus { get; }

    // Gets the task status as a string.
    public string TaskStatusStr { get; }

    public override string ToString()
}
```