Date of this edition: August 17, 2007
This note describes compatibility issues between QNX Momentics 6.3 and 6.2.1:
You can find the latest version of this document on our website: http://www.qnx.com/.
To switch between building QNX Neutrino 6.2.1 and QNX Neutrino 6.3 applications using the Momentics IDE:
The IDE operates independently of the environment variables used to locate files on the development host.
QNX Momentics 6.3 uses these environment variables to locate files on the host machine:
The qconfig utility automatically sets these variables according to the version of QNX Momentics that you specified. It also modifies the search path so that you use the binaries from the version you selected. For more information, see:
Under Windows, you can launch the Configuration utility from the Start menu to select which version of QNX Momentics to use. This utility automatically sets these variables based on the version you select. For more information, see QWinCfg in the Utilities Reference.
In general, C applications compiled with 6.2.1 will run under 6.3. They shouldn't be affected by anything other than the tools-related issues. You might have to update drivers and resource managers. For more information, see:
We have moved to new versions of the Dinkum library and compiler:
|C++ library||OS version|
|libcpp.so.3||6.3 (compiled with GCC 2.95.3)|
|libcpp.so.4||6.3 (compiled with GCC 3.3.5)|
Note also that the default C++ libraries have moved from the common library directory $QNX_TARGET/CPU/lib to the GCC version subdirectory. For example, the x86 libcpp.so for GCC 3.3.5 is now:
$QNX_TARGET/x86/lib/gcc/3.3.5/libcpp.so --> ../../libcpp.so.4
A C++ application compiled with 6.3 must run with the 6.3 version of the C++ library.
Any 6.2.1 binaries will still run, but will require the 6.2.1 version of the C++ library (libcpp.so.2) to reside on the target system.
|GCC 2.95.3 (from 6.2.1 or 6.3) and GCC 3.3.5 use different C++ ABIs and have different name mangling. As a result, you can't link C++ binaries (objects, executables, libraries) built with GCC 2.95.3 with binaries built with GCC 3.3.5.|
QNX Momentics 6.3 has some new directories for C++ header files:
If you use qcc, you shouldn't have to change anything because the configuration files include these directories. If you create your own Makefiles, and you aren't using qcc, then you should modify them to look in these directories for header files.
Workaround: Rebuild the startup binary using 6.3. The resulting startup will work with both 6.2.1 and 6.3.
The 6.2 GCC incorrectly changed the alignments of long longs from 4 to 8 bytes on those platforms whenever Neutrino system headers were used. This violates the ABI for those architectures; it has been fixed in 6.3.0.
For ARM, SH4, and, X86 architectures:
Drivers created with the 6.2.1 version of the following DDKs should be compatible with 6.3:
We don't guarantee that drivers created with the 6.2.1 version of the following DDKs are compatible with 6.3:
ls -l /lib/dll/npm-qnet.so
To use the original Qnet, make npm-qnet.so a symbolic link to npm-qnet-compat.so instead of to npm-qnet-l4_lite.so.
If you're using the new lightweight Qnet, a network driver developed with 6.2 could malfunction because the assignment of the bits in the flags field of the npkt_t structure has changed. See _NPKT_ORG_MASK and _NPKT_SCRATCH_MASK in <sys/io-net.h>.
The driver can use the eight most significant bits while it's processing a packet. The driver shouldn't make assumptions about the state of these bits when it receives a packet from the upper layers.
The next four most significant bits are for the use of the originator of a packet. The driver can use these flags for packets being sent upstream. If a packet didn't originate with the driver, the driver must not alter these flags.
We recommended you update the drivers to use the latest Network DDK structure. For more information, see the Network DDK documentation.
If your applications set Pt_LIST_INACTIVE, change them to set Pt_BLOCKED in the widget's Pt_ARG_FLAGS. If you don't, an inactive list will become active and might get a horizontal scrollbar.
The Photon Application Builder automatically converts the flags for you.
In 6.3, dinit now creates long filenames by default. You can disable support for long filenames by specifying the -N option. (Ref# 17642)
|This is the reverse of the behavior of 6.2.1; the -N option formerly enabled support for long filenames.|
For more information about long filenames, see the description of the QNX 4 filesystem in the Working with Filesystems chapter of the Neutrino User's Guide.
Timeouts for clnt_broadcast() have changed. In 6.2 and earlier, timeout and retransmission occurs at 4 seconds and increases by 2 seconds for every timeout after that to a max of 14-second timeouts, resulting in 6 retransmissions.
In 6.3, timeout and retransmission occurs at 4 seconds and doubles after that to a max of 8 seconds, resulting in 2 retransmissions. You can alter timeout values by calling the lower-level call rpc_broadcast_exp().
The value of FD_SETSIZE has changed from 32 to 256. This affects the size of the fd_set objects that you pass to select().
This means that by default the highest allowable fd number for FD_SET(fd, &set) is 255.
Any use of fd_set within data structures will therefore cause a change in structure size, so you should do a global recompile.
|The global recompile should include all application code, as well as library code that would be referencing fd_set or structures containing fd_set. If you don't recompile, you may see random corruption and crashes.|
To make the value higher, #define FD_SETSIZE before including <sys/select.h>. But make sure this is done consistently throughout your modules.
If you don't want to cause a global compile, you can #define FD_SETSIZE 32 before including <sys/select.h> (or -DFD_SETSIZE=32 on the command line) to set it back to the old size, but make sure this setting is consistently applied to all your code.
QNX Neutrino 6.3 implements the X/Open Largefile Support extensions (see http://en.wikipedia.org/wiki/Large_file_support).
A large file is a regular file whose size is greater than or equal to the previous limit of 2 GB (the maximum size representable in a 32-bit signed integer).
For a discussion on the impact these changes have on application code, and how programmers can access this functionality, see http://wwws.sun.com/software/whitepapers/wp-largefiles/largefiles.pdf. This section gives a brief summary of those documents and attempts to highlight potential issues for application code.
|QNX Neutrino 6.3 doesn't introduce an underlying 64-bit filesystem (the fs-cd, fs-dos, fs-ext2, and fs-qnx4 formats retain 32-bit on-disk fields). It contains extensions to libc that allow for the future existence and use of a 64-bit filesystem.|
A client application can be one of the following:
The libc and filesystem managers (themselves using libc/iofunc) now perform additional checks that prevent such a client from obtaining access to a large file, by failing open(), stat(), readdir(), etc. operations with an EOVERFLOW error.
If necessary, this mode can be explicitly forced by defining _FILE_OFFSET_BITS=32 before including any system headers (for example via CCFLAGS in common.mk). Leaving this symbol undefined is the same as defining it to have the value 32.
This definition causes all filesystem interfaces (such as open()), structures (such as struct dirent and struct stat), and relevant types (such as off_t and ino_t) to be 32-bit. Note that the structures themselves are always sized for 64-bits (for message-passing consistency), but in this mode consist of 32-bit fields and 32-bit *_hi fields for padding where appropriate. Calls to filesystem interfaces such as open(), stat(), etc. link directly to the corresponding open(), stat(), etc. libc routine.
This mode is explicitly forced by defining _FILE_OFFSET_BITS=64 before including any system headers (for example via CCFLAGS in common.mk).
This definition causes all filesystem interfaces (such as open()), structures (such as struct dirent and struct stat), and relevant types (such as off_t and ino_t) to be 64-bit. Note that the structures themselves are always sized for 64-bits (for message-passing consistency), and in this mode the full 64-bit value is accessible. Calls to filesystem interfaces such as open(), stat(), etc. are mapped (transparently, at link time) in the executable to the corresponding open64(), stat64(), etc. libc routine.
This mode is selected by defining _LARGEFILE64_SOURCE=1 before including any system headers (for example via CCFLAGS in common.mk). It doesn't make any sense to also define _FILE_OFFSET_BITS=64 in this case.
This definition causes the explicit 64-bit variants of all filesystem interfaces, structures, and relevant types to be exported into the namespace. For example, open64(), struct stat64, and off64_t. Such an application must also address the programming considerations above and be both safe with, and aware of, large files.
A server (resource manager) may support 32-bit or 64-bit objects. The selection, in addition to any programming considerations discussed above and in the referenced documents, is made at compile-time by the _FILE_OFFSET_BITS and _IOFUNC_OFFSET_BITS defines, before including any system headers.
The libc and iofunc library has been extended to perform additional checks as required by the X/Open Largefile Support specification. In particular, if the client isn't aware of large files, new tests within the library generate appropriate errors. A server using the standard iofunc_open(), iofunc_read_verify(), iofunc_write_verify(), iofunc_space_verify(), and iofunc_lock() routines thus automatically enforce appropriate client access semantics.
Server code should always use iofunc_attr_init() to initialize their internal object state, as this ensures that all fields are fully zeroed. _IO_STAT handling should use iofunc_stat(), to ensure the struct stat response is fully populated. For other functionality not having a default iofunc implementation, such as _IO_READ for directories and certain filesystem-related _IO_DEVCTL codes, the server code itself is responsible for ensuring the data structures are correctly manipulated.
Take care, in servers not compiled with _FILE_OFFSET_BITS=64, to fully populate reply message data structures. For example, a 32-bit struct dirent (used in _IO_READ handling of directories) contains two fields, d_ino_hi and d_offset_hi, which aren't modified by assignment to the 32-bit d_ino and d_offset fields. The resulting uninitialized 64-bit value then fails the range checks that the libc readdir() routine performs for a client that's safe for large files, causing the file entry to be skipped.
There are several solutions to this situation:
memset(dp, 0, sizeof(struct dirent));
#if !defined(_FILE_OFFSET_BITS) || _FILE_OFFSET_BITS == 32 dp->d_ino_hi = 0, dp->d_offset_hi = 0; #endif
A similar situation exists for the struct statvfs response to a DCMD_FSYS_STATVFS devctl(), which contains many 64-bit fields (f_blocks, f_bfree, f_bavail, f_files, f_ffree, and f_favail) or their *_hi components.
One potentially good compilation environment for a 32-bit server is to specify _FILE_OFFSET_BITS=64 and _IOFUNC_OFFSET_BITS=32. This definition causes:
Copyright © 2004-2007, QNX Software Systems GmbH & Co. KG. All rights reserved.