libtock-rs icon indicating copy to clipboard operation
libtock-rs copied to clipboard

debug: Add debugging prints crate

Open dcz-self opened this issue 3 years ago • 15 comments

Calling out to Console for "printf debugging" is tedious. This introduces macros familiar from stdlib: print, println, dbg.

The advantage of using those macros is also easier import of the tools needed for printing.

The cost is that the macros will panic at any hint that something went wrong.

TODO

I'm not sure how to put the macros in the global scope, and that could improve useability a lot.

The macros are also useful for debugging drivers, but it's messy to add them: they require both a dependency declaration and an import. With multiple debugging/committing cycles, it gets really annoying to add-remove-add-remove the calls and imports repeatedly.

Would it make sense to put these macros in libtock_platform? Since those are naked macros, they do not pull the console driver. They will fail to compile if libtock::console isn't there.

dcz-self avatar Aug 29 '22 15:08 dcz-self

I'm in favour of putting these in libtock_platform

alistair23 avatar Aug 30 '22 06:08 alistair23

These macros belong in libtock_console.

jrvanwhy avatar Aug 30 '22 14:08 jrvanwhy

Moved the macros into libtock_console.

dcz-self avatar Aug 30 '22 15:08 dcz-self

I just realized why you originally put these into libtock -- they depend on libtock_runtime::TockSyscalls. I did not notice that at first.

That's a tricky dependency. libtock_console should not depend on libtock_runtime. I would normally say that elements of libtock_console should take the Syscalls implementation as a parameter, but doing so would remove a lot of the convenience of these macros. So maybe these belong in libtock after all?

I no longer have a strong opinion on whether these belong in libtock_console (with the Syscalls implementation injected by the caller) or in libtock. What do you think?

jrvanwhy avatar Sep 06 '22 17:09 jrvanwhy

I didn't actually put much thought into where they should be put. They are macros, and they will use imports from the user's crate, regardless of where they are.

That being said, those are more useful if they can be used ad-hoc, so the only dimension to optimize is: make them useful with as few extra imports and deps as possible.

Given that the macros require importing Console, I'm okay with the current placement.

dcz-self avatar Sep 06 '22 17:09 dcz-self

Given that the macros require importing Console, I'm okay with the current placement.

If that's the case, then you should make the caller specify the Syscalls implementation.

jrvanwhy avatar Sep 06 '22 17:09 jrvanwhy

Oh, they don't import Console the way I committed them.

I have two goals with this. First is for users of libtock-rs to not have to write their own macros. We have achieved that already.

The second goal is to be able to debug other drivers. For that, the macros don't work, because macros depend on libtock, and libtock depends on drivers, creating a dependency loop.

The macros need to live in a separate crate for that, and import libtock_console and libtock_runtime directly. Just like libtock is doing it:

    use libtock_console as console;
    type Console = console::Console<libtock_runtime::TockSyscalls>;
[rest of the macro]

Is that a good idea? What should this crate be called?

dcz-self avatar Sep 06 '22 18:09 dcz-self

Drivers must not depend on libtock_runtime, either directly or indirectly, because such a dependency would prevent us from unit-testing them. Adding a temporary dependency on either std or libtock_runtime while you're debugging a driver should work, but it's not a permanent solution.

jrvanwhy avatar Sep 06 '22 18:09 jrvanwhy

As this is meant to help debugging, I just want to make it doable rather than sustainable. I don't see another way to make debugging prints available in drivers.

There's the downside that I'm not sure how to prevent changes that would make drivers no longer ad-hoc debuggable. Perhaps add a dummy driver crate which does only one thing: use the debug print? This driver crate would not have to be unit tested, but would otherwise have the same dependency considerations as any other driver.

Does that make sense?

dcz-self avatar Sep 06 '22 18:09 dcz-self

Wait, when you say "debugging drivers", do you mean debugging syscall drivers in the Tock kernel, or debugging APIs in the apis/ directory of libtock-rs?

jrvanwhy avatar Sep 06 '22 19:09 jrvanwhy

I mean debugging the userspace parts of the drivers in the api/ directory.

dcz-self avatar Sep 06 '22 19:09 dcz-self

Hmm, I've never needed to debug libtock-rs' APIs with a real Tock kernel, the unittest environment has always been enough. Are you trying to debug the drivers before you have a unit test environment for them?

jrvanwhy avatar Sep 06 '22 19:09 jrvanwhy

Yes, typically I do. I guess this is also a sort of sanity check, where I try to verify that the kernel side is doing the correct thing (this is how I caught the broken ABI).

dcz-self avatar Sep 06 '22 19:09 dcz-self

Okay, now I see why you want this. I think putting these in a separate crate is reasonable. Maybe libtock_print_macros? I do not think the new crate should live under apis/, but rather in the root of the repository, and libtock should depend on it.

Which is probably close to or exactly what this PR originally did, but GitHub has since forgotten the original version :-(

jrvanwhy avatar Sep 06 '22 20:09 jrvanwhy

I put the macros back in a crate on its own, added a standalone example, and even managed to add a not-nasty test to ensure that they can be used from within libtock itself.

dcz-self avatar Sep 07 '22 14:09 dcz-self

Yes - sorry, I'll come back to this as soon as I free up some time.

dcz-self avatar Jan 09 '23 19:01 dcz-self

Closing due to inactivity.

jrvanwhy avatar Sep 06 '23 15:09 jrvanwhy