[Cog] Trying to understand #assert:

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[Cog] Trying to understand #assert:

Mariano Martinez Peck
 
Hi Eliot. I noticed that in the Cog VM there are a lot of asserts in the code. I am trying to understand them but I have a couple of questions:

- What happens with the code execution when an assert fails?  it stops the execution?  it continues? it raises an error?  I tried to follow to the definition of assert() but I only came to this:
# define assert(expr)  ((expr)||(warning(#expr " " __stringifyNum(__LINE__)),0))

So....after time, I understood that when I compile in "development" and I run with GDB, and I have something printed in the console like:

(primitiveIndexOf(GIV(newMethod))) != 0 8913

this means that in the line 8913 the assert has failed?  so, do I understand correct?   when an assert fails, the code continues to execute, but it just prints the expresion + number of line in the console?
if it doesn't fail, it doesn't print.

thanks in advance,

Mariano

Reply | Threaded
Open this post in threaded view
|

Re: [Cog] Trying to understand #assert:

Eliot Miranda-2
 
Hi Mariano,

On Mon, Dec 20, 2010 at 1:22 AM, Mariano Martinez Peck <[hidden email]> wrote:
 
Hi Eliot. I noticed that in the Cog VM there are a lot of asserts in the code. I am trying to understand them but I have a couple of questions:

- What happens with the code execution when an assert fails?  it stops the execution?  it continues? it raises an error?  I tried to follow to the definition of assert() but I only came to this:
# define assert(expr)  ((expr)||(warning(#expr " " __stringifyNum(__LINE__)),0))

There are a few defines for asserts (in platforms/Cross/vm/sqAssert.h); here's the entire file:

/*
 * An informative assert definition that prints expression and line number.
 *
 * assert's expression is evaluated only if NDEBUG is not defined and printed
 * along with its the line number if it is false.
 *
 * asserta's expression is always evaluated but only printed if it is false and
 * NDEBUG is not defined. (asserta => assert always)
 *
 * assertf's message is printed along with its line number if NDEBUG is not
 * defined. (assertfd => assert fail)
 */

extern void warning(char *);

#ifdef NDEBUG /* compatible with Mac OS X (FreeBSD) /usr/include/assert.h */
# undef assert
# define assert(expr) 0 /* hack disabling of asserts.  Better in makefile? */
# define asserta(expr) (expr)
# define assertf(msg) 0
# define PRODUCTION 1
#elif 1
# undef assert
# define __stringify(foo) #foo
# define __stringifyNum(n) __stringify(n)
# define assert(expr)  ((expr)||(warning(#expr " " __stringifyNum(__LINE__)),0))
# define asserta(expr) ((expr)||(warning(#expr " " __stringifyNum(__LINE__)),0))
# define assertf(msg)  (warning(#msg " " __stringifyNum(__LINE__)),0)
# define PRODUCTION 0
#endif

#define halt() warning("halt")

 So there are three assert functions, assert, asserta and assertf.  These all print warnings if enabled; they do /not/ terminate execution - in the VW/HPS experience getting asserts right can be hard so having them produce warnings is more convenient than having them terminate execution.

Asserts are optional checks.  They are not present in the production VM (since evaluating asserts may cost performance).  You'll see in the Cog VM I build three VMs, the production one without asserts, the Assert VM with asserts enabled and with moderate optimization, good for smoke testing, and the Debug VM with asserts enabled but no optimization, good for debugging.

If enabled, assert prints a warning with the expression that failed, and the line number

asserta like assert prints a warning if its expression is false, but its expression is /always/ evaluated.  So if you disable asserts its expression is still evaluated.  Hence
# define asserta(expr) (expr)
So if you have an expression that is being evaluated for effect but you still want to check, use asserta.

assertf, if enabled, always prints a warning, so you use it when control reaches a point it shouldn't, e.g. the end of a chain of if-the-elses.


So....after time, I understood that when I compile in "development" and I run with GDB, and I have something printed in the console like:

(primitiveIndexOf(GIV(newMethod))) != 0 8913

this means that in the line 8913 the assert has failed?  so, do I understand correct?   when an assert fails, the code continues to execute, but it just prints the expresion + number of line in the console?
if it doesn't fail, it doesn't print.

that's right.

HTH
Eliot
 

thanks in advance,

Mariano



Reply | Threaded
Open this post in threaded view
|

Re: [Cog] Trying to understand #assert:

Mariano Martinez Peck
 
Thanks Eliot. This has been very helpful.

A problem I have debugging this asserts in Cog is that when an assert fails, it is not easy to discover why. So....I need to change the code, and ask an if, see if it fails, and if true, print the results.

