delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/11/07/13:03:29

From: Thomas Demmer <demmer AT LSTM DOT Ruhr-UNI-Bochum DOT De>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: WARNING: linker-error?
Date: Thu, 06 Nov 1997 10:03:42 +0100
Organization: Lehrstuhl fuer Stroemungsmechanik
Lines: 88
Message-ID: <346187EE.2C05B976@LSTM.Ruhr-UNI-Bochum.De>
References: <3461E508 DOT 2CE4 AT jk DOT uni-linz DOT ac DOT at>
NNTP-Posting-Host: c64.lstm.ruhr-uni-bochum.de
Mime-Version: 1.0
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

Roland Exler wrote:
> 
> Hi all,
> 
> programming a bigger project I found the following problem which may be
> a linker-error, but at least a very dangerous thing. It costs me more
> than one day to find the bug.
> 
> The program below crashes with an segmentation fault, if file test.o is
> linked to main, even if (as you see) main calls nothing from test, but
> calls a function with the same name as a variable in test.o. The linker
> seems to resolve the reference to the function 'int enable();' to the
> variable 'int enable;' !!!
> 
> The problem may arise with all variable-names. With enable the problem
> is even more complicated to find, as all file-io as (f)printf calls
> enable() if interrupts are disabled and crashes the program this way. If
> interrupts are not disabled, printf works without problems even if the
> variable enable is declared! In my case, enable was a variable in one
> module, but the program always crashed in other modules.
> 
> Roland
> #################################################################
>   main.cc
> #################################################################
> 
> #include <dos.h>
> 
> int main()
> {
>   disable();
>   enable();
>   return 0;
> }
> 
> ##########################################################################
>   test.cc
> ##########################################################################
> 
> int enable;

Well, I'd rather say it is a feature of ld, not a bug. And
a marvellous example why you should use include files, and
put all global variables into them in the first place. 
ld works like this:
 It crawls through all .o files finding references to external
 symbols and resolves them, as soon as possible.
 After that, it passes through the libs, trying to resolve
 the missing externals. 
 
Your symbol _enable is perfectly resolved by the int enable 
in test.o. So there is really no need to replace it by the
function enable() from libc. What is making things a bit tricky
is that <dos.h> has a prototype for enable(), so the compiler
doesn't need to bark. You could have found the problem if you had
had something like
// globals.h:
#ifndef __globals_h_
#define __globals_h_
extern int enable;
#endif
// globals.c:
int enable;

and put an 
#include "globals.h"
into every source module. Then, you would have got a compiler 
error(?warning) for the multiple definitions of enable.

I'm not deep enough into ld internals to say if there is a chance
for ld to figure out such subtleties, but I think this is a 
tough one. 


-- 
Ciao
Tom

*************************************************************
* Thomas Demmer                                             *
* Lehrstuhl fuer Stroemungsmechanik                         *
* Ruhr-Uni-Bochum                                           *
* Universitaetsstr. 150                                     *
* D-44780  Bochum                                           *
* Tel: +49 234 700 6434                                     *
* Fax: +49 234 709 4162                                     *
* http://www.lstm.ruhr-uni-bochum.de/~demmer                *
*************************************************************

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019