Wednesday May 14, 2008

VirtualBox, Parallels and OpenSolaris 2008-05

Ok, so OpenSolaris 2008-05 was released recently (see and I couldn't resist. I also couldn't resist the urge to try it out on my mac. Since I didn't want to actually create a dual boot system, I decided to try a couple of  virtualization products I happened to have handy. I already had VirtualBox, which I downloaded when Sun acquired it ( The other product was Parallels 3.0, which I acquired as part of a mac bundle that was sold (very cheaply, I might add) recently. So, armed with OpenSolaris, VirtualBox, and Parallels, I jumped headfirst into unknown territory, for up until now I hadn't tried any of these.

First up was Parallels. Not for any particular reason, just because. After firing it up, and pointing it at the OpenSolaris ISO image, it fired up the install. So far, so good. However, after some disconcerting warnings/errors about UARTs, inability to write addresses, and time-of-day clock warnings, the install "hung". I let it sit for a good long while, but nothing happened. I eventually gave up and aborted the installation. I didn't have any clue what happened, but I figured that I may as well try out VirtualBox. Quite a difference, I might add. Very simple (perhaps even simpler) than Parallels, and I didn't observe any errors during the installation. That speaks well of VirtualBox with respect to installing Solaris. So, after an amazingly simple installation process for OpenSolaris (yippee! I don't think it could have been any easier), it was finally time to boot it up under VirtualBox. Again, no problems at all. It came up without a hitch. Biggest surprise of all? I think that would have to be that wireless networking worked right out of the "box" (pun intended). Now how cool is that? Solaris is now, for all intent and purposes, fully functional for me on my mac. Nice!

Oh, so what about Parallels? Well, I noticed during the VirtualBox Solaris installation that they suggested a larger amount of memory than Parallels did for the OS being installed. I believe it was 512MB instead of 256MB. I decided to up it to 1GB for the VirtualBox install. Given that, I decided to go back and retry the Solaris installation under Parallels using 1GB memory allocated to the OS. Guess what? It worked, and it installed (though the unsettling errors/warnings were still present). After the install, I was able to boot it up. Great. And it seemed to be running ok as well. One major downer, however, was networking. Under Parallels, wireless networking does not work right out of the so-called box. In fact, I still haven't figured out how to get it to work. I'm not even sure that it is possible right now. At this point, I'm happy with VirtualBox, so I won't worry anymore (at least for now) about how to get the wireless working under Parallels (note that for installing and using windows xp, Parallels worked just fine for me ... apparently, they just can't handle Solaris very well, yet). Oh, and supposedly, plugging in an ethernet cable will allow you to access the internet in Solaris (through Parallels), but I'm not interested in doing that at the moment.

Here's how I'd rate my overall experience:

  • OpenSolaris - great. Give it a try, it's free.
  • VirtualBox - great. Give it a try as well, and it's free, too!
  • Parallels - ok. It's a nice product, but it's not free and it doesn't play well with Solaris, yet. 

Wednesday May 23, 2007

Sun Studio 12 - simplifying the debugging process


The feature discussed here is in an early form and available only through the use of a special compiler switch. The functionality isIn addition, since uninitialized local variable values are no longer random, whatever errors are seen should be not yet fully supported, but any feedback on the utility (or lack of utility :-) will help determine whether it is ever turned into a first-class, fully supported option in an upcoming update/patch. Feel free to comment directly to me or comment via SDN (Sun Developer Network) C and C++ compiler forums. Become a member and let us know what you think.


Debugging is an integral part of program development. A common bug, which can be one of the most difficult to detect due to its often random behavior, is that of using uninitialized local variables. Errors caused by these uninitialized variables can range from wrong answers to erratic program behavior resulting in segmentation faults.

Various tools, such as Purify, are helpful in detecting these kinds of programming errors. However, for large applications, these tools can sometimes be cumbersome. If there were a method to assist the programmer in detecting these errors, implemented in the compiler as an option, it would simplify the debugging process.

To that end, as an aid to programmers using the Sun Studio C compiler (and also the C++ compiler), a new flag has been added. This new flag instructs the compiler to assign pre-defined "garbage" values, based on data type, to all local variables. The expectation is that any subsequent use of a local variable prior to a "real" assignment will cause some form of an obvious error condition closer, in terms of program flow, to the actual cause of the problem (the use of an uninitialized variable) than would have otherwise been the case with the typical random value.

If this sounds somewhat familiar to any who have used Sun Studio tools in the past, it should. Since version 7.1, Sun Studio Fortran has supported the -xcheck flag, which is syntactically described as:


and is documented to:

"Perform special initialization of local variables."

"The compiler initializes local variables to a value that is likely to cause an arithmetic exception if it is used by the program before it is assigned. Memory allocated by the ALLOCATE statement will also be initialized in this manner."

"Module variables, SAVE variables, and variables in COMMON blocks are not initialized."

It is this flag that has been added to C and C++, and it's available on all architectures. The only significant difference between Fortran and C/C++ is in the excluded initializations: C/C++ exclude globals and statics.

As alluded to earlier, for the upcoming initial release of Sun Studio 12, this feature is only available by using a special switch. In other words, it is not possible to simply specify


This will result in the nifty little error message:

cc: Warning: illegal option -xcheck=init_local
usage: cc [ options] files. Use 'cc -flags' for details

The special switch that must be used to access this new flag is defined in two different ways, depending upon which compiler is used. For C, the switch is -W0. For C++, the switch is -Qoption. These can be used as follows to access the new init_local feature:

For C


For C++

-Qoption ccfe -xcheck=init_local

Note that the specific values used for initializations are always subject to change and can't be relied upon to remain identical between releases. Also, note that by the very nature of what -xcheck=init_local does, memory debuggers most likely will not be able to detect uses of uninitialized local variables in code compiled with this flag.

Wednesday May 16, 2007

__alignof__ keyword

Beginning with the Sun Studio 12 C compiler, the __alignof__ keyword (a gcc extension) will be accepted (see "Inquiring on Alignment of Types or Variables" in the gcc docs)

The syntax for __alignof__ is exactly like "sizeof", but it evaluates to the required, or optimal, alignment for a type or an object. It can be used in a variety of ways. For example, in situations where you want to specify an alignment larger than would normally be chosen, you can use this keyword in combination with __attribute__. Let's say you have an array of char and you want to change the eventual alignment from the default of "1" to that of the natural alignment of "int". Here's how it can be done -

unsigned char foo[100] __attribute__ ((aligned(__alignof__(int))));

Or perhaps there's some code somewhere that relies on data being aligned on a certain boundary. The __alignof__ keyword can be used to easily check the alignment -

        if (buffer % __alignof__(<aligned_data>)) ...

Or it can be used to simplify the specification of macros. For example -

 \* Largest alignment size needed, minus one.
#ifndef ALBYTES
#define ALBYTES (__alignof__ (long double) - 1)

/\* Align P to ALBYTES  \*/
#ifndef AL
#define AL(p) (((unsigned long int) (p) + ALBYTES) & ~ALBYTES)


  1. If the operand to __alignof__ is an lvalue rather than a type, the value returned is the alignment of the lvalue;
  2. No parentheses are required around expressions.

Friday May 11, 2007

Sun Studio 11 and a video game ... of course they go together

Ok, so I jump on over to Roman's blog entry

What do I see? Two things of which I've been guilty (hmm, perhaps I shouldn't be admitting any of this). First, I am a fan of video games, and not just when I was younger (I won't date myself by admitting to which early game console I owned). My most recent stint in the gaming world came from Halo/Halo2, though I've layed off the carnage for the time being (wait 'til November, though ... then it's Halo 3 ... whoot! whoot!)

I've also been the creater - though it's been many, many years now, and several companies ago - of some code a co-worker of mine took great pleasure in teasing me about. I dare not even bring it up to this day for fear of mass embarrassment. Besides, I'd deny it anyway.

Ok, so I've bared my soul - so to speak. What does any of this have to do with Sun Studio? Well, the main point of all this was, as noted in Roman's blog, the creation of this

a nifty little game that just happens to involve Sun Studio 11. Now, Halo it ain't. But, it's still quite a bit of fun.

Dave-Bob says, "Check it out".

Thursday Jun 01, 2006

Type-based alias analysis and lint

Type-based alias analysis and lint

Type-based alias analysis, enabled via the -xalias_level compiler option, can significantly improve optimizations performed by the compiler. The levels of aliasing that can be specified with this option specify certain properties about the way pointers are used in a C program. These "properties" range from assuming all memory references can alias each other (alias_level=any, the default) to a set of specific properties (specified under -alias_level=strong at the highest level) that broaden the assumptions the compiler can make about data references.

While alias levels and type-based alias analysis are all very well and good, a tool to assist in determining what potential aliasing may exist in a given program would simplify their use, especially when first considering type-based alias analysis for a particular program. Fortunately, there is a tool for this purpose: lint. Recognition of certain types of aliasing was added to lint (the traditional C program verifier as enhanced by Sun) at the same type as alias analysis was added to the C compiler.

Alias levels are specified to lint via the same option that is used with the C compiler, with the exception that the initial letter of the option is a capital 'X' instead of a lower case 'x'. For example, to specify an alias level of basic while using lint, you would use '-Xalias_level=basic'.

So, what does lint do that is of any value? Currently, it can aid in the diagnosis of certain situations in which assumptions specified by a given alias level are potentially violated or where more clarification is need than that which is available within the context of the source. An appropriate warning or error is generated when these situations are detected.

There are four cases that lint detects and for which it generates either a warning or an error:

    \* Casting a scalar pointer to a struct pointer

    \* Casting a void pointer to a struct pointer

    \* Casting a structure field to a scalar pointer

    \* Casting a struct pointer to a struct pointer at the level of -Xalias_level=strict without explicit aliasing.

For example, consider the following source:

struct fooa {
    int a;
    int b;

struct foob {
    int a;
    float b;

struct fooa \*f1;
struct foob \*f2;

void main()

    f1 = (struct fooa \*)f2;

Notice that we have a struct pointer assigned to another struct pointer where the two structs are identical (i.e., the same size) except for the tags associated with the individual struct fields. At alias level strict (or higher), lint issues a warning for the assignment:

(XX) warning: cast of struct pointer to struct pointer requires explicit aliasing under alias_level=strict

Why? Because, according to the definition of alias_level strict,

"... the compiler assumes that memory references, that involve types such as structs or unions, that are the same when tags are removed, can alias each other. Conversely, the compiler assumes that memory references involving types that are not the same even after tags are removed do not alias each other."

Since the two structs involved are not the same after the tags are removed, the compiler assumes (by definition) that they do \*not\* alias. However, the explicit assignment of one pointer to the other violates this aliasing assumption, which then causes lint to generate the above warning. As a side note, since each alias level builds on the preceding level, any alias level higher than strict will generate the same warning.

To eliminate the aliasing warning, and the potential for any unexpected optimization issues related to aliasing when compiling, as the warning message states, use explicit aliasing. This is accomplished by using the aliasing pragma "alias" at some point in the source prior to the first reference to the associated structs. It would be specified as follows:

#pragma alias (f1,f2)

Remember to run lint at a level of aliasing that is no more strict (i.e., makes stronger claims about types and data \*not\* aliasing) than that which will be used for the actual compilation.

For a complete discussion of type-based alias analysis, options, and associated aliasing pragmas, see chapter 5 of the Sun C User's Guide.

Bottom line: Try using type-based alias analysis to improve your program's performance, and try out lint's ability to detect and warn about potential aliasing problems up front.



« June 2016