So, for example, if I have:

self assert:  newMethod ... mcType = CMFree

then I need to add before that an if like this:

(expression) ifFalse: [ "print the actual results to understand" ].

->> (newMethod ... mcType = CMFree) ifFalse: [ self print: 'method type: '; self printNum:  newMethod..mcType..].

do you understand?

Now I was from my complete ignorance...if it could be possible to add a assert:equals:  just the same as in TestCase:

assert: expected equals: actual
    ^ self
        assert: (expected = actual)
        description: (self comparingStringBetween: expected and: actual)
 

So then in the assert I can do:

self assert:  newMethod ... mcType queals: CMFree

so after...in C, the message can be something like:   received:  "what newMethod ... mcType answers"  but expected:  CMFree.

Do you think this is doable?

thanks again in advance

Mariano


On Mon, Dec 20, 2010 at 7:53 PM, Eliot Miranda <[hidden email]> wrote:
 
Hi Mariano,

On Mon, Dec 20, 2010 at 1:22 AM, Mariano Martinez Peck <[hidden email]> wrote:
 
Hi Eliot. I noticed that in the Cog VM there are a lot of asserts in the code. I am trying to understand them but I have a couple of questions:

- What happens with the code execution when an assert fails?  it stops the execution?  it continues? it raises an error?  I tried to follow to the definition of assert() but I only came to this:
# define assert(expr)  ((expr)||(warning(#expr " " __stringifyNum(__LINE__)),0))

There are a few defines for asserts (in platforms/Cross/vm/sqAssert.h); here's the entire file:

/*
 * An informative assert definition that prints expression and line number.
 *
 * assert's expression is evaluated only if NDEBUG is not defined and printed
 * along with its the line number if it is false.
 *
 * asserta's expression is always evaluated but only printed if it is false and
 * NDEBUG is not defined. (asserta => assert always)
 *
 * assertf's message is printed along with its line number if NDEBUG is not
 * defined. (assertfd => assert fail)
 */

extern void warning(char *);

#ifdef NDEBUG /* compatible with Mac OS X (FreeBSD) /usr/include/assert.h */
# undef assert
# define assert(expr) 0 /* hack disabling of asserts.  Better in makefile? */
# define asserta(expr) (expr)
# define assertf(msg) 0
# define PRODUCTION 1
#elif 1
# undef assert
# define __stringify(foo) #foo
# define __stringifyNum(n) __stringify(n)
# define assert(expr)  ((expr)||(warning(#expr " " __stringifyNum(__LINE__)),0))
# define asserta(expr) ((expr)||(warning(#expr " " __stringifyNum(__LINE__)),0))
# define assertf(msg)  (warning(#msg " " __stringifyNum(__LINE__)),0)
# define PRODUCTION 0
#endif

#define halt() warning("halt")

 So there are three assert functions, assert, asserta and assertf.  These all print warnings if enabled; they do /not/ terminate execution - in the VW/HPS experience getting asserts right can be hard so having them produce warnings is more convenient than having them terminate execution.

Asserts are optional checks.  They are not present in the production VM (since evaluating asserts may cost performance).  You'll see in the Cog VM I build three VMs, the production one without asserts, the Assert VM with asserts enabled and with moderate optimization, good for smoke testing, and the Debug VM with asserts enabled but no optimization, good for debugging.

If enabled, assert prints a warning with the expression that failed, and the line number

asserta like assert prints a warning if its expression is false, but its expression is /always/ evaluated.  So if you disable asserts its expression is still evaluated.  Hence
# define asserta(expr) (expr)
So if you have an expression that is being evaluated for effect but you still want to check, use asserta.

assertf, if enabled, always prints a warning, so you use it when control reaches a point it shouldn't, e.g. the end of a chain of if-the-elses.


So....after time, I understood that when I compile in "development" and I run with GDB, and I have something printed in the console like:

(primitiveIndexOf(GIV(newMethod))) != 0 8913

this means that in the line 8913 the assert has failed?  so, do I understand correct?   when an assert fails, the code continues to execute, but it just prints the expresion + number of line in the console?
if it doesn't fail, it doesn't print.

that's right.

HTH
Eliot
 

thanks in advance,

Mariano





Reply | Threaded
Open this post in threaded view
|

Re: [Cog] Trying to understand #assert:

Eliot Miranda-2
 
when I see an assert fail I move to the Debug vm, set a breakpoint in warning and run my reproducible test case.  It therefore breaks at the first assert fail and I can diagnose in the debugger.

