473,396 Members | 2,147 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

How to override standard printf defined in gcc library

Hi,

I am Rahul. We have a complete software written out (with n other shared libraries maintained by various other teams). The shared libraries are loaded at run time by the main executable depending upon what feature user wants to run. All across our code, we are using printf and fprintf to print messages on the screen for the user. Now, we are adding a Graphical interface to our software and require that all such messages are displayed in a separate window inside that Graphical interface (whenever user is running in Graphical mode, else messages should be printed to screen only). For this, we need to overload printf and fprintf in our code. We have a combination of C and C++ code, as well as due to vast code base distributed across teams, it is not possible to replace printf/fprintf in all the code with some other function. So, what we did, we defined our own printf and fprintf functions that look something as follows -

Expand|Select|Wrap|Line Numbers
  1. extern "C" int fprintf (FILE *__restrict __stream,
  2.         __const char *__restrict __format, ...)
  3. {
  4.     va_list args;
  5.  
  6.     va_start(args,__format);
  7.  
  8.     int return_status = 0;
  9.     if (is_gui && (__stream == stdout || __stream == stderr)) {
  10.         return_status = showMessageInGui(NULL, __format, args);
  11.     }
  12.     else {
  13.         return_status = vfprintf(__stream, __format, args);
  14.     }
  15.  
  16.     va_end(args);
  17.     return return_status;
  18. }
  19.  
Above function is defined in main executable (where our main() lies). So, above definition is loaded before fprintf from gcc library is loaded. I guess, no fprintf should be picked from libgcc now.
Above code works fine for following fprintf calls (that pass variable argument list to fprintf) -

fprintf (stdout,"This is a variable argument message - %s\n", "Rahul Jain");

However, for following fprintf call (that is not taking any variable arguments), it seems fprintf from libgcc is getting picked up as then print comes on the screen instead of our Graphical interface window -

fprintf (stdout,"This is a variable argument message - Rahul Jain\n");

I am not sure why this is happening. Is fprintf implemented as macro, such that it is working for case1 and not for case2. Can anybody help.

I would be really greateful if someone can help me and reply as soon as possible, we have a hight priority delivery item and is very critical... Really appreciate your help guys.
Oct 27 '09 #1
9 25431
Banfa
9,065 Expert Mod 8TB
fprintf (and printf) are in the standard C library. This is a static library. You can replace any function in the standard library by writing your own version and compiling it and then linking with the object. The linker will prefer the version in your object file to the version in the library. The library is only used to resolve symbols that have not been resolved in all the object files of the program.

However when a shared library is created all its static symbols would be resolved in its own link stage. In order to get all your output redirected in this way you would need to link every shared object and executable with the file containing the alternate fprintf and printf.

Another option might be to redirect stdout, for instance using freopen, however I am not a Linux guru and do not know if shared libraries use the same output streams as their calling executables or if they have their own copy (which would be a problem with this suggestion).
Oct 27 '09 #2
weaknessforcats
9,208 Expert Mod 8TB
You are not really overloading anything. An overload means two functions have the same name but different argument lists.

Here your printf and fprintf have the same name and argument list but diffrerent guts. This is an override. Unfortunately, C provides no way to prefer your functions to the standard functions since you cannot override functions in C.

Your only solution will be to not use the standard library at all. Instead, since the source code to all the standard functions is publicly available, make a copy of it all, chang the printf and fprintf to be what you your want and then create a new library with a new name. Then recompile and relink all of your C/C++ code.

Lastly, make it a firing offense to use the C standard library directly.

In the long run you will be better off not using C functions at all. Instead there should be a C++ class that does the output for you. You install that class in your C code (which now becomes C++ code) and recompile. You will be totally on C++, your output will always go th the correct place and the notion of a graphical mode would go away.
Oct 27 '09 #3
Hi,

Thanks guys for your replies.. Yes, you people are right that what I want to achieve is actually overriding (and not overloading, i used that term in my question mistakenly). But, it is not exactly an overriding as I am loading libgcc as a shared library. If we look at the way by which the loader resolves various symbols on loading an application, it does something as follows -

1. Load symbols defined and already binded in the executable
2. Load the shared library on which the application depends and then resolve the still undefined symbols in the application.

In my case, loader finds that fprintf/printf are already defined in my executable, so it should not lookup for this function while loading gcc shared library.

It seems to be the case as in case#1 (with variable argument list given to fprintf my own version is getting called). This does not happens for case #2 however.

I have also narrowed down that this issue comes with gcc 4.2.4 and not with gcc 3.4.2.

You can easily reproduce this issue by creating a printf.c and defining your version of fprintf in it and calling it from main (defined in main.c)

Does anyone know if any changes made between gcc 342 and gcc 424 that might be causing this issue, and if there is any workaround to it by some build time flags.

Once again, thanks guys for your replies.
Oct 27 '09 #4
newb16
687 512MB
@weaknessforcats
And then contact company's IP lawyer to determine if you need to release under GPL all of your code or only modified stdlib.
Oct 28 '09 #5
@RahulJain83
I'm doing GCC on Cygwin. You mention a GUI. What is it called, and where do I get it? Many thanks, JonB
Nov 3 '09 #6
Ectara
24
If you are fine with macros, you could #define in one of your main headers to change fprintf and printf to functions that you name, and use the same argument list.

