Thread: Assert/Macro

  1. #1
    Registered User
    Join Date
    Dec 2009
    Posts
    47

    Assert/Macro

    I'm using assert's in my code and switching the NDEBUG flag to remove them at compile time, but my code is very modular and seperated among many c files. Is there a way to find out where the originating call to a function came from upon failure? Assert fails and reports the file and line, but that isn't entirely useful with generic code. After time, the problem can be found but i'd like a more specific error report.

    can I pass the " __FILE__ " etc.. attribute to functions? I guess I would have to not use asserts but develop my own, if I did include the '___FILE__ attribute i would have to macro all my functions so the caller's didn't know this was going on....

    Just looking for a good solution that is efficient, thanks.

  2. #2
    Registered User slingerland3g's Avatar
    Join Date
    Jan 2008
    Location
    Seattle
    Posts
    603
    I have used, use, variadic macros, to just simply print the -to- and -from-, I would believe you can do something similar, this all ties into using printf() for debugging.

  3. #3
    Registered User
    Join Date
    Dec 2009
    Posts
    47
    Can you be more specific or show me an example? Variodic macros?

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Attach a debugger to the program. When the assert triggers, the debugger will break and you can look at the stack trace.

    On UNIX systems, when an assert triggers it usually dumps core. Again, you can load that in the debugger and see the stack trace.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  5. #5
    Registered User
    Join Date
    Dec 2009
    Posts
    47
    no luck, it complains about not having assert.c in the local directory im running the program from....strange it doesn't take me to where to code really is...

  6. #6
    Registered User slingerland3g's Avatar
    Join Date
    Jan 2008
    Location
    Seattle
    Posts
    603
    What brewbuck suggested would be a more direct detailed approach, for those more lazy, you can simply just print were you left and where your heading by:

    [code]

    #define debug(args...) if(bug) printf(args)
    ...
    debug ("%s function....%s\n", *Entering-Exiting, *function_call);
    ...
    [/code


    http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html

  7. #7
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875
    I second Brewbucks approach; I have done it myself. Intentionally triggering the debugger based on logic is an old trick of mine. I cannot remember the exact line to trick it but it was *something like*: _asm 15 or _asm 3 or something (haven't done it for a long time, need to look it up if someone is interested. So the end-logic would look something like:

    Code:
    if( someDodgyConditionCallingForStackDump)
    {
          _asm 15;
    }
    Lame but it works.

    Peace
    Jeff
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

  8. #8
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875
    I second Brewbucks approach; I have done it myself. Intentionally triggering the debugger based on logic is an old trick of mine. I cannot remember the exact line to trick it but it was *something like*: _asm 15 or _asm 3 or something (haven't done it for a long time, need to look it up if someone is interested. So the end-logic would look something like:

    Code:
    if( someDodgyConditionCallingForStackDump)
    {
          _asm 15;
    }
    Lame but it works.

    Peace
    Jeff

    EDIT: I looked it up: its _asm int 3.
    Last edited by jeffcobb; 12-16-2009 at 07:32 PM. Reason: found exact line
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

  9. #9
    Registered User
    Join Date
    Dec 2009
    Posts
    47
    Seems easy, but what about getting the line and file number from the origin of the function call, as opposed to just inside the function? Is this a variable I'll have to pass to the function that is in some C file?

  10. #10
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by tempster09 View Post
    no luck, it complains about not having assert.c in the local directory im running the program from....strange it doesn't take me to where to code really is...
    So what? Use the stack trace. You don't need to source code to assert.c anyway.

    Remember that the crash doesn't happen in your code. assert() MAKES it crash. So the crash looks like it's coming from assert, which is not what you care about. Go up a level or two to get to the real problem.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  11. #11
    Registered User
    Join Date
    Dec 2009
    Posts
    47
    Well whatever the case, i know what an assert is and how it works. And i am capable of creating my own macro to do the same. My goal is merely to find out the origins of a function call (i.e. if it does not come from the same file which it never does). At the moment the only thing I can think of is passing the __FILE__ and __LINE__ arguments to my function calls which would require me to develop macros and function macros in order to hide this fact from the caller. I was simply asking if I had any other options, which it looks like I do not. This way I can fail inside the function I am calling, but also spit out the the information I need which is the origin file and line the call to my function came from.

  12. #12
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    For MSVC:
    __FUNCTION__ - outputs the current function name
    __FILE__ - outputs the current file
    __LINE__ - outputs the current line
    DebugBreak() - breaks the code on this line

    For Windows:
    OutputDebugString() - outputs a string to the output window

    If you use macros for this the replacement will take place at the point where the error occurred and thus the MSVC macros will have the correct values. You can output these to any output device you need to for debugging.

  13. #13
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by tempster09 View Post
    Well whatever the case, i know what an assert is and how it works. And i am capable of creating my own macro to do the same. My goal is merely to find out the origins of a function call (i.e. if it does not come from the same file which it never does). At the moment the only thing I can think of is passing the __FILE__ and __LINE__ arguments to my function calls which would require me to develop macros and function macros in order to hide this fact from the caller. I was simply asking if I had any other options, which it looks like I do not. This way I can fail inside the function I am calling, but also spit out the the information I need which is the origin file and line the call to my function came from.
    The other option, as I already said, is to use the debugger.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  14. #14
    Registered User
    Join Date
    Dec 2009
    Posts
    47
    Using the debugger is a must regardless, I am just trying to make it easier for someone debugging to have a file and line to debug at. A function that is being called is external to the main area where code is running, so knowing where code failed in some random file isn't exactly helpful when you have many lines of code in many other files all calling other files etc... makes it tricky to find the origin of the problem. Thats why I would like a breadcrumb trail printed to the screen on the even of an error to help the person debugging, afterall most of this code is just there for them to use, they don't know the intracate detai;s

  15. #15
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by tempster09 View Post
    Using the debugger is a must regardless, I am just trying to make it easier for someone debugging to have a file and line to debug at. A function that is being called is external to the main area where code is running, so knowing where code failed in some random file isn't exactly helpful when you have many lines of code in many other files all calling other files etc... makes it tricky to find the origin of the problem. Thats why I would like a breadcrumb trail printed to the screen on the even of an error to help the person debugging, afterall most of this code is just there for them to use, they don't know the intracate detai;s
    Do you not know what a backtrace is? All the information you are talking about is available in the debugger.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Popular pages Recent additions subscribe to a feed