Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTDEV
Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


clang-format and driver code

Jeffrey_Tippet_[MSFT]Jeffrey_Tippet_[MSFT] Member - All Emails Posts: 573

. . . I am now free to return to banging my fucking head against the wall trying to make clang-format (as packaged in VS 2019) actually do what I want it to do. Because, you know, that's something easy to accomplish.

My head still has bruises from my fights with clang-format. I can't say I'm 100% happy with the current cease-fire, but I have been able to coax clang into doing something ... passable ... with NDIS code.

The hard part was SAL annotations. I eventually solved that using a feature that was just introduced in the very recent clang 9.0 release: StatementMacros. This 9.0 release isn't currently bundled with Visual Studio, so you have to download it separately and configure VS to use your custom clang-format.exe. Tools > Options > Text Editor > C/C++ > Formatting > General > Use custom clang-format.exe file.

Then in your .clang-format, put something like this:

StatementMacros: [
    'EXTERN_C',
    '_At_',
    '_When_',
    '_Success_',
    '_Check_return_',
    '_Must_inspect_result_',
    '_IRQL_requires_',
    '_IRQL_requires_max_',
    '_IRQL_requires_min_',
    '_IRQL_saves_',
    '_IRQL_restores_',
    '_IRQL_saves_global_',
    '_IRQL_restores_global_',
    '_IRQL_raises_',
    '_IRQL_lowers_',
    '_Acquires_lock_',
    '_Releases_lock_',
    '_Acquires_exclusive_lock_',
    '_Releases_exclusive_lock_',
    '_Acquires_shared_lock_',
    '_Releases_shared_lock_',
    '_Requires_lock_held_',
    '_Use_decl_annotations_',
    '_Guarded_by_',
    ]

That'll ensure that each function-level annotation winds up on its own line, like this:

_IRQL_requires_(PASSIVE_LEVEL)
NTSTATUS Foo()
{
    return STATUS_NOT_IMPLEMENTED;
}

Another tip for drivers. If you use WPP tracing, you'll probably want this .clang-format directive:

CommentPragmas: '^begin_wpp|^end_wpp'

Otherwise, clang-format will permit itself to mangle the special //begin_wpp comment blocks.

That all being said, there's still brokenness here. For example, clang-format recognizes __declspec as a built-in token, so it won't let you hack it using StatementMacros. So NDIS code currently has this unfortunate spot of indentation:

__declspec(noinline)
    VOID ndisNblTrackerDebugBreak(. . . something . . .)
{
    . . .;
}

I also have some issues with clang-format's "binpacking" of arguments, but that's a general style issue and not specific to drivers, so I'll not discuss it here.

Comments

  • zx2c4zx2c4 Member Posts: 6

    Have you got a complete .clang-format file that works well for you generally? I wouldn't mind just adopting whatever code style you use wholesale.

  • Jeffrey_Tippet_[MSFT]Jeffrey_Tippet_[MSFT] Member - All Emails Posts: 573
    edited June 2019

    I won't say I'm completely happy about clang-format's output. Let's just say this format file is the best I could do, before my patience expired. But it is what we're using now for NDIS code.

    Some small parts of it are specific to NDIS code, like the PAGED and INITCODE tokens. You almost certainly don't need those.

    https://gist.github.com/jtippet/443c3769d5ff81691ebe6cdd9b9edd42

  • zx2c4zx2c4 Member Posts: 6

    Thanks! It's not so bad, and generally some enforced style even if not ideal is better than nothing.

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 7,845

    If I could only get the damn thing to wrap function arguments, one argument per line and aligned with the left brace. Always. I'd be a happy man.

            status = WdfDeviceCreate(&FxDeviceInit, 
                                     &deviceAttributes,
                                     &fxDevice);
    
    

    (let's hope everyone can read that. The point is the ampersands are all directly under each other)

    There is no setting -- none at all -- that I could use to get clang-format to produce anything even remotely like this. I don't even care if the first argument is on the same line as the function. I just want them all lined-up under each other, and with the left bracket, as Gxd himself so very obviously intended.

    I know, it defies common sense. I wasn't the only one who spent a whole day trying to get this to work, even :(

    Peter Viscarola
    OSR
    @OSRDrivers

  • Jeffrey_Tippet_[MSFT]Jeffrey_Tippet_[MSFT] Member - All Emails Posts: 573

    +1 I really don't like clang-format's love of what it calls "bin-packing". It's nice that the feature exists for whoever wants it, but I just want to turn it off everywhere. I got so frustrated that I tried to go fix their code, but then I discovered that it's this generic soup of crap that is designed to be equally bad at whitespacing both javascript, C++, Objective C, and google protobuf files. Because those are all clearly the same thing and need the same whitespacing rules.

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 7,845

    I got so frustrated that I tried to go fix their code, but then I discovered ...

    :D LOL LOL LOL

    That’s exactly what we did: “It’s open source. Pull the fucking repo and change the code to make it work. I mean, how hard can it be?”

    Most of my worst experiences have been prefaced with the phrase: how hard can it be?

    Yeah. Well. The answer is “Not hard. Rather, it’s effectively impossible unless you want to make clang-format your life's work. And, while my life may be pitifully silly in some respects, it’s not nearly pitiful enough to want to spend more than an hour of it on making clang-format do what it already should.

    “Oh well, whatever never mind”

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Kernel Debugging 30 Mar 2020 OSR Seminar Space
Developing Minifilters 15 Jun 2020 LIVE ONLINE
Writing WDF Drivers 22 June 2020 LIVE ONLINE
Internals & Software Drivers 28 Sept 2020 Dulles, VA