How to do -g but without assertions?
How to do -g but without assertions?
I find myself using assert() and #if __FB_DEBUG__ ... #endif to add debugging code to FB code I write. This is enabled with -g and disabled without it, which is nice.
But sometimes, for profiling with valgrind/callgrind, I want to have debug symbols, but no assertions. I wish there was an option like -gsymbolsonly or -gnoassert that would add debug symbols but not use assert() or __FB_DEBUG__.
Does that seem too weird? Perhaps I just shouldn't use assert()/__FB_DEBUG__, but a custom mechanism. I'd prefer staying with the built-ins though.
But sometimes, for profiling with valgrind/callgrind, I want to have debug symbols, but no assertions. I wish there was an option like -gsymbolsonly or -gnoassert that would add debug symbols but not use assert() or __FB_DEBUG__.
Does that seem too weird? Perhaps I just shouldn't use assert()/__FB_DEBUG__, but a custom mechanism. I'd prefer staying with the built-ins though.
-
- Site Admin
- Posts: 6323
- Joined: Jul 05, 2005 17:32
- Location: Manchester, Lancs
Re: How to do -g but without assertions?
Probably the easiest one-off solution is to undefine/redefine ASSERT manually. But I agree; I don't think there's a strong connection between debugging symbols and asserts.
If we separate the two, it does mean having to redefine the meaning of __FB_DEBUG__. I think it should probably follow asserts, since I think they're more likely to need compile-time conditionals.
If we separate the two, it does mean having to redefine the meaning of __FB_DEBUG__. I think it should probably follow asserts, since I think they're more likely to need compile-time conditionals.
Re: How to do -g but without assertions?
Here's a patch for this: https://github.com/freebasic/fbc/compare/gsymbolsonly
I think it'd be useful, though I'm not sure about the exact name for the command line option. But I'm also associating __FB_DEBUG__ with assert() in any case.
I can't believe I didn't think of #undef/redefine though, that would have saved me some time in the past... I ended up manually removing assert()'s and __FB_DEBUG__ blocks :)
I think it'd be useful, though I'm not sure about the exact name for the command line option. But I'm also associating __FB_DEBUG__ with assert() in any case.
I can't believe I didn't think of #undef/redefine though, that would have saved me some time in the past... I ended up manually removing assert()'s and __FB_DEBUG__ blocks :)
-
- Site Admin
- Posts: 6323
- Joined: Jul 05, 2005 17:32
- Location: Manchester, Lancs
Re: How to do -g but without assertions?
Cool.
I think maybe -gsymbols would be a more natural choice, otherwise it feels like you're having to do extra typing just to confirm you don't want an unrelated (or 'orthogonally related') feature.
To get the full range of options, we could add -asserts or something. Maybe -noasserts too, though it would only be needed if -g is used instead of -gsymbols.
I guess we need to have some defines, e.g. __FB_SYMBOLS__ and __FB_ASSERTS__, and treat __FB_DEBUG__ as deprecated.
Perhaps __DB_DEBUG__ could effectively be (__FB_ASSERTS__ OR __FB_SYMBOLS__) - I think that would be the least surprising setup.
I think maybe -gsymbols would be a more natural choice, otherwise it feels like you're having to do extra typing just to confirm you don't want an unrelated (or 'orthogonally related') feature.
To get the full range of options, we could add -asserts or something. Maybe -noasserts too, though it would only be needed if -g is used instead of -gsymbols.
I guess we need to have some defines, e.g. __FB_SYMBOLS__ and __FB_ASSERTS__, and treat __FB_DEBUG__ as deprecated.
Perhaps __DB_DEBUG__ could effectively be (__FB_ASSERTS__ OR __FB_SYMBOLS__) - I think that would be the least surprising setup.
Re: How to do -g but without assertions?
How about -asserts (__FB_ASSERTS__) and -debugsymbols (__FB_DEBUGSYMBOLS__), and -g (__FB_DEBUG__) means both.
-gsymbols seems nicer than -gsymbolsonly, though since they look like an extended version of -g, perhaps it should really be something not starting with g, like -debugsymbols.
Or perhaps -debuginfo or -debugdata?
-gsymbols seems nicer than -gsymbolsonly, though since they look like an extended version of -g, perhaps it should really be something not starting with g, like -debugsymbols.
Or perhaps -debuginfo or -debugdata?
-
- Site Admin
- Posts: 6323
- Joined: Jul 05, 2005 17:32
- Location: Manchester, Lancs
Re: How to do -g but without assertions?
I think debug info and debug symbols tend to be used synonymously. So I'd probably favour -debuginfo since it's shorter and a little friendlier.
Assuming people use __FB_DEBUG__ only for asserts, then people who prefer -debuginfo to -asserts will prefer __FB_DEBUG__ to be set when both DEBUGINFO and ASSERTS are. People who prefer --asserts will prefer __FB_DEBUG__ to be set when either are set.
I can't really see any clear advantage of one over the other, but perhaps it's better to be conservative and choose the both-and option. But we should consider it to be deprecated either way.
Assuming people use __FB_DEBUG__ only for asserts, then people who prefer -debuginfo to -asserts will prefer __FB_DEBUG__ to be set when both DEBUGINFO and ASSERTS are. People who prefer --asserts will prefer __FB_DEBUG__ to be set when either are set.
I can't really see any clear advantage of one over the other, but perhaps it's better to be conservative and choose the both-and option. But we should consider it to be deprecated either way.
Re: How to do -g but without assertions?
I think I have a simple solution: Let's think of __FB_DEBUG__ as refering to "adding debug code to the program" (which could be assertions, or any other code added for debugging purposes). Then -g can stay as-is (enabling __FB_DEBUG__, assertions, and -debuginfo).
It probably doesn't make sense for __FB_DEBUG__ to be related to "adding debug info", because it's a source code configuration option but one can't control debug info this way (except perhaps with inline asm). And should we ever need something like that, then we could still add an __FB_DEBUGINFO__.
It probably doesn't make sense for __FB_DEBUG__ to be related to "adding debug info", because it's a source code configuration option but one can't control debug info this way (except perhaps with inline asm). And should we ever need something like that, then we could still add an __FB_DEBUGINFO__.
Re: How to do -g but without assertions?
In my mind, assert() has a lot more to do with the error checking options than with debug symbols. (Those are indicated with __FB_ERR__)
(It would be nice if you could enable array bounds and null pointer checking separately to the others. Plus I really want array bounds checking, but the overhead of null-pointer checking was so large that I had to rewrite code in C. Err, sorry for getting offtopic.)
Code: Select all
-e Add error checking
-ex Add error checking with RESUME support
-exx Same as above plus array bounds and null-pointer checking
-
- Site Admin
- Posts: 6323
- Joined: Jul 05, 2005 17:32
- Location: Manchester, Lancs
Re: How to do -g but without assertions?
So, are you suggesting we just add the extra command-line switches, and just change the __fb_debug__ to show when any one of them is used? Yeah, that might be enough.dkl wrote:I think I have a simple solution: Let's think of __FB_DEBUG__ as refering to "adding debug code to the program" (which could be assertions, or any other code added for debugging purposes). Then -g can stay as-is (enabling __FB_DEBUG__, assertions, and -debuginfo)
Sorting out the different kinds of error checking might be worth its own feature request I think.
Re: How to do -g but without assertions?
I think __FB_DEBUG__ shouldn't be related to debuginfo, but only asserts & co. That's assuming that FB source code will be much more interested in knowing when to compile in debugging code and has much less has interest/use in knowing whether fbc will produce a binary with debuginfo.
-asserts or -debugbuild or similar: enable assertions, set __FB_DEBUG__=1
-debuginfo: produce binary with STABS/DWARF2 info, set __FB_DEBUGINFO__=1
-g: -asserts + -debuginfo (backwards compatible)
---
Enabling debugging code such as assert() is indeed very similar to -exx, which also adds extra checking... perhaps we should enable assertions under -exx then (perhaps even instead of -g).
-asserts or -debugbuild or similar: enable assertions, set __FB_DEBUG__=1
-debuginfo: produce binary with STABS/DWARF2 info, set __FB_DEBUGINFO__=1
-g: -asserts + -debuginfo (backwards compatible)
---
Enabling debugging code such as assert() is indeed very similar to -exx, which also adds extra checking... perhaps we should enable assertions under -exx then (perhaps even instead of -g).
Re: How to do -g but without assertions?
dkl, saw your link to here from https://github.com/freebasic/fbc/issues/140
If we allow breaking some backward compatabilty, maybe this can work:
'-e...' options for error checking code generation
'-g' for debug symbol generation
'-debug' for "debug mode" (really only a label and an abstraction)
Options:
'-e' enable run-time library error checking
'-earray' enable array bounds error checking
'-easserts' enable asserts error checking
'-enullptr' enable null pointer error checking
'-ex' enable run-time library error checking, plus RESUME
'-exx' enable run-time library error checking, plus RESUME, plus all extra error checking (implies all '-e...' options)
'-debug' convenience option, sets __FB_DEBUG__ = -1
'-g' generate debug symbols (implies -nostrip)
'-profile' enable profiling (implies -nostrip)
'-nostrip' disable (inhibit) default linking option "--strip-all"
Instrinics:
__FB_DEBUG__
0 = default
-1 = '-debug' option was given, so build the "debug" version, user-defined meaning based on __FB_DEBUG__ usage in source code
__FB_ERR__ sum of the following values (bits)
1 = '-e' specified
2 = '-ex' specified
4 = '-exx' specified
8 = '-easserts' or '-exx' specified
16 = '-earray' or '-exx' specified
32 = '-enullptr' or '-exx' specified
__FB_DEBUGINFO__ (maybe, though probably not needed)
0 = no debugging symbols
-1 = '-g' was specified, debug symbols generated, intend to source debug in a debugger
If we allow breaking some backward compatabilty, maybe this can work:
'-e...' options for error checking code generation
'-g' for debug symbol generation
'-debug' for "debug mode" (really only a label and an abstraction)
Options:
'-e' enable run-time library error checking
'-earray' enable array bounds error checking
'-easserts' enable asserts error checking
'-enullptr' enable null pointer error checking
'-ex' enable run-time library error checking, plus RESUME
'-exx' enable run-time library error checking, plus RESUME, plus all extra error checking (implies all '-e...' options)
'-debug' convenience option, sets __FB_DEBUG__ = -1
'-g' generate debug symbols (implies -nostrip)
'-profile' enable profiling (implies -nostrip)
'-nostrip' disable (inhibit) default linking option "--strip-all"
Instrinics:
__FB_DEBUG__
0 = default
-1 = '-debug' option was given, so build the "debug" version, user-defined meaning based on __FB_DEBUG__ usage in source code
__FB_ERR__ sum of the following values (bits)
1 = '-e' specified
2 = '-ex' specified
4 = '-exx' specified
8 = '-easserts' or '-exx' specified
16 = '-earray' or '-exx' specified
32 = '-enullptr' or '-exx' specified
__FB_DEBUGINFO__ (maybe, though probably not needed)
0 = no debugging symbols
-1 = '-g' was specified, debug symbols generated, intend to source debug in a debugger
Re: How to do -g but without assertions?
Which seems to be different, from what 'vilhelmgray' has implemented currently (inverted logic -Strip).dkl wrote:Anyways, an option to disable the -s during linking sounds useful for that. It should probably remain the default for non-debug builds though.
I'd therefore, prefer your approach: -NoStrip, default = FALSE (keeps current behaviour intact).
Not certain, about some of the other propsed changes ... (do we really need them all?).
Re: How to do -g but without assertions?
Years later, I still wish for these commandline options so I can get bounds checking without other stuff! For example, the null ptr checking can be really slow and add a lot of bloat to an executable.
Also, it would be nice if you could get bounds/nullptr/rtlib checking but without the overhead of 4 calls to fb_ErrorSetModName/fb_ErrorSetFuncName in every single function? Those calls are a huge overhead in small inlined functions, which might otherwise compile to just a few instructions. The line number and filename are already passed to fb_ErrorThrowAt anyway. Could add a variant which passes the function name too (and maybe omits the res_label & resnext_label args, to reduce bloat a little?).
Of course fb_ErrorSetMod/FuncName are also used to report the position if a fatal signal occurs, but I'm OK with that. Also, even in that case you can get the function name in other ways, eg with glibc using backtrace/backtrace_symbols (which uses exported function names (ld --export-dynamic), not debug info.)
Another possible option: fb_InitSignals, to catch memory access and other fatal errors, is only called if you compile with -e/-ex/-exx. But if you call fb_InitSignals manually you can use ON ERROR GOTO to set a signal handler without needing -e. But few people would know to do that. Actually, maybe fb_InitSignals should just be called unconditionally from main()?
__FB_DEBUGINFO__ is useful, I use __FB_DEBUG__ to print whether or not the program was compiled with -g in its logs.
Also, it would be nice if you could get bounds/nullptr/rtlib checking but without the overhead of 4 calls to fb_ErrorSetModName/fb_ErrorSetFuncName in every single function? Those calls are a huge overhead in small inlined functions, which might otherwise compile to just a few instructions. The line number and filename are already passed to fb_ErrorThrowAt anyway. Could add a variant which passes the function name too (and maybe omits the res_label & resnext_label args, to reduce bloat a little?).
Of course fb_ErrorSetMod/FuncName are also used to report the position if a fatal signal occurs, but I'm OK with that. Also, even in that case you can get the function name in other ways, eg with glibc using backtrace/backtrace_symbols (which uses exported function names (ld --export-dynamic), not debug info.)
Another possible option: fb_InitSignals, to catch memory access and other fatal errors, is only called if you compile with -e/-ex/-exx. But if you call fb_InitSignals manually you can use ON ERROR GOTO to set a signal handler without needing -e. But few people would know to do that. Actually, maybe fb_InitSignals should just be called unconditionally from main()?
__FB_DEBUGINFO__ is useful, I use __FB_DEBUG__ to print whether or not the program was compiled with -g in its logs.
-
- Posts: 606
- Joined: Nov 28, 2012 1:27
- Location: CA, USA moving to WA, USA
- Contact:
Re: How to do -g but without assertions?
To me, it is exciting to think that the STW nightly builds can be built better as candidates with degrees of fail info by default, yet still be run 'stripped' if someone chooses to stay simple/small. Simply pointing someone to 'the latest build' that has not really been completely verified and approved does not do justice to the still inprogress work by the developers.
This is a much more mature candidate/release attitude than has been true in the past.
I think many/many of the promoters of FB will use these features to more effectively investigate possible bugs in code.
Should speed troubleshooting a lot, I think.
Could I suggest:
With these further variations in how FBC could be built, should the -version switch be modified to reflect the switches and parameters used to build this particular version?
david
This is a much more mature candidate/release attitude than has been true in the past.
I think many/many of the promoters of FB will use these features to more effectively investigate possible bugs in code.
Should speed troubleshooting a lot, I think.
Could I suggest:
With these further variations in how FBC could be built, should the -version switch be modified to reflect the switches and parameters used to build this particular version?
david
Re: How to do -g but without assertions?
maybe a verbose version of version? like '-version -v'?speedfixer wrote:With these further variations in how FBC could be built, should the -version switch be modified to reflect the switches and parameters used to build this particular version?
I'd like to see the actual repository commit ID part of the version information too, so it's known exactly what source version it was made from.
----
For some control over symbols in the executable, this recently added in fbc 1.07
Wiki pages added:changelog.txt wrote: - github #141: introduced '-strip'/'-nostrip' options to control symbol stripping of output files (William Breathitt Gray)
- github #141: fbc will default to stripping symbols if '-d ENABLE_STRIPALL' is passed in FBCFLAGS (William Breathitt Gray)
- github #141: makefile option 'ENABLE_STRIPALL=1' introduced to pass '-d ENABLE_STRIPALL' via FBCFLAGS by default for dos/win32 targets (William Breathitt Gray)
Compiler Option: -nostrip
Compiler Option: -strip
Wiki pages updated:
Compiler Options