OS hacking: A better main() for SerenityOS C++ programs

Поделиться
HTML-код
  • Опубликовано: 5 фев 2025
  • SerenityOS is open source on GitHub: github.com/Ser...
    Follow me on Twitter: / awesomekling
    Sponsor me on GitHub: github.com/spo...
    Support me on Patreon: / serenityos
    Donate via Paypal: paypal.me/awes...
    Discord: / discord
    Merch: store.serenity...
    I drink Twinings Earl Grey tea! If you want to order some for yourself, you can support me by using my affiliate link: tidd.ly/3gjbGfj
    SerenityOS is a new operating system that we're building from scratch. serenityos.org

Комментарии • 52

  • @sam_bowman
    @sam_bowman 3 года назад +77

    Wow! I never would have even thought to replace int main(argc, argv) but this is clearly a huge improvement!
    It's truly impressive to me how Serenity has managed to take C++, a programming language I used to greatly dislike, and organically grow a code base that is as beautiful as the end product (and continually innovating and improving too!). It's caused me to realize that the majority of my distaste for C++ the language was misdirected, and what I really disliked was just the STL, poor style, and poor libraries, none of which are problems for Serenity.
    I really need to hurry up and graduate so I can spend more time contributing to this wonderful project...

    • @Andrath
      @Andrath 3 года назад +6

      He should include envp in his main though, and also modify his Argument class to include it.

  • @your_utube
    @your_utube 3 года назад +16

    Fail fast versus graceful failure is more in line with reality, where we would want warnings and a chance to mitigate failures that may sometimes be catastrophic. Great decision Andreas. I watched the interview with Brian after it was loaded and found it very nice , especially when I hear his approach to handling errors.

  • @anthonutty
    @anthonutty 3 года назад +9

    One neat trick: when you go to add a term to the CLion dictionary, one of the submenu items is to do it for the project dictionary which would allow you to check it into Git for others in your project to benefit from.

  • @skye1596
    @skye1596 3 года назад +13

    This was a really interesting watch! I rarely have time to watch your longer videos, but it's so enjoyable when I do.
    This is indeed, a really cool idea. Will definitely make the main() look nicer in many places!

  • @aryanadiazcakasana4414
    @aryanadiazcakasana4414 3 года назад

    Coming from golang and php seeing your video and your code encourage me to learn more about the kernel, and low level networking. Cant wait to get my hand dirty on this project this weekend !

  • @sgeisenh
    @sgeisenh 3 года назад +9

    ErrorOr has nice absl::Status vibes. A little bit unfortunate that statement expressions have not been standardized, yet.
    Really cool to see this kind of paradigm gaining steam as a reasonable alternative to exceptions.

  • @DanielTateNZ
    @DanielTateNZ 3 года назад

    I don't know why youtube unsubscribed me from your channel. Glad to re-subscribe and watch your videos again.

  • @Swirlstudios
    @Swirlstudios 3 года назад +6

    First off, I love this change and the out of the box thinking! One question though: Is there a reason you're duplicating the code between the wrapper and the original call, rather than just having one call the other? I can't see a reason why you'd want to have the code for pledge for example in two places, when you could just have the wrapper call the original and convert the resulting int to an ErrorOr or vice versa, but maybe I am missing something. It feels like you'd end up with twice as much code and the risk of things falling out of sync.

  • @akj7
    @akj7 3 года назад

    0:00 about the Result, i usually overload the operator bool() of the Result class to allow things like:
    if (!result) return result.error();
    or so. Not the best approach but does the job. Also works with std::assert.

  • @gazehound
    @gazehound 3 года назад +2

    Loving the new videos man

  • @1337dingus
    @1337dingus 3 года назад +1

    I'm a huge fan of this! Feels much more natural handling pledge and unveil this way.

  • @KnutBluetooth
    @KnutBluetooth 3 года назад +4

    Wouldn't it be possible to overload the main function and just have an alternative definition of main() instead of having a serenity_main() ?

  • @kiro_f
    @kiro_f 3 года назад +1

    wow this is super interesting, never even thought about the idea of the main getting replaced, but if one wanted to do the same, change the return value from main, and even possibly the parameters, how would that even be done?
    and by that i mean, still having the function being called main, would that still be able to be done without importing anything else?
    although i am aware SDL2 does something similar with redefining main.

  • @NotStirred9
    @NotStirred9 3 года назад +2

    @ 50:09, you added a TRY() around the unveil which previously had no error handling, was this intentional?
    Just thought I'd mention it :>
    I love the error propagation that comes from this, looks very clean!

  • @xasbo
    @xasbo 3 года назад +3

    Maybe I'm missing something, but won't this end up creating duplicate code between the new Wrappers.cpp and the existing syscall.cpp? The new approach is very slick, but I'm thinking forward to a scenario where one or the other is changed and they become out-of-sync functionally. Maybe that's just not likely because the existing syscalls are pretty well vetted?

  • @kawcco
    @kawcco 3 года назад +3

    Question: do Errors contain stack traces (e.g. Java, Python)? If so, I think it would be a good idea to print them in certain cases, as they'd be useful for finding runtime errors.

  • @chrrrs
    @chrrrs 3 года назад +4

    Does this allow for adding extra context to errors? I noticed while you were refactoring id, you deleted some warnln's that explained a bit what exactly went wrong, and with this you'd only get the final error message right?

    • @awesomekling
      @awesomekling  3 года назад +3

      Sure, we decide what an Error object contains. We definitely want to add more context to them as we go. :)
      The error strings I removed from the id program seemed pretty useless, so I elected to simply drop them.

  • @matthiasd4228
    @matthiasd4228 3 года назад

    I have been staring at your try macro trying to figure out how it works as an expression for a second. Is it relying on GCC statement expression extension? Great video, digging where this is going!

    • @awesomekling
      @awesomekling  3 года назад +1

      That's right, it wouldn't work without the statement expression extension. Thankfully that is available in both GCC and Clang :)

  • @diegorocha2186
    @diegorocha2186 3 года назад

    This is for sure a great idea, I wish golang have some way to handle error like this lol. Btw this IDE annotations (parameters annotations?) is really annoying and hard to read the code, but sorry if I sound rude, that is not the idea!

  • @andrewkelley9405
    @andrewkelley9405 3 года назад +5

    Oooo a DS3 background!

  • @gazehound
    @gazehound 3 года назад

    I already commented earlier but now I've had a chance to finish the video and I've warmed up to this idea so much more. Those error messages are so nice

  • @JordanWerthman
    @JordanWerthman 3 года назад +1

    Very cool idea , love the videos :) qq, is there a reason you don't pass the StringView arguments directly into the syscall args and elect to recreate them (passing characters and length).

    • @awesomekling
      @awesomekling  3 года назад +2

      The syscall boundary is written in assembly and takes a pointer+size separately.
      That said, we could probably make a convenience function that allows passing of a StringView directly.. 🤔

    • @JordanWerthman
      @JordanWerthman 3 года назад +1

      @@awesomekling ah that makes sense, I figured I was missing something, but I like the idea of expressing things as higher level primitives and shoving the messy C low level details as far down as possible and in one central place...
      I also wonder if it is worth implementing libc in terms of these higher level concepts natively since they seem more expressive and simply having a (possibly auto generated wrapper) that converts them to a traditional plain C interface... Though I haven't spent a lot of time thinking about the potential pitfalls of that approach.
      Excuse my armchair coding, love this project and that you make time to reply :)

  • @DFsdf3443d
    @DFsdf3443d Год назад

    when would you say its appropriate to use a macro like you do to handle the return code, vs using a static helper function?

  • @devashishjaiswal6037
    @devashishjaiswal6037 3 года назад +1

    38:40 slightly dislike the fact that return keyword isn't visible in code anymore but maybe that's okay idk.

  • @erlend1587
    @erlend1587 3 года назад +2

    What about adding a new Error type for syscalls which inherits from Error, so you don't add too much bloat to Error?

    • @erlend1587
      @erlend1587 3 года назад

      You could also add a "Error.message" method which would format it per type instead of doing a if / else

  • @human-ft3wk
    @human-ft3wk 3 года назад

    Great video! How did you list files inside a directory while typing your touch command at 16:58 ?

  • @camillebrugel2988
    @camillebrugel2988 3 года назад

    Hello Andreas,
    Thank you for your great streams. :^)
    I was wondering if there was a reason to make HANDLE_SYSCALL_RETURN_VALUE a macro vs using a simple function?

    • @awesomekling
      @awesomekling  3 года назад +3

      Hello Camille!
      As we add more syscall wrappers, not all of them will return ErrorOr. For example, an open() wrapper would return ErrorOr. Since we can't overload the function based on return type, I used a macro instead :^)

    • @camillebrugel2988
      @camillebrugel2988 3 года назад +1

      @@awesomekling Could have been a template function then? ;)
      edit: but you would have to specify the type (probably?) so that is slightly less pratical. Thank you for your answer!

  • @luandkg
    @luandkg 3 года назад

    Ohhh it's amazing 😮😮😮

  • @RobertWHurst
    @RobertWHurst Год назад

    I think try_main sounds better than serenity_main. It's more descriptive in explaining what it's actually for

  • @anthonutty
    @anthonutty 3 года назад +1

    Instead of making wrappers for stuff, would it make sense to make TRY macros for common return conventions that just takes a parameter to express what constitutes an error? For example: TRY_NON_NEGATIVE and pass in an expression that returns an int.

  • @Codeaholic1
    @Codeaholic1 3 года назад

    Is this the Result pattern?

  • @Handskemager
    @Handskemager 3 года назад

    What text editor are you using Andreas?

    • @Handskemager
      @Handskemager 3 года назад +1

      Ty! :) will have a look at it later

  • @rezaizadi2815
    @rezaizadi2815 3 года назад

    what is your idea ?

  • @thegabriel3891
    @thegabriel3891 3 года назад +2

    Make argparser great again by taking an arguments instead of argc/v.

  • @jr_stan_91
    @jr_stan_91 3 года назад

    Hello bro,where do you learn c++ for creating os

  • @bbq1423
    @bbq1423 3 года назад +1

    No envp in Main::Arguments then :p

    • @Andrath
      @Andrath 3 года назад +1

      Yeah he should probably fix that for portability-sake

  • @alfioemanuelef
    @alfioemanuelef 3 года назад +2

    Or, you know, you could build a Serenity OS Rust toolchain 💛

  • @WilliamRaezer
    @WilliamRaezer Месяц назад

    Ruining "main"😂.