Welcome to Linux Knowledge Base and Tutorial
"The place where you learn linux"
No Starch Press

 Create an AccountHome | Submit News | Your Account  

Tutorial Menu
Linux Tutorial Home
Table of Contents

· Introduction to Operating Systems
· Linux Basics
· Working with the System
· Shells and Utilities
· Editing Files
· Basic Administration
· The Operating System
· The X Windowing System
· The Computer Itself
· Networking
· System Monitoring
· Solving Problems
· Security
· Installing and Upgrading
· Linux and Windows

Glossary
MoreInfo
Man Pages
Linux Topics
Test Your Knowledge

Site Menu
Site Map
FAQ
Copyright Info
Terms of Use
Privacy Info
Disclaimer
WorkBoard
Thanks
Donations
Advertising
Masthead / Impressum
Your Account

Communication
Feedback
Forums
Private Messages
Surveys

Features
HOWTOs
News Archive
Submit News
Topics
User Articles
Web Links

Google
Google


The Web
linux-tutorial.info

Who's Online
There are currently, 274 guest(s) and 0 member(s) that are online.

You are an Anonymous user. You can register for free by clicking here

  

HOWTO Home

Current HOWTO: Program-Library-HOWTO


Miscellaneous

5. Miscellaneous

5.1. nm command

The nm(1) command can report the list of symbols in a given library. It works on both static and shared libraries. For a given library nm(1) can list the symbol names defined, each symbol's value, and the symbol's type. It can also identify where the symbol was defined in the source code (by filename and line number), if that information is available in the library (see the -l option).

The symbol type requires a little more explanation. The type is displayed as a letter; lowercase means that the symbol is local, while uppercase means that the symbol is global (external). Typical symbol types include T (a normal definition in the code section), D (initialized data section), B (uninitialized data section), U (undefined; the symbol is used by the library but not defined by the library), and W (weak; if another library also defines this symbol, that definition overrides this one).

If you know the name of a function, but you truly can't remember what library it was defined in, you can use nm's ``-o'' option (which prefixes the filename in each line) along with grep to find the library name. From a Bourne shell, you can search all the libraries in /lib, /usr/lib, direct subdirectories of /usr/lib, and /usr/local/lib for ``cos'' as follows:

nm -o /lib/* /usr/lib/* /usr/lib/*/* \
      /usr/local/lib/* 2> /dev/null | grep 'cos$' 

Much more information about nm can be found in the nm ``info'' documentation locally installed at info:binutils#nm.

5.2. Library constructor and destructor functions

Libraries should export initialization and cleanup routines using the gcc __attribute__((constructor)) and __attribute__((destructor)) function attributes. See the gcc info pages for information on these. Constructor routines are executed before dlopen returns (or before main() is started if the library is loaded at load time). Destructor routines are executed before dlclose returns (or after exit() or completion of main() if the library is loaded at load time). The C prototypes for these functions are:

  void __attribute__ ((constructor)) my_init(void);
  void __attribute__ ((destructor)) my_fini(void);

Shared libraries must not be compiled with the gcc arguments ``-nostartfiles'' or ``-nostdlib''. If those arguments are used, the constructor/destructor routines will not be executed (unless special measures are taken).

5.2.1. Special functions _init and _fini (OBSOLETE/DANGEROUS)

Historically there have been two special functions, _init and _fini that can be used to control constructors and destructors. However, they are obsolete, and their use can lead to unpredicatable results. Your libraries should not use these; use the function attributes constructor and destructor above instead.

If you must work with old systems or code that used _init or _fini, here's how they worked. Two special functions were defined for initializing and finalizing a module: _init and _fini. If a function ``_init'' is exported in a library, then it is called when the library is first opened (via dlopen() or simply as a shared library). In a C program, this just means that you defined some function named _init. There is a corresponding function called _fini, which is called whenever a client finishes using the library (via a call dlclose() that brings its reference count to zero, or on normal exit of the program). The C prototypes for these functions are:

  void _init(void);
  void _fini(void);

In this case, when compiling the file into a ``.o'' file in gcc, be sure to add the gcc option ``-nostartfiles''. This keeps the C compiler from linking the system startup libraries against the .so file. Otherwise, you'll get a ``multiple-definition'' error. Note that this is completely different than compiling modules using the recommended function attributes. My thanks to Jim Mischel and Tim Gentry for their suggestion to add this discussion of _init and _fini, as well as help in creating it.

5.3. Shared Libraries Can Be Scripts

It's worth noting that the GNU loader permits shared libraries to be text files using a specialized scripting language instead of the usual library format. This is useful for indirectly combining other libraries. For example, here's the listing of /usr/lib/libc.so on one of my systems:

/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a )

For more information about this, see the texinfo documentation on ld linker scripts (ld command language). General information is at info:ld#Options and info:ld#Commands, with likely commands discussed in info:ld#Option Commands.

5.4. Symbol Versioning and Version Scripts

Typically references to external functions are bound on an as-needed basis, and are not all bound when the application starts up. If a shared library is out of date, a required interface may be missing; when the application tries to use that interface, it may suddenly and unexpectedly fail.

A solution to this problem are symbol versioning coupled with version scripts. With symbol versioning, the user can get a warning when they start their program if the libraries being used with the application are too old. You can learn more about this from ld manual's descussion of version scripts at http://www.gnu.org/manual/ld-2.9.1/html_node/ld_25.html.

5.5. GNU libtool

If you're building an application that should port to many systems, you might consider using GNU libtool to build and install libraries. GNU libtool is a generic library support script. Libtool hides the complexity of using shared libraries behind a consistent, portable interface. Libtool provides portable interfaces to create object files, link libraries (static and shared), link executables, debug executables, install libraries, install executables. It also includes libltdl, a portability wrapper for dynamically loading programs. For more information, see its documentation at http://www.gnu.org/software/libtool/manual.html

5.6. Removing symbols for space

All the symbols included in generated files are useful for debugging, but take up space. If you need space, you can eliminate some of it.

The best approach is to first generate the object files normally, and do all your debugging and testing first (debugging and testing is much easier with them). Afterwards, once you've tested the program thoroughly, use strip(1) to remove the symbols. The strip(1) command gives you a good deal of control over what symbols to eliminate; see its documentation for details.

Another approach is to use the GNU ld options ``-S'' and ``-s''; ``-S'' omits debugger symbol information (but not all symbols) from the output file, while ``-s'' omits all symbol information from the output file. You can invoke these options through gcc as ``-Wl,-S'' and ``-Wl,-s''. If you always strip the symbols and these options are sufficient, feel free, but this is a less flexible approach.

5.7. Extremely small executables

You might find the paper Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux useful. It describes how to make a truly tiny program executable. Frankly, you shouldn't use most of these tricks under normal circumstances, but they're quite instructive in showing how ELF really works.

5.8. C++ vs. C

It's worth noting that if you're writing a C++ program, and you're calling a C library function, in your C++ code you'll need to define the C function as extern "C". Otherwise, the linker won't be able to locate the C function. Internally, C++ compilers ``mangle'' the names of C++ functions (e.g., for typing purposes), and they need to be told that a given function should be called as a C function (and thus, not have its name mangled).

If you're writing a program library that could be called from C or C++, it's recommended that you include 'extern "C"' commands right in your header files so that you do this automatically for your users. When combined with the usual #ifndef at the top of a file to skip re-executing header files, this means that a typical header file usable by either C or C++ for some header file foobar.h would look like this:

/* Explain here what foobar does */

#ifndef FOOBAR_H
#define FOOBAR_H

#ifdef __cplusplus
extern "C" {
#endif

 ... header code for foobar goes here ...

#ifdef  __cplusplus
}
#endif
#endif

5.9. Speeding up C++ initialization

The KDE developers have noticed that large GUI C++ applications can take a long time to start up, in part due to its needing to do many relocations. There are several solutions to this. See Making C++ ready for the desktop (by Waldo Bastian) for more information.

5.10. Linux Standard Base (LSB)

The goal of the Linux Standard Base (LSB) project is to develop and promote a set of standards that will increase compatibility among Linux distributions and enable software applications to run on any compliant Linux system. The project's home page is at http://www.linuxbase.org.

A nice article that summarizes how to develop LSB-compliant applications was published in October 2002, Developing LSB-certified applications: Five steps to binary-compatible Linux applications by George Kraft IV (Senior software engineer, IBM's Linux Technology Center). Of course, you need to write code that only accesses the standardized portability layer if you want your code to be portable. In addition, the LSB provides some tools so that application writers of C/C++ programs can check for LSB compliance; these tools use some capabilities of the linker and special libraries to do these checks. Obviously, you'll need to install the tools to do these checks; you can get them from the LSB website. Then, simply use the "lsbcc" compiler as your C/C++ compiler (lsbcc internally creates a linking environment that will complain if certain LSB rules aren't followed):

 $ CC=lsbcc make myapplication
  (or)
 $ CC=lsbcc ./configure; make myapplication 
You can then use the lsbappchk program to ensure that the program only uses functions standardized by the LSB:
 $ lsbappchk myapplication
You also need to follow the LSB packaging guidelines (e.g., use RPM v3, use LSB-conforming package names, and for add-on software must install in /opt by default). See the article and LSB website for more information.


The Linux Tutorial completely respects the rights of authors and artists to decide for themselves if and how their works can be used, independent of any existing licenses. This means if you are the author of any document presented on this site and do no wish it to be displayed as it is on this site or do not wish it to be displayed at all, please contact us and we will do our very best to accommodate you. If we are unable to accommodate you, we will, at your request, remove your document as quickly as possible.

If you are the author of any document presented on this site and would like a share of the advertising revenue, please contact us using the standard Feedback Form.


  
Help us cut cost by not downloading the whole site!
Use of automated download sofware ("harvesters") such as wget, httrack, etc. causes the site to quickly exceed its bandwidth limitation and therefore is expressedly prohibited. For more details on this, take a look here

Login
Nickname

Password

Security Code
Security Code
Type Security Code


Don't have an account yet? You can create one. As a registered user you have some advantages like theme manager, comments configuration and post comments with your name.

Help if you can!


Amazon Wish List

Did You Know?
The Linux Tutorial welcomes your suggestions and ideas.


Friends



Tell a Friend About Us

Bookmark and Share



Web site powered by PHP-Nuke

Is this information useful? At the very least you can help by spreading the word to your favorite newsgroups, mailing lists and forums.
All logos and trademarks in this site are property of their respective owner. The comments are property of their posters. Articles are the property of their respective owners. Unless otherwise stated in the body of the article, article content (C) 1994-2013 by James Mohr. All rights reserved. The stylized page/paper, as well as the terms "The Linux Tutorial", "The Linux Server Tutorial", "The Linux Knowledge Base and Tutorial" and "The place where you learn Linux" are service marks of James Mohr. All rights reserved.
The Linux Knowledge Base and Tutorial may contain links to sites on the Internet, which are owned and operated by third parties. The Linux Tutorial is not responsible for the content of any such third-party site. By viewing/utilizing this web site, you have agreed to our disclaimer, terms of use and privacy policy. Use of automated download software ("harvesters") such as wget, httrack, etc. causes the site to quickly exceed its bandwidth limitation and are therefore expressly prohibited. For more details on this, take a look here

PHP-Nuke Copyright © 2004 by Francisco Burzi. This is free software, and you may redistribute it under the GPL. PHP-Nuke comes with absolutely no warranty, for details, see the license.
Page Generation: 0.14 Seconds