Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Add more options to make output log a bit narrower #164

Open
3 tasks
0blu opened this issue Sep 1, 2024 · 3 comments
Open
3 tasks

Feature Request: Add more options to make output log a bit narrower #164

0blu opened this issue Sep 1, 2024 · 3 comments
Labels
enhancement New feature or request

Comments

@0blu
Copy link
Contributor

0blu commented Sep 1, 2024

image

I would really liked it if those features were implemented:

  • Omit function parameters, only print the namespace/name
  • Add source base dir.
    So it does not print D:\Programming\GitHub\Project\src\stuff\abc\main.c
    But rather src\stuff\abc\main.c
  • Omit std functions

Maybe add a struct of all those settings to the print() method.
Depending on how fancy those settings should be definable you can do something like this

// default settings
cpptrace::generate_trace().print();

// custom settings
auto base_dir = cpptrace::current_file("../../.."); //?
cpptrace::generate_trace().print(
    cpptrace::trace_print_settings()
        .set_output(std::cout)
        .set_color(false)
        .set_project_dir(base_dir)
        .set_omit_out_of_project_functions(true)
);
@jeremy-rifkin
Copy link
Owner

Hi thanks for opening this. I'm wondering whether this is something that should be done on the library side or the user side of things.

In one of my other libraries, libassert, which uses cpptrace I do a bunch of trace processing to make things look nice (like shortening file paths, folding recursive frames etc, and cleaning up type names in the signatures). I always envisioned this as being how the library would be used; cpptrace does all the "hard work" of generating the trace and the user figures out what to do with it.

That being said, I can see how it might be useful to provide some helpful trace cleaning utilities that are generally useful. I'm not immediately sure how best to go about doing this and where to draw the line between generally useful and more project-specific. I'd be interested in your thoughts

@0blu
Copy link
Contributor Author

0blu commented Sep 4, 2024

I understand and appreciate the work that this library does, but I feel like a bit of customizations or at least some helpers would be a nice addition.


I thought about modify the frames by myself,

    for (auto it = trace.frames.begin(); it != trace.frames.end(); ++it)
    {
        auto frame = *it;
        if (ShouldBeSkipped(frame))
        {
            it = trace.frames.erase(it);
            continue;
        }

        frame.filename = MakeNiceFilename(frame.filename);
        frame.symbol = MakeNiceSymbol(frame.symbol);
    }

but then I have to parse the filename and symbol by myself.

It would be much easier if the symbol would not be a std::string and had at least a custom data type like

struct cpptrace::function_symbol {
    std::string declaration_owner; // namespace / class path
    std::string name;
    std::vector<cpptrace::function_parameter> parameters;

    std::string to_string() const;
}

struct cpptrace::function_parameter {
    std::string type_declaration_owner; // namespace / class path
    std::string type_name;
    // std::string parameter_name; // impossible to get?

    std::string to_string() const;
}

Edit: it appears that C++ demangled type names are bit more complicated as the above example <.<

@jeremy-rifkin
Copy link
Owner

Thanks for the thoughtful response. I'm inclined to agree cpptrace should do much more on the formatting side of things. I was just running into a use where it would have been really convenient to be able to turn off the Stack trace (most recent call first): header but of course there's no option for that.

I think some sort of cpptrace::trace_print_settings builder is a great idea. I'll give this some more thought. At the very least options to control:

  • The header
  • Color
  • Filtering parameters
  • Filtering template parameters

would make sense. Additionally:

  • Maybe some std:: type name filtering (though that's a big can of worms)
  • Maybe some sort of .filter([](const auto& frame) { return !frame.symbol.starts_with("std::"); }) instead?

Path stuff too makes a lot of sense, though it adds a fair bit of complication on the library side of things. I think stack traces typically have absolute paths, though this isn't a guarantee. Everything is at the mercy of what the compiler decided to output. Handling symbolic links would probably be out of the question, paths in a trace aren't guaranteed to exist. I think trying to add some known base directories would make sense. Possibly the out of source exclusion stuff you mentioned as well, though that might be a little trickier.

On my other library, libassert, I do some path disambiguation stuff. E.g. /home/foo/bar/baz.hpp becomes baz.hpp if it's the only baz.hpp. That's usually sufficient in a trace. If there's another baz.hpp, e.g. /home/foo/bar2/baz.hpp, then they'd be bar/baz.hpp and bar2/baz.hpp as much as is needed for differentiating the two.

Regarding parsing of the symbol, unfortunately cpptrace usually gets the symbol name as a string so that's just carried through instead of doing any parsing and whatnot :)

@jeremy-rifkin jeremy-rifkin added the enhancement New feature or request label Sep 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants