The assertions in LLVM would be a lot more useful if they could print out not only the source code of the expression that failed, but also print the values of the various arguments. To that end, I have an idea for an improved assert macro which would use raw_ostream. It would look something like this: ASSERT_STRM(Ty == STy, "Expected " << Ty << " but got " << STy->getElementType(0)); This would transform to: if (!(Ty == STy)) AssertionFailureStream(__FILE__, __LINE__) << "Expected " << Ty << " but got " << STy->getElementType(0); The AssertionFailureStream is a subtype of raw_ostream whose destructor calls abort() after printing the contents of the stream to stderr. (I use a similar technique in my frontend.) As you can see, this ought to work with any argument type that can work with raw_ostream. And it shouldn't cost anything if the assert doesn't fail. The actual definition of the macro would be something like this: #define ASSERT_STRM(cond, args) \ if (!(cond)) AssertionFailureStream(__FILE__, __LINE__) << args Note that there's no trailing semicolon, as this is supplied at the point where the macro is invoked. What do you think? -- -- Talin -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110726/55fc6174/attachment.html>
> #define ASSERT_STRM(cond, args) \ > if (!(cond)) AssertionFailureStream(__FILE__, __LINE__) << args > > Note that there's no trailing semicolon, as this is supplied at the > point where the macro is invoked. > > What do you think?Neat, but inducing a debug trap is even more useful on asserts (optionally).
On Tue, Jul 26, 2011 at 10:56 AM, FlyLanguage <flylanguage at gmail.com> wrote:> #define ASSERT_STRM(cond, args) \ >> if (!(cond)) AssertionFailureStream(__FILE_**_, __LINE__) << args >> >> Note that there's no trailing semicolon, as this is supplied at the >> point where the macro is invoked. >> >> What do you think? >> > > Neat, but inducing a debug trap is even more useful on asserts > (optionally). >What's the best way to do that? I'd like to incorporate it into my frontend's diagnostics. -- -- Talin -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110726/8309df13/attachment.html>
On Tue, Jul 26, 2011 at 10:41 AM, Talin <viridia at gmail.com> wrote:> The assertions in LLVM would be a lot more useful if they could print out > not only the source code of the expression that failed, but also print the > values of the various arguments. To that end, I have an idea for an improved > assert macro which would use raw_ostream. It would look something like this: > > ASSERT_STRM(Ty == STy, "Expected " << Ty << " but got " << > STy->getElementType(0)); >Chromium (and several other Google open source projects) have a somewhat superior variant of this: http://google.com/codesearch#hfE6470xZHk/base/logging.h&exact_package=http://src.chromium.org/git/chromium.git&q=CHECK&type=cs&l=398 It ends up looking like: CHECK(Ty == STy) << "Expected " << Ty << " .." << ...; The important difference is that most of the parameters go outside of the macro rather than inside, making error messages way more intelligible. *If* we want to go this direction in LLVM, I'd much rather see this formulation. It's still easy to have it compile away to nothing using ?: operator. *If* there is a desire to go this route, I've worked closely with several variants of the pattern and would be happy to contribute a minimal implementation. However, I agree with Chris's concerns about how useful this is in LLVM. While I've used it on projects where it provides tremendous value, with LLVM I often end up in the debugger anyways. I think the automatic debugger trapping is marginally more useful, but only marginally. Having my debugger discard the SIGABRT and continue isn't too hard. On the flip side, it might make crash reports from users much more useful (in the absence of, or prior to arriving at, a reduction). I think the cost is quite low, so maybe its worth it, but maybe it isn't. I'll leave it to Chris and others to make the call, just wanted to make sure a slightly different implementation was on the table in case it does go in... -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110727/90907fd9/attachment.html>
On Jul 27, 2011, at 12:51 AM, Chandler Carruth wrote:> On Tue, Jul 26, 2011 at 10:41 AM, Talin <viridia at gmail.com> wrote: > The assertions in LLVM would be a lot more useful if they could print out not only the source code of the expression that failed, but also print the values of the various arguments. To that end, I have an idea for an improved assert macro which would use raw_ostream. It would look something like this: > > ASSERT_STRM(Ty == STy, "Expected " << Ty << " but got " << STy->getElementType(0)); > > Chromium (and several other Google open source projects) have a somewhat superior variant of this: > > http://google.com/codesearch#hfE6470xZHk/base/logging.h&exact_package=http://src.chromium.org/git/chromium.git&q=CHECK&type=cs&l=398 > > It ends up looking like: > > CHECK(Ty == STy) << "Expected " << Ty << " .." << ...; > > The important difference is that most of the parameters go outside of the macro rather than inside, making error messages way more intelligible. *If* we want to go this direction in LLVM, I'd much rather see this formulation. It's still easy to have it compile away to nothing using ?: operator. > > *If* there is a desire to go this route, I've worked closely with several variants of the pattern and would be happy to contribute a minimal implementation. > > However, I agree with Chris's concerns about how useful this is in LLVM. While I've used it on projects where it provides tremendous value, with LLVM I often end up in the debugger anyways. I think the automatic debugger trapping is marginally more useful, but only marginally. Having my debugger discard the SIGABRT and continue isn't too hard. On the flip side, it might make crash reports from users much more useful (in the absence of, or prior to arriving at, a reduction). I think the cost is quite low, so maybe its worth it, but maybe it isn't.If this is done we should make sure the expressions operated on by the stream are only evaluated when the condition is false and !NDEBUG. Since the macros that I'm used to are not available in LLVM, I'm often tempted to write this: #ifndef NDEBUG if (!cond) { dbgs() << something_expensive_to_lookup; assert(false); } #endif I've gotten used to spending time in the debugger for simple problems just because using too many DEBUG() statements blows up the trace output, but nasty #ifdefs like this obfuscate the non-error code. -Andy -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110727/1b391a6c/attachment.html>
On Wed, Jul 27, 2011 at 12:51 AM, Chandler Carruth <chandlerc at google.com>wrote:> On Tue, Jul 26, 2011 at 10:41 AM, Talin <viridia at gmail.com> wrote: > >> The assertions in LLVM would be a lot more useful if they could print out >> not only the source code of the expression that failed, but also print the >> values of the various arguments. To that end, I have an idea for an improved >> assert macro which would use raw_ostream. It would look something like this: >> >> ASSERT_STRM(Ty == STy, "Expected " << Ty << " but got " << >> STy->getElementType(0)); >> > > Chromium (and several other Google open source projects) have a somewhat > superior variant of this: > > > http://google.com/codesearch#hfE6470xZHk/base/logging.h&exact_package=http://src.chromium.org/git/chromium.git&q=CHECK&type=cs&l=398 > > It ends up looking like: > > CHECK(Ty == STy) << "Expected " << Ty << " .." << ...; > > The important difference is that most of the parameters go outside of the > macro rather than inside, making error messages way more intelligible. *If* > we want to go this direction in LLVM, I'd much rather see this formulation. > It's still easy to have it compile away to nothing using ?: operator. > > Can you explain how it avoids evaluating the arguments in the false case? Ilooked at the code but it's pretty complex.> *If* there is a desire to go this route, I've worked closely with several > variants of the pattern and would be happy to contribute a minimal > implementation. > > However, I agree with Chris's concerns about how useful this is in LLVM. > While I've used it on projects where it provides tremendous value, with LLVM > I often end up in the debugger anyways. I think the automatic debugger > trapping is marginally more useful, but only marginally. Having my debugger > discard the SIGABRT and continue isn't too hard. On the flip side, it might > make crash reports from users much more useful (in the absence of, or prior > to arriving at, a reduction). I think the cost is quite low, so maybe its > worth it, but maybe it isn't. > > I'll leave it to Chris and others to make the call, just wanted to make > sure a slightly different implementation was on the table in case it does go > in... >-- -- Talin -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110727/9e0f1cc0/attachment.html>