Debugger tools

I'm in need of a debugger. Something that would allow stepping through the code. I don't need anything robust like breakpoints or variable watches, just stepping through. Any tools? Possible feature?

1 Like

https://www.keysight.com/en/pd-2730652-pn-16861A/34-channel-portable-logic-analyzer?cc=US&lc=eng

Probably some surface mount soldering skills will be necessary too.

3 Likes

It's a joke, correct?

2 Likes

YES

:smiley:

I have a very dry humor. It's my Father's fault. He was British. They are afflicted with that.

5 Likes

Well, continuing the joke then, I guess you can say I am a "debugger", but I don't do anything usefull that you want!

To quote my Mom: Now where is de bugger hiding again????

J

4 Likes

What I use is a mixture of log.* commands and state variables where I need to see certain things at a given point.

I always add what line number I'm on to my logging and the method name.

Breaking up your code in more debuggable chunks helps as well.

If I am dealing with someone else's code, I start with putting in log.trace commands at the start and end of each method and include vars passed in.

No real option for any tools beyond this. Just basic debugging.

That's what I've been doing, aside from using line numbers. But I've got a function that's somehow triggering multiple times when it shouldn't. I was hoping some way of stepping through. Other than just mentally stepping through it, which is difficult even with debugs because it's a scheduled function, I'm at a loss.

How do you "clean up" after?

You spray state variables around the code and then you find it.. this debug session is over. You want to go back to the normal set of state variables. How do you revert? I ask because I've gone through 4-6 drivers attached to a device as I try and find the ideal one. (The Aeon MultiSensor6 is the example in my head at the moment.) There's the native one and at least 5-6 others I've tried. My device has state variables that never go away. I know the tedious way:

private dbCleanUp() {
unschedule()
state.remove("version")
state.remove("sensorTemp")
}

Identify each state variable and remove it, by name.

I'm thinking the Great and Powerful OZ... I mean @patrick has a much silkier way..

1 Like

When I have a block of code that's giving me trouble I normally use https://groovyconsole.appspot.com/ so I can test the logic and make sure I didn't make any simple groovy mistakes.

It's not a debugger, but I've found it helpful, especially at first while I was learning Groovy.

1 Like

I do the same thing except I use logTrace "message" and add the function below so I can toggle trace logging on and off by commenting out that one line in the function.

private logTrace(msg) {
    log.trace "${msg}"
}

I would love to do better debugging while testing. I currently add a bunch of logs all over the place that I have to remember to comment or delete before sharing.

Can you explain how your method is different from doing a log.trace msg?
I'm obviously missing something because it seems like it would require the same number of lines to comment out.

Adding a single method means you can toggle it or just comment out the one log.trace command for that method.

As for cleaning up state, it you are developing something, surely you are going to do a cleanup of your debugging by doing a production install.

Removing the app or driver / device and starting over is a key part of troubleshooting and insuring a great user experience.

Also using custom commands to trigger methods can help. Using the groovy console listed above can help too.

Last tip is good documentation. I usually write down what each method should be doing, inputs, calculation and conversions and outputs.

If I can't write that out then I don't understand the code. Time to refactor it.

Patience, determination and lots of logging will get you what you need.

Stopping the hub to see what line you are on in code is not practical nor benifical.

Internally, we all use actual hubs to write apps and drivers.

Last tip, use the code folding. Or the go to line number features of the code editor. Fold up the known good code. Jump to specific line numbers quickly.

Oh and keep a notebook. Write down stuff. Don't keep it in your head. You will forget.

Also an ultrawide or dual screen monitor works wonders :slight_smile:

I code directly on the hub (I need to test at every step because I brute force a lot). Is this possible on the hub code editor? If not consider this a feature request :smiley:

I'm sorry, I still dont get how commenting out
Log.trace "message"

Is different from commenting out
Logtrace("message")

Since you are in development mode, is there any chance that you are forgetting to "unschedule()" previous scheduled events? This could easily lead to having your function called multiple times. Most Apps call unschedule() in their updated() method, and then schedule() just the events that are now needed.

I could see during development where this could get overlooked.

You can leave all the logTrace "message" lines in place because they won't actually do anything if the one log.trace line in that function is commented out. I always put that function at the bottom of my code so when I paste it into the IDE I'll see it and remember to comment it out in the final version.

I'm not sure if you're using any of my ST handlers, but I'm pretty sure I've implemented that in all of them.

If a user is running into problems with one of my handlers I sometimes tell them to uncomment that line, do some stuff, then send the live logging info. That sometimes makes troubleshooting the problem a lot easier.

1 Like

Code folding is already in the 2.0 editor. See the left side margin for the tick marks.

Along with going to a specific line number.

3 Likes

Following the advice here, I'm going through and putting in comments at the beginning of each method with incoming values, and everywhere the method is exiting, including any value they're returning (eg all "return"s and at the end). That's a lot of work. So, I'm not going to pull them out, and commenting them would be just as much work as removing them.

Rather than commenting anything out, I'll just set a state in the initialize (eg "state.debug = true"), and have a method to output to log where it checks the state in one place, rather than having ""if(state.debug)" in front of every log message.

edit: Note that it will have to check the state.debug value on EVERY log output, so this is far more expensive than commenting out the one line in logTrace. /edit

Specifically, at least as first draft, I'm using something like "$app.label, $app.getId(): function methodName returning $value (matched device)" (where "matched device" is a description of the condition for why it's "return"ing).

Don't know how expensive app.getId() might be (edit: and probably not real useful except when using multiple child apps).

And, I'm debating whether to make it parent.logTrace, or put logTrace in all child apps.

This is awesome!
No more marathon scrolling.

This stuff needs to be in the changelogs under "misc" or something like that because I never would have noticed it...and the little things make a huge difference sometimes.

Any way to make the fold setting stick?
The more you give...the more we want :smile:

It should stick.