And Jon, I'm not sure of the protocol, but that probably should have gone in a PM.
Nov 3 '09 #7
try using "nm" command ... in linux.. doing "man nm" would say like... it lists all the symbols in the object file.... So what i did.. was... i modified a bit of your code.. and tried using it in my code.. compiled it... and.. used nm <objectfilename> to see.. whtat's the result......

$ nm a.out
<it gave a lot many lines... bt i would like to mention only a few>
08048484 T fprintf
08048460 t frame_dummy
080484f7 T main

0804a020 B stderr@@GLIBC_2.0
0804a040 B stdout@@GLIBC_2.0
U vfprintf@@GLIBC_2.0

for first and second column read man of nm... the third column is what we can see for you query...
as fprintf has been defined in the source code.. so no extra symbol defining.. where to link it has been mentioned... which can be seen in stderr@@GLIBC_2.0 , stdout@@GLIBC_2.0 and vfprintf@@GLIBC_2.0.. which tells the system.. to where to look for this external symbols!!!

I hope.. usign nm can help you in understanding.. what your source code is actually using.. after becoming a object file....

Other useful command can be.. objdump.. which I haven't used... so.. please try it by yourself... and post any reply!! if that was useful in your case!!
Nov 21 '09 #8
weaknessforcats
9,208 Expert Mod 8TB
Keep in mind as you progress in the effort that if things keep getting more and more complicated, you are on the wrong track.

In fact you are on the wrong track.

At some point you will revert to using the printf from C and renaming yours. This is the whol reason static functions were out into C. It was to isolate your name conflicts from the system.

In C++ you use namespaces for this. My printf is MyStuff::printf and this is clearly different from just the C printf. You will need to call MyStuff::printf to get your printf and just printf to get the C standard printf.

I assume there is someone there that knows how to implement a namespace. Otherwise, let me know and I'll go over it here.
Nov 23 '09 #9
RRick
463 Expert 256MB
I tried a similar test on my linux box using g++ 4.2.4 and it works fine for all cases. To test out the C lib fprintf, just change the method's name to xxxfprintf.

This makes me think that there is something missing in your checking for stdout and stderr. I'm not 100% certain, but if something is piped between processeses or copied or whatever, it might act like a stdout, but not be the same stdout.

Expand|Select|Wrap|Line Numbers
  1. #include <stdio.h>
  2. #include <iostream>
  3.  
  4. extern "C" int fprintf( FILE * file, const char * format, ...)
  5. {
  6.     va_list args;
  7.  
  8.     va_start( args, format);
  9.  
  10.     std::string fstr( std::string( "Got It:  ") + format + "\n");
  11.  
  12.     int status =  vfprintf( file, fstr.c_str(), args);
  13.  
  14.     va_end(args);
  15.  
  16.     return status;
  17. }
  18.  
  19.  
  20.  
  21. int main()
  22. {
  23.      fprintf( stdout, "xxx\n");
  24.      fprintf( stdout, "xxx %s\n", "yyy");
  25.      return 0;
Nov 23 '09 #10

Sign in to post your reply or Sign up for a free account.

Similar topics

71
by: Christopher Benson-Manica | last post by:
At what point was the .h dropped from the STL headers? I just had a discussion yesterday with my boss, who said he wanted .h on all the STL includes, despite me protesting that it was not...
41
by: Greenhorn | last post by:
Hi, We see that C is a bit liberal towards non-standard syntax, for e.g. when i tried <printf("string1", "string2 %d", v1);> in Dev-C++, it printed string1 and no error was raised, is this the...
2
by: Luke Wu | last post by:
Hi, I'm finding myself reinventing the wheel too much in my code (because I don't know all the functions available in the Standard library) and would like to purchase a reference like Plauger's...
9
by: kernelxu | last post by:
hi,everybody. I calling function setbuf() to change the characteristic of standsrd input buffer. some fragment of the progrem is: (DEV-C++2.9.9.2) #include <stdio.h> #include <stdlib.h> int...
21
by: Kannan | last post by:
Its been a while I have done pure C programming (I was coding in C++). Is the following function valid according to standard C? int main(int argc, char *argv) { int x; x = 9; printf("Value...
39
by: Jim Showalter | last post by:
Does a hosted implementation require any particular libraries in order to be considered a standard C compiler? -- _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ _/...
2
by: Nishu | last post by:
Hi all, I was under the impression that below code should give errors while compiling, since i'm using same name for macro as well as function. but it didnt give any errors!! Isnt this is...
4
by: MisterE | last post by:
Is there anything in c standard about the operation of file streams etc. in reguards to how they are supposed to act if an over flow occurs. I am trying to work out the correct way to handle files...
126
by: Dann Corbit | last post by:
Rather than create a new way of doing things: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2497.html why not just pick up ACE into the existing standard:...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.