FAQ

Questions frequently asked by Ovm users

Why does gen-ovm die with Configuration Error...?

Image building sometimes fails with the error, Configuration Error: in calling-class: invalid configuration of base-type: selected-type is not a subtype of needed-type. This happens when trying to use an incompatible set build options. Code in the OVM (calling-class in particular) needs additional features from the implemenation of base-type, but these features are not provided by the configured implemenation (selected-type).

Common sources of this error include:

If none of the above apply, your best bet is to grep for base-type in the ovm config files. (By default, these files are installed at /usr/local/ovm/config.)

Why does ovm die with an assertion failure complaining about abstract methods?

If such an error occurs at runtime, gen-ovm printed a warning at at compile time describing the problem in greater detail. These errors typically occur in application bytecode due to bugs in Ovm's method resolution code (see Bin compat).

Ovm developers encounter these errors more frequently. These errors occur on a call to a VM-internal method that itself calls a method that only exists at image-build time (inside the gen-ovm process). Warnings from gen-ovm indicate which methods it treats as build time, and the line number of the method's first build-time call.

Why does gen-ovm report that methods clearly inherited from interfaces are not found?

J2c's compile-time messages sometimes complain that methods in javax.realtime can't be found, or that application methods can't be found when said methods are clearly inheritted from interfaces. Both these problems can be avoided by invoking javac more carefully. javac should always be invoked as follows:

     javac -bootclasspath /usr/local/ovm/classes/ovm_rt_user.jar     \
           -target 1.1                                               \
           java-files
     
(You may need to change the path to ovm_rt_user.jar depending on where, or whether, you chose to install Ovm.) No other definitions of javax.realtime should be present in javac's -classpath or -bootclasspath lists.

Setting the appropriate -bootclasspath ensures that your code is compiled against the Ovm's javax.realtime implemenation, rather than code that implements another version of the RTSJ, or no version of the RTSJ at all.

Setting -target ensures that javac will generate class files that Ovm can understand.

Why does ovm dies with an assertion failure complaining about a reflective call to `unreachable' method?

The current version of J2c requires complete knowledge of reflection at image-build time. Every method that is invoked reflectively must be listed in the -ud-reflective-methods switch.

Building up this list can be extremely tedious, so we provide two alternatives:

Why doesn't the above work for a method named class__0003cclinit_0003e_n, and what is this method anyway?

The latter question is the key one: _0003cclinit_0003e_ corresponds to a <clinit> method in Java bytecode, and this method contains class's static initializers.1 Static initializers are not explicitly invoked through Java reflection, but may be implicitly invoked through Class.forName(). See NoClassDef for ways to ensure that a class, and its static initializers are included in an Ovm image.

Why am I getting NoClassDefFoundError for a class that is clearly defined?

Typically, this error occurs when a class C is only referenced through Class.forName() calls or C.class expressions, but this error may also come up if the standard library uses Class.forName() incorrectly. If u1_C does not appear in structs.hh, gen-ovm must be explicitly told to include C with the -ud-reflective-classes option.

As with -ud-reflective-methods, Ovm provides a couple ways to build this list automatically.

How can I run strip under Darwin?

In some configurations, ovm generates absolute symbols that point into the initial heap image. For some reason, MacOS's ld does not relocate references to these symbols. `strip -ruA' will strip all symbols that are not needed at runtime.

How do I enable fine-grained timers under RTLinux?

OVM uses a default timer interrupt rate of 10ms. This affects all timed operations, such as sleeps, waits, RTSJ periodic thread release, and RTSJ timers. The timer interrupt rate can be set at runtime using the -period runtime argument:

     ./ovm -period=nnn img main class name + args
     
where nnn is a value in microseconds. The requested value will be rounded up to a multiple of the supported underlying timer resolution. A warning is printed if you ask for a timer interrupt rate that is shorter than the supported timer resolution, but no warning is printed if the rate needs to be rounded up. OVM reports that actual timer interrupt rate being used at start-up time.

On the majority of Linux systems the supported timer resolution is 10ms. This cannot be changed. Apparently in 2.6 kernel Linux systems this will reduce to 1ms. When running on the licensed Timesys Linux RT system a high resolution implementation of the POSIX real-time timers is available, with a resolution of 1us. To use these timers you must ensure that the Timesys library, librk-rt.a, is available by setting the LIBRARY_PATH environment variable when running configure, and when building the OVM and an OVM image.

OK, how do I link with RTLinux's magic library?

First you must have the licensed version of Timesys Linux RT, not the GPL version. If you can find librk-rt.a then you have the licensed version.

Second, librk-rt.a must be locatable by ld when the configure script runs and when building the OVM and any image. To do this either librk-rt.a must be in the default location looked in by ld (which is /usr/lib normally) or you must set the LIBRARY_PATH environment variable to point to the directory where lbrk-rt.a is located. Check the config.log file to see if ld was able to find the library when configure ran. Check the build output to see if -lrk-rt is being passed as a link option.

You might be tempted to edit ld.so.conf instead of setting LIBRARY_PATH. This is a bad idea. ld.so.conf tells ld.so where to find dynamically loaded libraries at runtime. You need to tell ld where to find the statically linked librk-rt.a library at link time - the only way to do this (apart from recompiling ld) is to set the LIBRARY_PATH environment variables (NOTE: this is not LD_LIBRARY_PATH which is again telling ld.so how to dynamically load libraries at runtime.)

Questions frequently asked by Ovm developers

How can I use Eclipse on Ovm source code?

Go to src/ within your build directory, and run make eclipse-dotfiles. This target will overwrite .classpath and .project in your toplevel source directory, and allow you to run Eclipse as before. The make target is more reliable than the .classpath and .project files in CVS, because it knows whether a seperate build directory is being used, and it knows whether sun.tools.javac.Main is available in rt.jar.

How can I run tests manually?

By running make in the test directory, of course.

How are tests run automatically?

They are run on aardvark.cs.purdue.edu as the ovm psuedo-user. If all tests pass, I delete the entire OpenVM tree. Otherwise, I delete the VM-gen directories of all passing configurations. (These img files really eat up space.) If you are Fil and you are lucky (an unlikely combination), some impossible-to-reproduce bug has resulting in a j2c core dump during automated testing. You can now:

     me@here> ssh aardvark
     me@aardvark> sudo -u ovm bash
     password: your own password
     ovm@aardvark> cd /scrach/ovm/OpenVM-YYYYMMDDHH00/test/build-failed-test
     ovm@aardvark> gdb ovm core.NNNN
     

How are benchmarks run automatically?

Benchmarks are run on cordelia by RTJUnit. To get a better idea of what's going on, check out a copy of RTJUnit from /p/sss/cvs, and take a look at RTJUnit/scripts/. RTJUnit's cron jobs updated themselves from CVS, so any changes that are committed to the cvs tree will become part of the benchmark run within a day or two.


Footnotes

  1. Note the sequence of two cs. These methods should not be confused with constructors named class__0003cinit_0003e_n. See gdb Tutorial for a more complete description of j2c's naming conventions.