Runtime checking with bcheck

Reading uninitialised memory, reading past the end of arrays, or freeing memory twice are some of a number of problems which are hard to detect from browsing the source code of an application. This problems usually cause runtime behaviour which is random and hard to debug - the very act of running the program under the debugger can change the behaviour of the program (usually causing it to work perfectly ;).

The tool bcheck is an easy way of testing a program for uninitialised variables, or a number of other common runtime problems. The command is a convenient wrapper for dbx; the commandline looks like:

bcheck -all  

Consider this snippet of code:

void test()
{
  int a,b;
  a=b;
}

void main()
{
  int i,j;
  i=j;
  test();
}

This code has a couple of variables (j and b) which are used without being initialised first. Compiling the code with no optimisation and then running under bcheck produces the following output.

$ cc -g uninit.c
$ bcheck -all a.out
Reading a.out
Reading ld.so.1
Reading rtcapihook.so
Reading libc.so.1
Reading libdl.so.1
Reading libc_psr.so.1
Reading rtcaudit.so
Reading libmapmalloc.so.1
Reading libgen.so.1
Reading rtcboot.so
Reading librtc.so
access checking - ON
memuse checking - ON
Running: a.out 
(process id 25160)
RTC: Enabling Error Checking...
RTC: Running program...

Checking for memory leaks...
  errors are being redirected to file 'a.out.errs'

Actual leaks report    (actual leaks:            0  total size:          0 bytes)
Possible leaks report  (possible leaks:          0  total size:          0 bytes)
 
Checking for memory use...
  errors are being redirected to file 'a.out.errs'
Blocks in use report   (blocks in use:           0  total size:          0 bytes)
 
RTC output redirected to logfile 'a.out.errs'

execution completed, exit code is 1

The more complete report is recorded to the file a.out.errs:

$ more a.out.errs
 Read from uninitialized (rui):
Attempting to read 4 bytes at address 0xffbff9f0
    which is 96 bytes above the current stack pointer
Variable is 'j'
=>[1] main(), line 10 in "uninit.c"

 Read from uninitialized (rui):
Attempting to read 4 bytes at address 0xffbff988
    which is 96 bytes above the current stack pointer
Variable is 'b'
=>[1] test(), line 4 in "uninit.c"
  [2] main(), line 11 in "uninit.c"


Actual leaks report    (actual leaks:            0  total size:          0 bytes)

Possible leaks report  (possible leaks:          0  total size:          0 bytes)

Since the program has been compiled with debug and low optimisation, bcheck is able to report both the line number and the name of the variable causing the problem. When debug is enabled, the line number is usually available, but the variable name is normally only available at low optimisation (and debug).

Comments:

Post a Comment:
Comments are closed for this entry.
About

Darryl Gove is a senior engineer in the Solaris Studio team, working on optimising applications and benchmarks for current and future processors. He is also the author of the books:
Multicore Application Programming
Solaris Application Programming
The Developer's Edge

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
5
6
8
9
10
12
13
14
15
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today
Bookmarks
The Developer's Edge
Solaris Application Programming
Publications
Webcasts
Presentations
OpenSPARC Book
Multicore Application Programming
Docs