Skip to content

Debugging

Neil Dorin edited this page Feb 12, 2020 · 12 revisions

Methods of Debugging

  1. You can use Visual Studio step debugging
    • Pros:
      • Detailed real time debugging into with breakpoints and object inspection
    • Cons:
      • Doesn't really work remotely
      • On processors with Control Subnet, you must be connected to the CS interface to use step debugging. Often not practical or possible.
      • No logging
      • Using breakpoints stops the program and can interrupt system usage
      • Requires the running application to be built in debug mode, not release mode
  2. You can use the Debug class features build into the PepperDash.Core library.
    • Pros:
      • Can be easily enabled from console
      • Allows for setting the level of verbosity
      • Works when troubleshooting remotely and doesn't require a connection to the CS interface of the processor.
      • Allows for logging to the Crestron error log or a custom log stored on removable media
      • Works regardless of build type setting (debug/release)
      • Can easily identify which class instance console messages are being generated by
      • Can use console commands to view the state of public properties on devices
      • Can use console commands to call methods on devices
      • Doesn't stop the program
    • Cons:
      • No detailed object inspection in real time
      • Only prints console statements already in code
      • When enabled at the highest level of verbosity, it can produce a significant amount of data in console. Can be hard to find messages easily.
      • No current mechanism to filter messages by device. (can be filtered by 3rd party tools easily, though)
      • Not very effective in debugging applications running on the VC-4 platform as only log messages get printed to the Syslog

How to use the PepperDash.Core Debug Class

The majority of interaction is done via console, preferably via an SSH session through Crestron Toolbox, PuTTy or any other suitable application.

In code, the most useful method is Debug.Console() which has several overloads. All variations take an integer value for the level (0-2) as the first argument. Level 0 will ALWAYS print. Level 1 is for typical debug messages and level 2 is for verbose debugging. In cases where the overloads that accept a Debug.ErrorLogLevel parameter are used, the message will ALWAYS be logged, but will only print to console if the current debug level is the same or higher than the level set in the Debug.Console() statement.

All statements printed to console are prefixed by a timestamp which can be greatly helpful in debugging order of operations.

// The most basic use, sets the level (0) and the message to print.
Debug.Console(0, "Hello World");
// prints: [timestamp]App 1:Hello World

// The string parameter has a built in string.Format() that takes params object[] items
string world = "World";
Debug.Console(0, "Hello {0}", world);
// prints: [timestamp]App 1:Hello World

// This overload takes an IKeyed as the second parameter and the resulting statement will
// print the Key of the device in console to help identify the class instance the message
// originated from
Debug.Console(0, this, "Hello World);
// prints: [timestamp]App 1:[deviceKey]Hello World

// Each of the above overloads has a corresponding variant that takes an argument to indicate
// the level of error to log the message at as well as printing to console
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Hello World");
// prints: [timestamp]App 1:Hello World

Console Commands

Appdebug:[slot] [0-2]

Gets or sets the current debug level where 0 is the lowest setting and 2 is the most verbose ` RMC3>appdebug:1 RMC3>AppDebug level = 0

RMC3>appdebug:1 1 RMC3>[Application 1], Debug level set to 1 `

Devlist:[slot]

Gets the current list of devices from DeviceManager

RMC3>devlist:1

RMC3>[16:34:05.819]App 1:28 Devices registered with Device Mangager:
[16:34:05.834]App 1:  [cec-1] Tx 5 cec 1
[16:34:05.835]App 1:  [cec-1-cec] 
[16:34:05.835]App 1:  [cec-5] Rmc 1 cec 1
[16:34:05.836]App 1:  [cec-5-cec] 
[16:34:05.836]App 1:  [cec-6] Dm Chassis In 1 cec 1
[16:34:05.837]App 1:  [cec-6-cec] 
[16:34:05.837]App 1:  [cec-7] Dm Chassis Out 1 cec 1
[16:34:05.838]App 1:  [cec-7-cec] 
[16:34:05.838]App 1:  [comm-1] Generic comm 1
[16:34:05.838]App 1:  [comm-1-com] 
[16:34:05.839]App 1:  [comm-2] Rmc comm 1
[16:34:05.839]App 1:  [comm-2-com] 
[16:34:05.840]App 1:  [comm-3] Rmc comm 2
[16:34:05.840]App 1:  [comm-3-com] 
[16:34:05.841]App 1:  [dmMd8x8-1] DM-MD8x8 Chassis 1
[16:34:05.842]App 1:  [dmRmc100C-1] DM-RMC-100-C Out 3
[16:34:05.843]App 1:  [dmRmc200C-1] DM-RMC-200-C Out 2
[16:34:05.843]App 1:  [dmRmc4kScalerC-1] DM-RMC-4K-SCALER-C Out 1
[16:34:05.844]App 1:  [dmTx201C-1] DM-TX-201C 1
[16:34:05.845]App 1:  [eisc-1A] 
[16:34:05.845]App 1:  [gls-odt-1] GLS-ODT-CN 1
[16:34:05.846]App 1:  [gls-oir-1] GLS-OIR-CN 1
[16:34:05.846]App 1:  [processor] 
[16:34:05.847]App 1:  [ssh-1] Generic SSH 1
[16:34:05.847]App 1:  [ssh-1-ssh] 
[16:34:05.848]App 1:  [systemMonitor] 
[16:34:05.848]App 1:  [tcp-1] Generic TCP 1
[16:34:05.849]App 1:  [tcp-1-tcp] 

Devprops:[slot] [deviceKey]

Gets the list of public properties on the device with the corresponding deviceKey

RMC3>devprops:1 cec-1-cec
[
  {
    "Name": "IsConnected",
    "Type": "Boolean",
    "Value": "True",
    "CanRead": true,
    "CanWrite": false
  },
  {
    "Name": "Key",
    "Type": "String",
    "Value": "cec-1-cec",
    "CanRead": true,
    "CanWrite": true
  },
  {
    "Name": "Name",
    "Type": "String",
    "Value": "",
    "CanRead": true,
    "CanWrite": true
  },
  {
    "Name": "Enabled",
    "Type": "Boolean",
    "Value": "False",
    "CanRead": true,
    "CanWrite": true
  }
]

RMC3>

Devmethods

Devjson