Results 1 to 19 of 19

Thread: Executing C++ before and after main()

  1. #1
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Executing C++ before and after main()

    I'm writing a C++ component that brings some requirements and after intense web browsing I did no find any clue...

    1. How to make some pieces of code called before main() and also static constructors?
    2. How to make some pieces of code called after main() and also static destructors?
    3. How to ensure that this hack is portable?

    Thanks in advance for your help.
    Current Qt projects : QCodeEdit, RotiDeCode

  2. #2
    Join Date
    Jul 2006
    Location
    Catalunya - Spain
    Posts
    117
    Thanks
    16
    Thanked 8 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Executing C++ before and after main()

    Quote Originally Posted by fullmetalcoder View Post
    I'm writing a C++ component that brings some requirements and after intense web browsing I did no find any clue...
    [*]How to make some pieces of code called before main() and also static constructors?[*]How to make some pieces of code called after main() and also static destructors?
    I've made this trick :

    Qt Code:
    1. // GlobalClass.h
    2.  
    3. class GlobalClass
    4. {
    5. static GlobalClass * m_Instance;
    6. public :
    7. GlobalClass();
    8. ~GlobalClass();
    9.  
    10. // here stuff, if needed...
    11. };
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. // GlobalClass.cpp
    2.  
    3. GlobalClass * GlobalClass::m_Instances = 0;
    4.  
    5. GlobalClass::GlobalClass ()
    6. {
    7. // To avoid dlouble execution...
    8. assert ( m_Instance );
    9. m_Instance = this;
    10. // Before main stuff
    11. ...
    12. }
    13.  
    14. GlobalClass::GlobalClass ()
    15. {
    16. m_Instance = 0;
    17. // After main stuff
    18. ...
    19. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. GlobalClass GLOBALSTUFF;
    2.  
    3. int main ( int argc, char *argv[] )
    4. {
    5. // Here your code...
    6. }
    To copy to clipboard, switch view to plain text mode 
    [*]How to ensure that this hack is portable?[/LIST]

    I think that's portable...

    Thanks in advance for your help.
    Not at all, if I hope this was useful for you...

  3. #3
    Join Date
    Aug 2006
    Posts
    83

    Default Re: Executing C++ before and after main()

    This technique is called singleton. U can read more about it here: http://en.wikipedia.org/wiki/Singleton_pattern

  4. #4
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Executing C++ before and after main()

    Quote Originally Posted by jpujolf View Post
    I've made this trick :

    Qt Code:
    1. // GlobalClass.h
    2.  
    3. class GlobalClass
    4. {
    5. static GlobalClass * m_Instance;
    6. public :
    7. GlobalClass();
    8. ~GlobalClass();
    9.  
    10. // here stuff, if needed...
    11. };
    To copy to clipboard, switch view to plain text mode 
    This is very similar to singleton pattern and something used by Qt (apart from the fact that it's probably not thread safe) : Q_GLOBAL_STATIC(TYPE, NAME) macro defined in qtglobal.h

    However it does not solve my problem because it won't be called BEFORE ALL STATIC CONSTRUCTORS of the program and attached libraries...
    Current Qt projects : QCodeEdit, RotiDeCode

  5. #5
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Executing C++ before and after main()

    I'm afraid the answer is simple: You can't do that!
    You have no control over main() - how or when it is executed.
    The point is that you don't call main(), it is the other way around.

    I actually am curious to hear a solution for this.

    What should your component do? Maybe there is another solution.

    Regards

  6. #6
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Executing C++ before and after main()

    I think there should be a solution because Qt someway does it (or are static object used?) to manage object cleanup and things like that... Anyway my component is an application wide memory pool : http://www.qtcentre.org/forum/f-qt-p...age2-6838.html

    My problem, as described in this thread, is that I get unexpected crash when using my custom alloc()/dealloc() functions whereas replacing them by qMalloc()/qFree() works well. One could think that my functions are directly responsible for these segfaults but actually it looks trickier than this because my allocator seems to work quite well and segfaults occur in two precise location only : QMutex::lock() and QMutex::unlock() called on wrong pointers from QReadWriteLock::lock() or QreadWriteLock::unlock()...

    I thus thought that forcing EVERY SINGLE object to be allocated through the pool would solve this but....
    Current Qt projects : QCodeEdit, RotiDeCode

  7. #7
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Executing C++ before and after main()

    Regarding the segfaults:
    Are you allocating from more than one thread.

    The global memory pool should be locked for exclusive access by the current allocating thread ( mem allocation is not atomic ). It is possible, if you use more than one thread, that two threads may try to allocate the same block in the mem pool, resulting in a mem violation -> therefore the segfault.


    Qt most likely uses static objects that are destroyed in the same time (or after ) the QApplication.


    The main function is the application entry point - it is called by the OS when you run a program. You can force something to be called before main, or after main exits.

  8. #8
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Executing C++ before and after main()

    Could we see your custom allocator/deallocator and how you use it? Maybe you can show us where exactly you get the segfaults...

    Regards

  9. #9
    Join Date
    Sep 2006
    Posts
    339
    Thanks
    15
    Thanked 21 Times in 16 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Executing C++ before and after main()

    Well, I dont if I'm correct. I was asked the same question by my friend, How to call display a string before main() and another string after main()...

    Something like
    Qt Code:
    1. int main()
    2. {
    3. cout<<"Love";
    4. }
    To copy to clipboard, switch view to plain text mode 
    Now without touching main() I need to display "I Love You"
    So the solution is something like this
    Qt Code:
    1. class A
    2. {
    3. public:
    4. A(){ cout<< "I"; }
    5. ~A() { cout<<"You"; }
    6. };
    7. A a;
    8. int main()
    9. {
    10. cout<<"Love";
    11. }
    To copy to clipboard, switch view to plain text mode 

    Here 'I' is displayed before main and 'You' after main.. Do you want something like this???

    //I have not tested above code so might be incorrect....

  10. #10
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Executing C++ before and after main()

    Quote Originally Posted by marcel View Post
    Regarding the segfaults:
    Are you allocating from more than one thread.
    AFAIK there shouldn't be ANY thread apart from the main/GUI one in the test case...

    The global memory pool should be locked for exclusive access by the current allocating thread ( mem allocation is not atomic ). It is possible, if you use more than one thread, that two threads may try to allocate the same block in the mem pool, resulting in a mem violation -> therefore the segfault.
    I'm afraid it's trickier than that... When I serialize access to the pool (for both alloc and dealloc) through QMutex I get a deadlock message and the application hangs...

    The main function is the application entry point - it is called by the OS when you run a program. You can force something to be called before main, or after main exits.
    That's not exactly true... For example, under Linux some other functions are called before main and after (mainly things related to global objects and added internally by the compiler but still...). I found an example on the web showing how to do that but it worked only with recent versions of MSVC so I just dropped it. Anyway singleton may help me here because it would ensure that the pool is created as soon as program asks for memory allocation.

    Could we see your custom allocator/deallocator and how you use it? Maybe you can show us where exactly you get the segfaults...
    Sure! But it probably won't help... As far as I investigated, everything is allocated and initialized properly but for some reason the pointer to one of the allocated QReadWriteLock is somewhere decremented by one byte causing the segfault... I don't know where this decrement is done and I've no idea why it occurs when my allocator is used...

    @vermarajeev :
    Your trick will work but there is no way to ensure that A::A() gets called BEFORE ALL OTHER STATIC CTORs and A::~A() AFTER ALL OTHER STATIC DTORs....
    Current Qt projects : QCodeEdit, RotiDeCode

  11. #11
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Executing C++ before and after main()

    Understood.
    Can you give a link to that example you were talking about?

    About the allocator/deallocator: if you don't manage to solve it, you may as well post it, maybe we can find some solution.

    Why don't you use a QMutex instead of a QReadWriteLock?
    In many cases, QReadWriteLock is a direct competitor to QMutex. QReadWriteLock is a good choice if there are many concurrent reads and writing occurs infrequently.
    I believe a QMutex( actually you need two ) is more trustworthy . You could trace the errors easier than with a rw lock.

    Regards

  12. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Executing C++ before and after main()

    Obviously the trick from the beginning of the thread is neither working or portable (the compiler may change the order of calls if it finds it useful).

    A general answer is that you need your own startup code for that. One that doesn't call main() but first executes your code and only then jumps to the starting address of the application (not "main"!). On Linux you could probably use a preload object with a small assembly code that does what I explained, but this certainly won't be portable. A portable solution is hardly doable for an already built application (when you can't substitute the startup code directly yourself).

  13. #13
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Executing C++ before and after main()

    About the allocator/deallocator: if you don't manage to solve it, you may as well post it, maybe we can find some solution.
    I've posted a link to an older version in another thread : http://www.qtcentre.org/forum/f-qt-p...tion-6838.html

    Quote Originally Posted by marcel View Post
    Understood.
    Can you give a link to that example you were talking about?
    Sure!, It's packed with the allocator code

    Why don't you use a QMutex instead of a QReadWriteLock?
    I don't use QReadWriteLock, Qt does...

    I believe a QMutex( actually you need two ) is more trustworthy . You could trace the errors easier than with a rw lock.
    One appears to be enough and is safer because otherwise parallel alloc/dealloc would be allowed which would be quite bad...


    Obviously the trick from the beginning of the thread is neither working or portable (the compiler may change the order of calls if it finds it useful).

    A general answer is that you need your own startup code for that. One that doesn't call main() but first executes your code and only then jumps to the starting address of the application (not "main"!). On Linux you could probably use a preload object with a small assembly code that does what I explained, but this certainly won't be portable. A portable solution is hardly doable for an already built application (when you can't substitute the startup code directly yourself).
    That's what I was thinking about but there does not seem to be a standard and portable way to achieve that...

    OK, that was for the answers! The nice thing is that, after some hard work I've been able to fix it all :
    1. There must have been a problem in the allocator but rewriting its internal functions seems to have fully fixed it
    2. A tricky singleton alternative pattern fixes the problem of prior initialization of the pool before any new call. The only downside is that the size of the pool becomes fixed on compile time... Will do for my purpose so it's not so embarassing after all...
    Only one problem left : QLibrary now refuses to load my plugin... I'll see if it comes from an error of mine or a broken internal...

    Thank you all for your advices.
    Current Qt projects : QCodeEdit, RotiDeCode

  14. #14
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Executing C++ before and after main()

    Quote Originally Posted by fullmetalcoder View Post
    Only one problem left : QLibrary now refuses to load my plugin... I'll see if it comes from an error of mine or a broken internal...
    It was actually a LD_LIBRARY_PATH quirk so everything is fine!

    But (yeah, there MUST always be a but...), there is one trouble left I'm now able to use a memory pool all along the execution with thread safety, pretty good performances and no leak but I get screwed on program end... Due to the way Qt works (many underlying static components and auto object cleanup) I just can't destroy my pool at the end of the main loop or I get a segfault... I tried using a static wrapper object to do it after but it doesn't help. Actually my big problem is that I need to make sure that Qt libs get unloaded/uninitialized before destroying the pool. So we're back to the thread topic : how do I hook some code at a post-main() entry point?

    Just to help you understanding what's going on, here comes a gdb backtrace :
    Program received signal SIGSEGV, Segmentation fault.
    [Switching to Thread -1208957232 (LWP 4905)]
    QMutex::lock (this=0xb7e170e4) at thread/qmutex.cpp:177
    177 thread/qmutex.cpp: No such file or directory.
    in thread/qmutex.cpp
    (gdb) bt
    #0 QMutex::lock (this=0xb7e170e4) at thread/qmutex.cpp:177
    #1 0x0026c7ec in qUnregisterResourceData (version=1, tree=0xbc6620 "", name=0xbc6b20 "", data=0xbc7a60 "")
    at ../../include/QtCore/../../src/corelib/thread/qmutex.h:93
    #2 0x00b86dec in qCleanupResources_qstyle () at .rcc/release-shared/qrc_qstyle.cpp:15616
    #3 0x00b86e0b in __tcf_0 () at .rcc/release-shared/qrc_qstyle.cpp:15619
    #4 0x01022c0c in __cxa_finalize () from /lib/libc.so.6
    #5 0x00706393 in __do_global_dtors_aux () from /usr/local/Trolltech/Qt-4.2.2/lib/libQtGui.so.4
    #6 0x00b86f1c in _fini () from /usr/local/Trolltech/Qt-4.2.2/lib/libQtGui.so.4
    #7 0x0060f0fd in _dl_fini () from /lib/ld-linux.so.2
    #8 0x0102298e in exit () from /lib/libc.so.6
    #9 0x0100d72c in __libc_start_main () from /lib/libc.so.6
    #10 0x080493d1 in _start ()
    (gdb)
    Last edited by fullmetalcoder; 11th May 2007 at 20:50. Reason: spelling error
    Current Qt projects : QCodeEdit, RotiDeCode

  15. #15
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Executing C++ before and after main()

    I've found a very interesting link after some more investigations and web research : http://www-128.ibm.com/developerwork...ux.html#N10083

    There are unfortunately some issues left :
    1. For some reasons (possibly to allow it to make use of shared components), this custom destructor is called before libraries unloading so segfaults still occurs unless I call abort() which is IMHO quite bad, even though harmless...
    2. Using the "standard" _fini() entry point seems to work better since the segfault disappears but any debug output placed in it (via printf, qDebug, whatever...) does not show up and I suppose that in this case libraries are not unloaded at all because this entry point is AFAIK, just like new/delete operators, a substitution to existing symbols available in C/C++ runtime...
    3. How portable is this solution???
    Current Qt projects : QCodeEdit, RotiDeCode

  16. #16
    Join Date
    Feb 2006
    Posts
    91
    Thanks
    4
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Executing C++ before and after main()

    Did you guys find the answer ? ok this may not be useful for you but I think sometimes ago I was trying to achieve "Reflection" in C++. I noticed something strange through some of the examples, it was the way a particular line of code has to be written for it to run before the main...


    #include<iostream>

    using namespace std;

    int myfunc()
    {
    cout<<"hello world"<<endl;
    return 1;
    }
    class myClass{

    public:
    static int func(){ cout << "Inside static function"<<endl;
    return 1;
    }
    myClass(){ cout<<"inside my class constructor"<<endl; }
    ~myClass();

    };

    static int s = myClass::func();
    static int n = myfunc();


    int main(int argc,char** argv)
    {
    cout << "inside main"<<endl;
    return 0;
    }
    static int g = myfunc();
    if you don't use static then the code won't compile..btw how do you call a function right after main..becuase main is the point your program will be starting and after main ends the program ends..so guess..I don't have a answer to that..it does appear to be calling after main but it calls myfunc() twice before entering main...We can call static functions or global functions but it *has* to return something and we need to put it in a static variable....if anyone can explain why we need to do this..that would be great...i just know it works this way..

    However, I actually don't have much idea about the seg faults that you guys are talking about....
    Humans make mistake because there is really NO patch for HUMAN STUPIDITY

  17. #17
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Executing C++ before and after main()

    If you want to call something after main, you may use atexit().

  18. #18
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Executing C++ before and after main()

    Quote Originally Posted by wysota View Post
    If you want to call something after main, you may use atexit().
    That's how gcc registers function declared with __attribute__((destructor)) and it's actually not what I want because my tests showed that such a function will be called before shared libs unloading, resulting in segfaults when Qt tries to do its cleanup...
    Current Qt projects : QCodeEdit, RotiDeCode

  19. #19
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Executing C++ before and after main()

    I was referring to what my preposter said, not to your situation, I know it's different.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.