HTH
Eliot

On Tue, Dec 21, 2010 at 3:09 PM, Mariano Martinez Peck <[hidden email]> wrote:
 
Thanks Eliot. This has been very helpful.

A problem I have debugging this asserts in Cog is that when an assert fails, it is not easy to discover why. So....I need to change the code, and ask an if, see if it fails, and if true, print the results.

So, for example, if I have:

self assert:  newMethod ... mcType = CMFree

then I need to add before that an if like this:

(expression) ifFalse: [ "print the actual results to understand" ].

->> (newMethod ... mcType = CMFree) ifFalse: [ self print: 'method type: '; self printNum:  newMethod..mcType..].

do you understand?

Now I was from my complete ignorance...if it could be possible to add a assert:equals:  just the same as in TestCase:

assert: expected equals: actual
    ^ self
        assert: (expected = actual)
        description: (self comparingStringBetween: expected and: actual)
 

So then in the assert I can do:

self assert:  newMethod ... mcType queals: CMFree

so after...in C, the message can be something like:   received:  "what newMethod ... mcType answers"  but expected:  CMFree.

Do you think this is doable?

thanks again in advance

Mariano


On Mon, Dec 20, 2010 at 7:53 PM, Eliot Miranda <[hidden email]> wrote:
 
Hi Mariano,

On Mon, Dec 20, 2010 at 1:22 AM, Mariano Martinez Peck <[hidden email]> wrote:
 
Hi Eliot. I noticed that in the Cog VM there are a lot of asserts in the code. I am trying to understand them but I have a couple of questions:

- What happens with the code execution when an assert fails?  it stops the execution?  it continues? it raises an error?  I tried to follow to the definition of assert() but I only came to this:
# define assert(expr)  ((expr)||(warning(#expr " " __stringifyNum(__LINE__)),0))

There are a few defines for asserts (in platforms/Cross/vm/sqAssert.h); here's the entire file:

/*
 * An informative assert definition that prints expression and line number.
 *
 * assert's expression is evaluated only if NDEBUG is not defined and printed
 * along with its the line number if it is false.
 *
 * asserta's expression is always evaluated but only printed if it is false and
 * NDEBUG is not defined. (asserta => assert always)
 *
 * assertf's message is printed along with its line number if NDEBUG is not
 * defined. (assertfd => assert fail)
 */

extern void warning(char *);

#ifdef NDEBUG /* compatible with Mac OS X (FreeBSD) /usr/include/assert.h */
# undef assert
# define assert(expr) 0 /* hack disabling of asserts.  Better in makefile? */
# define asserta(expr) (expr)
# define assertf(msg) 0
# define PRODUCTION 1
#elif 1
# undef assert
# define __stringify(foo) #foo
# define __stringifyNum(n) __stringify(n)
# define assert(expr)  ((expr)||(warning(#expr " " __stringifyNum(__LINE__)),0))
# define asserta(expr) ((expr)||(warning(#expr " " __stringifyNum(__LINE__)),0))
# define assertf(msg)  (warning(#msg " " __stringifyNum(__LINE__)),0)
# define PRODUCTION 0
#endif

#define halt() warning("halt")

 So there are three assert functions, assert, asserta and assertf.  These all print warnings if enabled; they do /not/ terminate execution - in the VW/HPS experience getting asserts right can be hard so having them produce warnings is more convenient than having them terminate execution.

Asserts are optional checks.  They are not present in the production VM (since evaluating asserts may cost performance).  You'll see in the Cog VM I build three VMs, the production one without asserts, the Assert VM with asserts enabled and with moderate optimization, good for smoke testing, and the Debug VM with asserts enabled but no optimization, good for debugging.

If enabled, assert prints a warning with the expression that failed, and the line number

asserta like assert prints a warning if its expression is false, but its expression is /always/ evaluated.  So if you disable asserts its expression is still evaluated.  Hence
# define asserta(expr) (expr)
So if you have an expression that is being evaluated for effect but you still want to check, use asserta.

assertf, if enabled, always prints a warning, so you use it when control reaches a point it shouldn't, e.g. the end of a chain of if-the-elses.


So....after time, I understood that when I compile in "development" and I run with GDB, and I have something printed in the console like:

(primitiveIndexOf(GIV(newMethod))) != 0 8913

this means that in the line 8913 the assert has failed?  so, do I understand correct?   when an assert fails, the code continues to execute, but it just prints the expresion + number of line in the console?
if it doesn't fail, it doesn't print.

that's right.

HTH
Eliot
 

thanks in advance,

Mariano