.. _kassert: ********************** OS/161 - KASSERT() ********************** .. topic:: Learning Outcome Use KASSERT to check invariants and debug. .. topic:: Introduction KASSERT is a macro which tests for conditions which should never occurr in a correct implementation of OS/161. .. topic:: Applicable subjects COMP3231 ---- KASSERT ============== KASSERT(); If *expression* is false, panic is called. Panic terminates the program, however, we can still debug at this point if the program is executed with gdb and a breakpoint is placed on panic. The OS/161 on Linux and OS/161 on WSL modules contain instructions for how to set up appropriate .gdbinit files which place this breakpoint for us. *KASSERT()* is very similar to *assert()* with regards to its purpose and functionality. For more details on when these macros should be used, please see the :ref:`assert` module. ---- Example ======= We can use *KASSERT()* to check invariants within OS/161 - say if we want to dereference a pointer but we want to ensure that pointer is not NULL before we do that. However, somewhere in our code, if we accidentally set it to be NULL, a *KASSERT()* can be used to stop the program. An example of this is given below: Terminal 1: :: $ sys161 -p 16161 kernel sys161: System/161 release 2.0.8, compiled Feb 19 2017 14:31:53 OS/161 base system version 2.0.3 (with locks&CVs solution) Copyright (c) 2000, 2001-2005, 2008-2011, 2013, 2014 President and Fellows of Harvard College. All rights reserved. Put-your-group-name-here's system version 0 (ASST0 #4) 16224k physical memory available Device probe... lamebus0 (system main bus) emu0 at lamebus0 ltrace0 at lamebus0 ltimer0 at lamebus0 beep0 at ltimer0 rtclock0 at ltimer0 lrandom0 at lamebus0 random0 at lrandom0 lser0 at lamebus0 con0 at lser0 cpu0: MIPS/161 (System/161 2.x) features 0x0 panic: Assertion failed: foo != NULL, at ../../main/main.c:140 (boot) sys161: trace: software-requested debugger stop sys161: Waiting for debugger connection... sys161: New debugger connection Terminal 2: :: $ os161-gdb kernel (gdb) connect membar_any_any () at includelinks/machine/membar.h:47 47 __asm volatile( Breakpoint 1 at 0x8000ac8c: file ../../lib/kprintf.c, line 135. (gdb) where #0 membar_any_any () at includelinks/machine/membar.h:47 #1 membar_store_store () at includelinks/machine/membar.h:58 #2 lamebus_write_register (bus=, slot=, offset=offset@entry=16, val=val@entry=0) at ../../arch/sys161/dev/lamebus_machdep.c:184 #3 0x8000539c in ltrace_stop (code=code@entry=0) at ../../dev/lamebus/ltrace.c:87 #4 0x8000ad58 in panic (fmt=fmt@entry=0x8001f7b4 "Assertion failed: %s, at %s:%d (%s)\n") at ../../lib/kprintf.c:184 #5 0x8000add8 in badassert (expr=expr@entry=0x8001ffd4 "foo != NULL", file=file@entry=0x8001ff9c "../../main/main.c", line=line@entry=140, func=func@entry=0x8001db20 <__func__.2001> "boot") at ../../lib/kprintf.c:214 #6 0x8000b520 in boot () at ../../main/main.c:140 #7 0x8000b5d8 in kmain (arguments=) at ../../main/main.c:219 #8 0x8001d19c in __start () at ../../arch/sys161/main/start.S:216 (gdb) frame 6 #6 0x8000b520 in boot () at ../../main/main.c:140 140 KASSERT(foo != NULL); (gdb) print foo $1 = 0x0 (gdb) list 135 kheap_nextgeneration(); 136 137 { 138 139 char *foo = NULL; /* create a NULL pointer */ 140 KASSERT(foo != NULL); 141 * foo = 'x'; /* attempt to access it */ 142 } 143 144 /* (gdb) .. moduleauthor:: Liz Willer :Date: 2020-01-30