Skip to content

When traces are disabled, trace_* calls shouldn't expand to nothing #1999

Closed

Description

@paulstelian97

@ktrzcinx do you mean that if we have something like this

if (ret < 0) 
    trace_();
foo();

and the trace_() expands to nothing then we are in big trouble?

Originally posted by @dbaluta in #1997

Activity

  1. ktrzcinx commented on Oct 24, 2019

    @ktrzcinx
    Member

    I claim that when trace_* expands to nothing then it will be ok, but when trace_* expand to any code with more than one line of code without { } inside then it won't. It will be need to spend much more time to debug what happen in such a situation in comparison with usage redundant parenthesis. I know that such a macro function is not a good solution but it is open source project and when using extra {} I know that I am safe for such a situation. Such a situation is not a big abstraction, also in tracing functions, for example:

    #define trace(obj_ptr,msg,...) \ 
       typeof(obj_ptr) __obj_ptr__ = obj_ptr; \
       _log_fun(__obj_ptr__ ->id, __obj_ptr__ ->parent_id, __VA_ARGS__)
    

    or

    #define trace(obj_ptr,msg,...) \ 
       flush_logs(); \
       _log_fun(obj_ptr->id, obj_ptr->parent_id, __VA_ARGS__)
    

    Now

    if (ret < 0)
       trace(obj,"blah");
    foo();
    

    will trace independently ret value but my solution will still work correctly. There also won't be any compilation error and a lot of tests should pass. In conclusion, I rather prefer defensive programming with extra {} from debugging.

  2. paulstelian97 commented on Oct 24, 2019

    @paulstelian97
    CollaboratorAuthor

    @ktrzcinx This one is actually a non-issue as all multiline macros either are uppercase (obvious macros) or are wrapped around a do { ... } while(0) block. When I extended the trace function for my own platform (to also call some __dsp_printf() function which you can see in paulstelian97:topic/imx_wip) I wrap it around a do {...} while(0). That's what all macros which don't have uppercase macro-like names should do.

  3. paulstelian97 commented on Oct 24, 2019

    @paulstelian97
    CollaboratorAuthor

    A particular example of such is:

    #define __log_message(func_name, lvl, comp_class, id_0, id_1, has_ids,» \
    »       »             format, ...)»     »       »       »       »       \
    do {»   »       »       »       »       »       »       »       »       \
    »       _DECLARE_LOG_ENTRY(lvl, format, comp_class,»    »       »       \
    »       »       »          PP_NARG(__VA_ARGS__), has_ids);»     »       \
    »       BASE_LOG(func_name, id_0, id_1, &log_entry, ##__VA_ARGS__)»     \
    } while (0)
    

    This is a multiline macro from within trace. To make trace_* macros act as functions this has been made into a do {...} while(0) macro. So in your case no need for the extra safety as the convention is that any bugs coming from weird flow control from macros with lowercase names are bugs in the macros themselves and need to be adjusted. Hence my issue.

  4. ktrzcinx commented on Oct 24, 2019

    @ktrzcinx
    Member

    Of course it is as you said. The only difference is that extra { } allow to defense from errors in macros written out of convention and lack of then lead to malfunctioning code.

  5. paulstelian97 commented on Oct 24, 2019

    @paulstelian97
    CollaboratorAuthor

    Guess you can add it in, my issue still stands though -- the macros themselves are written like functions and should act like functions, thus should be safe even if you don't take care like that.

  6. dbaluta commented on Oct 24, 2019

    @dbaluta
    Collaborator

    @ktrzcinx I think the better defensive technique is to have macros wrapped around do {} while(0) rather then expecting anyone using curly braces with if constructs.

  7. ktrzcinx commented on Oct 25, 2019

    @ktrzcinx
    Member

    I found some bigger trouble with previous code and at the opportunity I removed this { } as you wish but I still think that the best options is using do { } while(0) in multiline macro functions and { } in each if statement were content is not just C/C++ keyword or rather in each if/while statement to be more consistent.

  8. paulstelian97 commented on Oct 25, 2019

    @paulstelian97
    CollaboratorAuthor

    Well unless someone else picks up on this before me I'll get to fixing this one myself once the asserts change is merged.

    Not having {} on if statements unless required by one of the branches is something coming from the Linux kernel coding style, which is also used within SOF. So:

    if (cond)
        action1;
    else
        action2;

    But:

    if (cond) {
        multiline1;
        multiline2;
    } else {
        single_action;
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions