Creation Zone

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Wednesday, 14 June 2006

Sun Studio: symbol collisions revisited

Posted on 02:02 by Unknown
Even though my blog entry C/C++: global const variables, symbol collisions & symbolic scoping and article Reducing Symbol Scope with Sun Studio C/C++ discuss about techniques to avoid symbol collisions in great length with examples, apparently they failed to provide a simple way to detect if the anomalous behavior is due to a symbol conflict. This blog entry tries to fill that gap with the help of Sun Studio debugger dbx and Solaris' link-edit tracing facility.

Let us start with the obligatory example first.
 % cat dummy.c
 #include <stdio.h>

 void compare (int x, int y)
 {
  printf("\ndummy.c: compare(int, int)");
 }

 void Comparable (int a, int b)
 {
  printf("\nNext line should print \"dummy.c: compare(int, int)\". It you see something
  else, it must be a symbol collision.");
  compare (a, b);
 }

 % cc -G -o libdummy.so dummy.c

 % cat thirdparty.c
 #include <stdio.h>

 int compare (char x, char y)
 {
  printf("\nthirdparty.c: compare(char, char)");
  return (0);
 }

 % cc -G -o lib3rdparty.so thirdparty.c
 % export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

 % cat test.c
 void Comparable(int, int);

 int main()
 {
  Comparable(1, 2);
  return (0);
 }

 % cc -o test -l3rdparty -ldummy test.c

 % ./test

 Next line should print "dummy.c: compare(int, int)". It you see something else, it must be a symbol collision.
 thirdparty.c: compare(char, char)

1) Using dbx to detect symbol collision
 % dbx test
 For information about new features see `help changes'
 To remove this message, put `dbxenv suppress_startup_message 7.5' in your .dbxrc
 Reading test
 Reading ld.so.1
 Reading lib3rdparty.so
 Reading libdummy.so

 Reading libc.so.1

 (dbx) stop in compare
 More than one identifier 'compare'.
 Select one of the following:
  0) Cancel
  1) `lib3rdparty.so`compare
  2) `libdummy.so`compare
  a) All
 > a
 dbx: warning: 'compare' has no debugger info -- will trigger on first instruction
 dbx: warning: 'compare' has no debugger info -- will trigger on first instruction
 Will create handlers for all 2 hits
 (2) stop in compare
 (3) stop in compare

 (dbx) run
 Running: test
 (process id 4404)

 Next line should print "dummy.c: compare(int, int)". It you see something else, it must be a symbol collision.stopped in compare at 0xd27a0240
 0xd27a0240: compare : pushl %ebp

 (dbx) where
 =>[1] compare(0x1, 0x2), at 0xd27a0240
  [2] Comparable(0x1, 0x2), at 0xd27702d9
  [3] main(0x1, 0x8047324, 0x804732c), at 0x80506f8
proc -map shows the list of objects loaded with addresses.
 (dbx) proc -map
 Loadobject mappings for Process ID: 4404
 0x08050000 /export/home/techno/C/test
 0xd27a0000 /export/home/techno/C/lib3rdparty.so
 0xd2770000 /export/home/techno/C/libdummy.so
 0xd2690000 /lib/libc.so.1
 0xd27c8000 /lib/ld.so.1 [LM_ID_LDSO]

From the above mappings, it appears that the symbol compare was bound to the definition in lib3rdparty.so. However it should really be bound to the definition in libdummy.so.

Other way to check the mappings is by getting the process id with proc -pid command, and using pmap <pid> command in dbx environment.
 (dbx) proc -pid
 4404

 (dbx) pmap 4404
 4404: /export/home/techno/C/test
 08046000 8K rwx-- [ stack ]
 08050000 4K r-x-- /export/home/techno/C/test
 08060000 4K rwx-- /export/home/techno/C/test
 D261E000 384K rw--- [ anon ]
 D2680000 24K rwx-- [ anon ]
 D2690000 764K r-x-- /lib/libc.so.1
 D275F000 24K rw--- /lib/libc.so.1
 D2765000 8K rw--- /lib/libc.so.1
 D2770000 4K r-x-- /export/home/techno/C/libdummy.so
 D2780000 4K rwx-- /export/home/techno/C/libdummy.so
 D2790000 4K rwx-- [ anon ]
 D27A0000 4K r-x--  /export/home/techno/C/lib3rdparty.so
 D27B0000 4K rwx-- /export/home/techno/C/lib3rdparty.so
 D27BA000 4K rwxs- [ anon ]
 D27C8000 140K r-x-- /lib/ld.so.1
 D27FB000 4K rwx-- /lib/ld.so.1
 D27FC000 8K rwx-- /lib/ld.so.1
  total 1396K

The following outputs in dbx env. confirm that the symbol compare was actually resolved in lib3rdparty.so rather than libdummy.so.
 (dbx) which compare
 `lib3rdparty.so`compare
which command prints the full qualification of a given name.
 
(dbx) scopes
 Function compare
 File "(unknown OF)"
 Loadobject /export/home/techno/C/lib3rdparty.so
The scopes command prints a list of active scopes.
 (dbx) status
 *(2) stop in compare
  (3) stop in compare
The status prints the stop breakpoints in effect. In the above output we do not know which compare belong to which library. -s option of status will show the information we need.
 (dbx) status -s
  stop in `lib3rdparty.so`#compare
  stop in `libdummy.so`#compare

 2) Using Solaris' link-edit tracing to detect symbol collision

Setting the run-time linker (ld.so.1) env variable LD_DEBUG to the token bindings causes the run-time linker to show the binding of a symbol reference to a symbol definition. Usually the output from run-time linker will be overwhelming if the application is big with a handful of symbols. By default, all this output will be displayed on stdout; so, it might be a little inconvenient to read all the output on stdout. However the tracing data from run-time linker can be redirected to a file using LD_DEBUG_OUTPUT env variable as shown below.

eg.,
 % export LD_DEBUG=bindings
 % export LD_DEBUG_OUTPUT=/tmp/bindings.log

 % ./test
 Next line should print "dummy.c: compare(int, int)". It you see something else, it must be a symbol collision.
 thirdparty.c: compare(char, char)

 % grep compare /tmp/bindings.log.0443*
 /tmp/bindings.log.04436:04436: binding file=./libdummy.so to file=./lib3rdparty.so: symbol `compare'
Observe that the call to symbol (function or method) compare in libdummy.so was resolved in lib3rdparty.so. It confirms the symbol conflict. This problem arises when the symbols are left in default global scope. Use elfdump tool to check the scope and attribute of the symbol of interest (compare in this example).
 % /usr/ccs/bin/elfdump -sN.symtab libdummy.so | grep compare
  [40] 0x00000280 0x00000027 FUNC GLOB D 0 .text compare

 % /usr/ccs/bin/elfdump -sN.symtab lib3rdparty.so | grep compare
  [41] 0x00000240 0x00000036 FUNC GLOB D 0 .text compare

Symbols with global default scope are always vulnerable to symbol conflicts, as seen in the above example. The primary reason being any one can interpose upon these global default symbols. To prevent others from interposing on the symbols that are completely useless outside the defining component (executables or shared objects), make them protected with Sun Studio's -xldscope=symbolic compiler option or __symbolic attribute. Note that these language extensions were introduced in Sun Studio 8. Refer to Reducing Symbol Scope with Sun Studio C/C++ article for detailed information about global, symbolic scopes and also about the linker scoping language extension. If you are using any older compiler, use -Bsymbolic linker option to build your executables and shared libraries there by making the symbols protected.

eg.,
 % cc -G -o libdummy.so -xldscope=symbolic dummy.c

 % /usr/ccs/bin/elfdump -sN.symtab libdummy.so | grep compare
  [40] 0x00000280 0x00000027 FUNC GLOB P 0 .text compare

 % cc -G -o lib3rdparty.so -xldscope=symbolic thirdparty.c

 % /usr/ccs/bin/elfdump -sN.symtab lib3rdparty.so | grep compare
  [41] 0x00000240 0x00000036 FUNC GLOB P 0 .text compare

 % cc -o test -l3rdparty -ldummy test.c

 % ./test

 Next line should print "dummy.c: compare(int, int)". It you see something else, it must be a symbol collision.
 dummy.c: compare(int, int)

Note that the compiler option -xldscope=symbolic and the linker option -Bsymbolic make all the symbols protected - so, it is not possible for others to interpose upon the symbols of such libraries or executables. For some reason if you have to leave some symbols in global default scope, use __symbolic specifier for those symbols which must be protected from interposers.

eg.,
 % cat dummy.c
 #include <stdio.h>

 __symbolic void compare (int x, int y)
 {
  printf("\ndummy.c: compare(int, int)");
 }

 void Comparable (int a, int b)
 {
  printf("\nNext line should print \"dummy.c: compare(int, int)\". It you see something
  else, it must be a symbol collision.");
  compare (a, b);
 }

 % cc -G -o libdummy_.so dummy.c

 % /usr/ccs/bin/elfdump -sN.symtab libdummy_.so | grep -i compar
  [40] 0x00000280 0x00000027 FUNC GLOB P 0 .text compare
  [45] 0x000002b0 0x00000037 FUNC GLOB D 0 .text Comparable

Observe that the symbol compare is protected (although global in scope); and hence cannot be overridden by another global symbol with name compare. However Comparable can still be overridden by a different implementation, due to its global default scope.

Just to make sure that the symbol was bound to the definition in the right library, you can check the mappings, scope etc., again with dbx. Link-edit tracing won't show any binding information when it gets resolved within the same library.
_______________
Technorati tags: Sun Studio | Solaris | linker | Programming
Email ThisBlogThis!Share to XShare to Facebook
Posted in | No comments
Newer Post Older Post Home

0 comments:

Post a Comment

Subscribe to: Post Comments (Atom)

Popular Posts

  • *nix: Workaround to cannot find zipfile directory in one of file.zip or file.zip.zip ..
    Symptom: You are trying to extract the archived files off of a huge (any file with size > 2 GB or 4GB, depending on the OS) ZIP file with...
  • JDS: Installing Sun Java Desktop System 2.0
    This document will guide you through the process of installing JDS 2.0 on a PC from integrated CDROM images Requirements I...
  • Linux: Installing Source RPM (SRPM) package
    RPM stands for RedHat Package Manager. RPM is a system for installing and managing software & most common software package manager used ...
  • Solaris: malloc Vs mtmalloc
    Performance of Single Vs Multi-threaded application Memory allocation performance in single and multithreaded environments is an important a...
  • C/C++: Printing Stack Trace with printstack() on Solaris
    libc on Solaris 9 and later, provides a useful function called printstack , to print a symbolic stack trace to the specified file descripto...
  • Installing MySQL 5.0.51b from the Source Code on Sun Solaris
    Building and installing the MySQL server from the source code is relatively very easy when compared to many other OSS applications. At least...
  • Oracle Apps on T2000: ORA-04020 during Autoinvoice
    The goal of this brief blog post is to provide a quick solution to all Sun-Oracle customers who may run into a deadlock when a handful of th...
  • Siebel Connection Broker Load Balancing Algorithm
    Siebel server architecture supports spawning multiple application object manager processes. The Siebel Connection Broker, SCBroker, tries to...
  • 64-bit dbx: internal error: signal SIGBUS (invalid address alignment)
    The other day I was chasing some lock contention issue with a 64-bit application running on Solaris 10 Update 1; and stumbled with an unexpe...
  • Oracle 10gR2/Solaris x64: Fixing ORA-20000: Oracle Text errors
    First, some facts: * Oracle Applications 11.5.10 (aka E-Business Suite 11 i ) database is now supported on Solaris 10 for x86-64 architectur...

Categories

  • 80s music playlist
  • bandwidth iperf network solaris
  • best
  • black friday
  • breakdown database groups locality oracle pmap sga solaris
  • buy
  • deal
  • ebiz ebs hrms oracle payroll
  • emca oracle rdbms database ORA-01034
  • friday
  • Garmin
  • generic+discussion software installer
  • GPS
  • how-to solaris mmap
  • impdp ora-01089 oracle rdbms solaris tips upgrade workarounds zombie
  • Magellan
  • music
  • Navigation
  • OATS Oracle
  • Oracle Business+Intelligence Analytics Solaris SPARC T4
  • oracle database flashback FDA
  • Oracle Database RDBMS Redo Flash+Storage
  • oracle database solaris
  • oracle database solaris resource manager virtualization consolidation
  • Oracle EBS E-Business+Suite SPARC SuperCluster Optimized+Solution
  • Oracle EBS E-Business+Suite Workaround Tip
  • oracle lob bfile blob securefile rdbms database tips performance clob
  • oracle obiee analytics presentation+services
  • Oracle OID LDAP ADS
  • Oracle OID LDAP SPARC T5 T5-2 Benchmark
  • oracle pls-00201 dbms_system
  • oracle siebel CRM SCBroker load+balancing
  • Oracle Siebel Sun SPARC T4 Benchmark
  • Oracle Siebel Sun SPARC T5 Benchmark T5-2
  • Oracle Solaris
  • Oracle Solaris Database RDBMS Redo Flash F40 AWR
  • oracle solaris rpc statd RPC troubleshooting
  • oracle solaris svm solaris+volume+manager
  • Oracle Solaris Tips
  • oracle+solaris
  • RDC
  • sale
  • Smartphone Samsung Galaxy S2 Phone+Shutter Tip Android ICS
  • solaris oracle database fmw weblogic java dfw
  • SuperCluster Oracle Database RDBMS RAC Solaris Zones
  • tee
  • thanksgiving sale
  • tips
  • TomTom
  • windows

Blog Archive

  • ►  2013 (16)
    • ►  December (3)
    • ►  November (2)
    • ►  October (1)
    • ►  September (1)
    • ►  August (1)
    • ►  July (1)
    • ►  June (1)
    • ►  May (1)
    • ►  April (1)
    • ►  March (1)
    • ►  February (2)
    • ►  January (1)
  • ►  2012 (14)
    • ►  December (1)
    • ►  November (1)
    • ►  October (1)
    • ►  September (1)
    • ►  August (1)
    • ►  July (1)
    • ►  June (2)
    • ►  May (1)
    • ►  April (1)
    • ►  March (1)
    • ►  February (1)
    • ►  January (2)
  • ►  2011 (15)
    • ►  December (2)
    • ►  November (1)
    • ►  October (2)
    • ►  September (1)
    • ►  August (2)
    • ►  July (1)
    • ►  May (2)
    • ►  April (1)
    • ►  March (1)
    • ►  February (1)
    • ►  January (1)
  • ►  2010 (19)
    • ►  December (3)
    • ►  November (1)
    • ►  October (2)
    • ►  September (1)
    • ►  August (1)
    • ►  July (1)
    • ►  June (1)
    • ►  May (5)
    • ►  April (1)
    • ►  March (1)
    • ►  February (1)
    • ►  January (1)
  • ►  2009 (25)
    • ►  December (1)
    • ►  November (2)
    • ►  October (1)
    • ►  September (1)
    • ►  August (2)
    • ►  July (2)
    • ►  June (1)
    • ►  May (2)
    • ►  April (3)
    • ►  March (1)
    • ►  February (5)
    • ►  January (4)
  • ►  2008 (34)
    • ►  December (2)
    • ►  November (2)
    • ►  October (2)
    • ►  September (1)
    • ►  August (4)
    • ►  July (2)
    • ►  June (3)
    • ►  May (3)
    • ►  April (2)
    • ►  March (5)
    • ►  February (4)
    • ►  January (4)
  • ►  2007 (33)
    • ►  December (2)
    • ►  November (4)
    • ►  October (2)
    • ►  September (5)
    • ►  August (3)
    • ►  June (2)
    • ►  May (3)
    • ►  April (5)
    • ►  March (3)
    • ►  February (1)
    • ►  January (3)
  • ▼  2006 (40)
    • ►  December (2)
    • ►  November (6)
    • ►  October (2)
    • ►  September (2)
    • ►  August (1)
    • ►  July (2)
    • ▼  June (2)
      • Ubuntu 6.06: setting up the root password
      • Sun Studio: symbol collisions revisited
    • ►  May (4)
    • ►  April (5)
    • ►  March (5)
    • ►  February (3)
    • ►  January (6)
  • ►  2005 (72)
    • ►  December (5)
    • ►  November (2)
    • ►  October (6)
    • ►  September (5)
    • ►  August (5)
    • ►  July (10)
    • ►  June (8)
    • ►  May (9)
    • ►  April (6)
    • ►  March (6)
    • ►  February (5)
    • ►  January (5)
  • ►  2004 (36)
    • ►  December (1)
    • ►  November (5)
    • ►  October (12)
    • ►  September (18)
Powered by Blogger.

About Me

Unknown
View my complete profile