Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
General
GeneralPortable MacsHardwareNetworking
Applications
Mac ApplicationsEudoraFirefox / MozillaInternet ExplorerOutlook ExpressMS OfficeEntourageExcelPowerPointWordVirtual PCMedia PlayerOther MS Products
Programming
Mac ProgrammingCodeWarriorPerl
Country Specific
Australian Mac GroupUK Mac Group

Mac Forum / Programming / CodeWarrior / February 2004



Tip: Looking for answers? Try searching our database.

comp.sys.mac.programmer.codewarrior

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Peter Paulus - 17 Feb 2004 09:11 GMT
Hello all,

I used to have a CodeWarrior 8.3 MacOS 9.2 Shared Library project where I redirected std::cout, and std::err to a custom class, by replacing it's streambuf with rdbuf(). The custom class inherits from std::streambuf and overrides the sync() and overflow() methods. Thus everything that got inserted into std::cout was redirected to my class that displayed it appropriately.

Recently I changed over to a bundle package, MacOS X and CodeWarrior 9.1. Now, whenever I insert something in the outputstream std::cout, I get a read access failure in if (os_.good()) with the follwoing callstack:

QuarkXPress 0x00003800 (PPC)
QuarkXPress 0x00003980 (PPC)
QuarkXPress 0x00482604 (PPC)
QuarkXPress 0x000164B0 (PPC)
QuarkXPress 0x003BB738 (PPC)
QuarkXPress 0x00530FD0 (PPC)
QuarkXPress 0x00530A3C (PPC)
QuarkXPress 0x0052FF08 (PPC)
QuarkXPress 0x0052F69C (PPC)
QuarkXPress 0x0052BBFC (PPC)
QuarkXPress 0x0052DB24 (PPC)
QuarkXPress 0x00526C30 (PPC)
QuarkXPress 0x00526E44 (PPC)
Cougar::setup_callback(xtsetuprec*)
xpress::xtensions::cougar::ConsoleWAP::ConsoleWAP(long, long)
std& std::operator<<<std, char_traits<char> >(basic_ostream<char, std>, basic_ostream, const char*)
std::ostream::sentry::sentry(std::ostream&)
std::ostream::flush()
std::ostream::sentry::sentry(std::ostream&)

I suspect it has something to do with the std::cout not being initialized properly. As far as I know __initialize() took care of that on the MacOS 9 Shared Library. In bundle1.o I cannot find a corresponding call.

All I can find is a source iostream.cpp that contains the definition of std::cout and it's companions.

Can somebody point me in the right direction to solve this issue?

With kind regards,
Peter Paulus
MW Ron - 17 Feb 2004 16:11 GMT
>Hello all,
>
[quoted text clipped - 37 lines]
>
>Can somebody point me in the right direction to solve this issue?

Yeah for bundles you need to set the initialization your self,  in the
linker settings be sure to add the init entry point  the main entry
point is just a suggestion but the init entry point will be enforced.

See if that doesn't work.  If not let us know.

Ron

Signature

Metrowerks, maker of CodeWarrior   -  "Software Starts Here"  
Ron Liechty - MWRon@metrowerks.com - <http://www.metrowerks.com>

Peter Paulus - 19 Feb 2004 16:18 GMT
Hello Ron,

Thank you for answering my question twice. I posted the message to soon
and then tried to correct the subject-field. Sorry about that.

I've been trying to find the correct static initialization function for
C++ objects in a MacOS X Bundle Package, but have been unable to find one.

Disassembling /usr/lib/crt1.o I came up with _call_mod_init_funcs. This
object-file is used for applications.

Disassembling /usr/lib/dylib1.o I came up with __initialize_Cplusplus.
This object-file is used for shared libraries.

Disassembling /usr/lib/bundle1.o seems to have no initialization
function. This object-file is used for Bundle Packages. It is the one I
use in this project.

I link against 'MSL_All_Mach-O_D.lib' and 'MSL_Runtime_Mach-O_D.lib'.
The frameworks 'System' and 'Carbon' are included in the project.

Next I've seen functions like
__sinit_/ConsoleWAP.cpp
__register_global_object
__mod_init_func
__ZSt20__msl_ios_base_ninit
__ZSt20__msl_ios_base_winit

when disassembling my ConsoleWAP.cpp.

But whatever I specify at the Init Entry Point in the linker panel, I
get a warning:

Only dynamic libraries and frameworks support initialization (init
routine '_initialize_Cplusplus' ignored.)

And a link-error:
undefined _initialize_Cplusplus

I've tried inserting something into std::cout before it is redirected to
my custom class. This gives the same result.

I've read (parts of) the MachORuntime.pdf from Apple. On page 16 they
mention the static initializers for C++ objects in /usr/lib/crt1.o.

On page 111 /usr/lib/bundle1.o is mentioned. But nothing is said about
the static C++ initializers.

Would you be so kind as to tell me what initialization function can be
used to initialize std::cout (and others) correctly.

With kind regards,
Peter Paulus

>>Hello all,
>>
[quoted text clipped - 45 lines]
>
> Ron
Howard Hinnant - 19 Feb 2004 20:28 GMT
> Would you be so kind as to tell me what initialization function can be
> used to initialize std::cout (and others) correctly.

Try constructing an object of type:  std::ios_base::Init

#include <ios>

int main()
{
   std::ios_base::Init construct_streams;
}

-Howard
Peter Paulus - 20 Feb 2004 10:51 GMT
Hello Howard,

Thank you for your suggestion. I've changed my code accordingly. Tracing
into std::ios_base::Init::Init() and then __nInit::__nInit(), I see the
following.

__nInit::ninit_cnt_s equals 13 the first time I reach that codepoint.
Next the block guarded by

if (ninit_cnt_s == 0)
{
  new (&cin)istream(&fin);
  new (&cout)ostream(&fout);
  new (&cerr)ostream(&ferr);
  new (&clog)ostream(&ferr);
  cin.tie(&cout);
  cerr.setf(ios_base::unitbuf);

  fin.pubsetbuf(0, 0);
  fout.pubsetbuf(0, 0);
  ferr.pubsetbuf(0, 0);
}

is skipped. This eventually leads up to the problem I described earlier.

Even when I break at the entry point of the Bundle Package, the Global
Variables dialog tell me that both std::__nInit::ninit_cnt_s and
std::__wInit::winit_cnt_s equal 13.

Looking at lines 54, 55 of MSL/MSL_C++/MSL_Common/Src/iostream.cpp I see
the following:

int __nInit::ninit_cnt_s;
int __wInit::winit_cnt_s;

I would have expected:

int __nInit::ninit_cnt_s = 0;
int __wInit::winit_cnt_s = 0;

So I changed this code to the above. Rebuild the MSL_C++_Mach-O library.
Included MSL_C++_Mach-O.lib, MSL_C_Mach-O.lib and MSL_Runtime_Mach-O.lib

instead of MSL_All_Mach-O.lib.

Now the debugger came up with only assembly, but I think I've located
the 'if (ninit_cnt_s == 0)': (Please bear with me, the last time I did
some serious assembly was in way back in 1985 on a Rockwell 6502)

...
lwz RTOC, 12932(r3)
addi r0, RTOC, 1
cmpwi RTOC, 0x0000
stw r0, 12932(r3)
bne std::__nInit::__nInit()+0x5A800
...

In the Register Window, General Registers, register R0 contains 0x0D.

Note that, after I changed the libraries, in the Gloabel Variables
window, I could not find std::__nInit::ninit_cnt_s and
std::__wInit::winit_cnt_s any more.

Is this where Ron's remarks about the linker initialization point come
into play?

Have you got any more suggestions?

With kind regards,
Peter Paulus

>>Would you be so kind as to tell me what initialization function can be
>>used to initialize std::cout (and others) correctly.
[quoted text clipped - 9 lines]
>
> -Howard
Howard Hinnant - 20 Feb 2004 20:32 GMT
> So I changed this code to the above. Rebuild the MSL_C++_Mach-O library.
> Included MSL_C++_Mach-O.lib, MSL_C_Mach-O.lib and MSL_Runtime_Mach-O.lib

Try linking to the debug versions of these (have _D in the name).  That
should get you back to source debugging.

> instead of MSL_All_Mach-O.lib.
>
[quoted text clipped - 11 lines]
>
> In the Register Window, General Registers, register R0 contains 0x0D.

It sounds like (in both of your tests) that the stream initialization
code has already been run (13 times in your example).  The actual
initialization  is done during the first run, and the later ones do
nothing but increment the count.

> Have you got any more suggestions?

After switching to the debug version of the libraries, set a break point
in the initialization functions, and rerun to convince yourself that the
streams are indeed getting initialized, and walk up the stack to see
who's responsible.

-Howard
Peter Paulus - 23 Feb 2004 10:24 GMT
Hello Howard,

Including the debug versions gave me source code debugging again.
Setting the breakpoint at std::__nInit::__nInit() gave me the following
callstack:

QuarkXPress 0x00003800 (PPC)
QuarkXPress 0x00003980 (PPC)
QuarkXPress 0x00482604 (PPC)
QuarkXPress 0x000164B0 (PPC)
QuarkXPress 0x003BB738 (PPC)
QuarkXPress 0x00530FD0 (PPC)
QuarkXPress 0x00530A3C (PPC)
QuarkXPress 0x0052FF08 (PPC)
QuarkXPress 0x0052F69C (PPC)
QuarkXPress 0x0052BBFC (PPC)
QuarkXPress 0x0052DB24 (PPC)
QuarkXPress 0x00526C30 (PPC)
QuarkXPress 0x00526E44 (PPC)
Cougar::setup_callback(xtsetuprec*)
std::ios_base::Init::Init()
std::__nInit::__nInit()

std::__nInit::ninit_cnt_s equals 13 at this point.

I'm developing a plugin for QuarkXPress. For version 6 the MacOSX
version of QuarkXPress this is a Bundle Package.

My plugin is called Cougar. The setup_callback is one of the first, but
not hte first, call_backs that QuarkXPress issues to rendez-vous with
the plugin. This would be the 'normal' place to initialize 'plugin'-things.

I've also moved the 'std::ios_base::Init construct_streams;' statement
to the Bundle Package entry point; QuarkXPress is initializing it's
plugins. My plugin has not registered with QuarkXPress yet. The first
registration of any callback in my plugin happens in Cougar::activate_cb().

#pragma export on
int32 XTActivateCallback(xtactivaterec *cbparam)
{
std::ios_base::Init construct_streams;
return(Cougar::xtactivate_cb(cbparam));
}
#pragma export off

That results in the call-stack below:

QuarkXPress 0x00003800 (PPC)
QuarkXPress 0x00003980 (PPC)
QuarkXPress 0x00482604 (PPC)
QuarkXPress 0x000164B0 (PPC)
QuarkXPress 0x003BB738 (PPC)
QuarkXPress 0x00530F78 (PPC)
QuarkXPress 0x00530860 (PPC)
QuarkXPress 0x0052FE10 (PPC)
QuarkXPress 0x003BC21C (PPC)
QuarkXPress 0x0052EAC4 (PPC)
QuarkXPress 0x0052BB0C (PPC)
QuarkXPress 0x0052DE54 (PPC)
QuarkXPress 0x0052DB24 (PPC)
QuarkXPress 0x00526C30 (PPC)
QuarkXPress 0x00526E44 (PPC)
_XTActivateCallback
std::ios_base::Init::Init()
std::__nInit::__nInit()

std::__nInit::ninit_cnt_s equals 13 at this point also. This must mean
that either QuarkXPress initializes the standard streams std::cin,
std::cout, std::cerr and std::clog or something that QuarkXPress depends
upon.

As far as I know QuarkXPress does not have any support for the standard
streams. That is the reason I've developed a custom class to send
diagnostic messages through std::cout to a dialog that has a
textarea-control displaying the messages. This scenario used to work
fine when my plugin was still a Shared Library under MacOS 9.2,
QuarkXPress version 4 and 5, CodeWarrior 8.3. I'll ask them with respect
to the standard streams.

What I do not understand is the following.

With my entry point as follows:
#pragma export on
int32 XTActivateCallback(xtactivaterec *cbparam)
{
std::ios_base::Init construct_streams;
std::cout << "Hello World";
std::cout << std::endl;
return(Cougar::xtactivate_cb(cbparam));
}
#pragma export off

The code crashes in (file: MSL/MSL_C++/MSL_Common/Include/ostream):
template <class charT, class traits>
basic_ostream<charT, traits>::sentry::sentry(basic_ostream<charT,
traits>& os)
: ok_(false), // Breakpoint here
  uncaught_exception_(false),
  os_(os)
{
#ifndef _MSL_NO_EXCEPTIONS
try
  {
#endif
  if (os_.good()) // Access failure occurs here.
    {
    if (os_.tie() != 0)
    os_.tie()->flush();
    if (os_.good()) ok_ = true;
    else os_.setstate(ios_base::failbit);
    }
  ...

Tracing at the indicated breakpoint I see that this code is called
twice. The first invocation looks allright: The parameter 'os' of
basic_ostream::sentry::sentry(basic_ostream<charT, traits>& os) is
0x04498A58. This corresponds to the variable std::cout in
_XTActivateCallback. I can then trace it into os_.tie()->flush (line
360). It is at this point that the access failure occurs. The callstack
now is:

QuarkXPress 0x00003800 (PPC)
QuarkXPress 0x00003980 (PPC)
QuarkXPress 0x00482604 (PPC)
QuarkXPress 0x000164B0 (PPC)
QuarkXPress 0x003BB738 (PPC)
QuarkXPress 0x00530F78 (PPC)
QuarkXPress 0x00530860 (PPC)
QuarkXPress 0x0052FE10 (PPC)
QuarkXPress 0x003BC21C (PPC)
QuarkXPress 0x0052EAC4 (PPC)
QuarkXPress 0x0052BB0C (PPC)
QuarkXPress 0x0052DE54 (PPC)
QuarkXPress 0x0052DB24 (PPC)
QuarkXPress 0x00526C30 (PPC)
QuarkXPress 0x00526E44 (PPC)
_XTActivateCallback
std& std::operator<<<std, char_traits<char> >(basic_ostream<char, std>,
basic_ostream, const char*)
std::ostream::sentry::sentry(std::ostream&)
std::ostream::flush()
std::ostream::sentry::sentry(std::ostream&)

The paramater 'os' on the second invocation of
basic_ostream::sentry::sentry(basic_ostream<charT, traits>& os) is
0x10020000. Now as soon as 'if (os_.good())' (line 357) is executed the
access failure occurs. You can't 'trace into', so I believe the os_
field points to an invalid memory location.

Tracing into line 360: os_.tie()->flush() show that

basic_ios<charT, traits>::tie() (file:
MSL/MSL_C++/MSL_Common/Include/ios) returns the member field tiestr_
that has value 0x10020000.

Can you help me from this point on?

I believe there are 2 possibilties:
1. The constructor basic_ios(void) is called. This constructor does not
initialize the tiestr_ member field. Not to 0 or otherwise. Unfortunetly
I cannot set a breakpoint here.

2. Somebody (e.g. nInit) calls basic_ios<charT,
traits>::tie(basic_ostream<charT, traits>* tiestr). This is what nInit
tries to do. Unfortunately I cannot set a breakpoint here aswell.

With kind regards,
Peter Paulus

>>So I changed this code to the above. Rebuild the MSL_C++_Mach-O library.
>>Included MSL_C++_Mach-O.lib, MSL_C_Mach-O.lib and MSL_Runtime_Mach-O.lib
[quoted text clipped - 31 lines]
>
> -Howard
Howard Hinnant - 23 Feb 2004 15:51 GMT
> I believe there are 2 possibilties:
> 1. The constructor basic_ios(void) is called. This constructor does not
[quoted text clipped - 4 lines]
> traits>::tie(basic_ostream<charT, traits>* tiestr). This is what nInit
> tries to do. Unfortunately I cannot set a breakpoint here aswell.

Another possibility is that the count (std::__nInit::ninit_cnt_s) 13
represents garbage and the streams are never getting initialized.  Can
you determine how 13 gets in that memory location?  At load time it
should be 0.

-Howard
Peter Paulus - 24 Feb 2004 13:45 GMT
Hello Howard,

I've haven't got a clue as to whether or not the streams get initialized
 or std::__nInit::ninit_cnt_s just contains garbage.

However, if I break at my entry point:

#pragma export on
int32 XTActivateCallback(xtactivaterec *cbparam)
{
std::ios_base::Init construct_streams;
std::cout << "Hello World";
std::cout << std::endl;
return(Cougar::xtactivate_cb(cbparam));
}
#pragma export off

And step into std::ios_base::Init and set std::__nInit::ninit_cnt_s to
zero by hand in the debugger and step through the guarded block,
initializing the streams, the result in std::cout << "Hello World"; is
exactly the same: access failure.

I must say that, since yesterday, I do get messages in the 'Log System
Messages' window when debugging or the Darwin console when running. Mind
you, I do redirect std::cout, std:cerr and std:clog to a QuarkXPress
dialog and do not insert anything into std::cout in XTActivateCallback().

The redirection looks as follows:
ConsoleWAP::ConsoleWAP(long callbackID, long resourceID)
: WAP(callbackID, resourceID)
{
oldcout = _STD::cout.rdbuf();
oldcerr = _STD::cerr.rdbuf();
oldclog = _STD::clog.rdbuf();

log = new ::xpress::core::TextAreaStreamBuf(*this, messageList);

_STD::cout.rdbuf(log);
_STD::cerr.rdbuf(log);
_STD::clog.rdbuf(log);
}

TextAreaStreamBuf::TextAreaStreamBuf(WAP& wap, dlgitemid control)
: _STD::streambuf(), wap(wap)
{
this->control = control;
buffer[0] = '\0';
#pragma message("TextAreaStreamBuf::TextAreaStreamBuf(): fix buffer size")
setp(buffer, buffer + 10);
}

Apart from this problem, I have heaps and heaps of problems using the
debugger. Despite restarting my machine, restarting CodeWarrior,
removing object code, removing the build product(s), rebuilding the
Classic database, exporting and importing the project, combining all my
subprojects into one integral project, setting options (on all my
projects) over and over again, clearing all breakpoints, closing and
opening the symbol file, I cannot do but a handfull of succesfull
debug-sessions per day. And even when the debugger inconspicously looks
right, e.g. no breakpoints on comment lines, all statements eligble for
breakpoint, I do get the feeling that sometimes variables are incorrect.

It seems I've drifted off-topic, but I feel I'm getting close to a point
 were I'm far from productive. A solution for this is very much required.

With kind regards,
Peter Paulus.

>>I believe there are 2 possibilties:
>>1. The constructor basic_ios(void) is called. This constructor does not
[quoted text clipped - 11 lines]
>
> -Howard
Peter Paulus - 25 Feb 2004 11:11 GMT
Hi Howard,

Changing the entry point to

#pragma export on
int32 XTActivateCallback(xtactivaterec *cbparam)
{
// std::ios_base::Init construct_streams;
// Metrowerks::mutex::scoped_lock lock(get_stream_init_mutex());
static Metrowerks::console_inputbuf<char> fin(stdin);
static Metrowerks::console_outputbuf<char> fout(stdout);
static Metrowerks::console_outputbuf<char> ferr(stderr);

// if (ninit_cnt_s++ == 0)
//  {
    new (&std::cin) std::istream(&fin);
    new (&std::cout) std::ostream(&fout);
    new (&std::cerr) std::ostream(&ferr);
    new (&std::clog) std::ostream(&ferr);
    std::cin.tie(&std::cout);
    std::cerr.setf(std::ios_base::unitbuf);

    fin.pubsetbuf(0, 0);
    fout.pubsetbuf(0, 0);
    ferr.pubsetbuf(0, 0);
//  }

_STD::cout << "Hello World";
// _STD::cout << std::endl;
// _STD::cout.flush();
return(Cougar::xtactivate_cb(cbparam));
}

the code crashes with an access failure with the following call-stack.

QuarkXPress 0x00003800 (PPC)
QuarkXPress 0x00003980 (PPC)
QuarkXPress 0x00482604 (PPC)
QuarkXPress 0x000164B0 (PPC)
QuarkXPress 0x003BB738 (PPC)
QuarkXPress 0x00530F14 (PPC)
QuarkXPress 0x0052FD20 (PPC)
QuarkXPress 0x0052E924 (PPC)
QuarkXPress 0x0052BA1C (PPC)
QuarkXPress 0x0052CF5C (PPC)
CoreFoundation 0x9015CBF4 (PPC)
CoreFoundation 0x9015CFE4 (PPC)
libSystem.B.dylib 0x900169C8 (PPC)
dyld 0x8FE121A4 (PPC)
dyld 0x8FE106F0 (PPC)
dyld 0x8FE160A0 (PPC)
dyld 0x8FE16594 (PPC)
___sinit_/Cougar_cpp
std::__nInit::__nInit()
Metrowerks::bufferedbuf<char, std, char_traits<char> >::seekoff(long
long, std::ios_base::seekdir, Metrowerks::bufferedbuf<char, std,
char_traits<char> >::openmode)

Below the position of the programm counter is indicated.

__nInit::__nInit()
{
    Metrowerks::mutex::scoped_lock lock(get_stream_init_mutex());
    static Metrowerks::console_inputbuf<char> fin(stdin);
    static Metrowerks::console_outputbuf<char> fout(stdout);
    static Metrowerks::console_outputbuf<char> ferr(stderr);

    if (ninit_cnt_s++ == 0)
    {
        new (&cin)istream(&fin);
        new (&cout)ostream(&fout);
        new (&cerr)ostream(&ferr);
        new (&clog)ostream(&ferr);
        cin.tie(&cout);
        cerr.setf(ios_base::unitbuf);

        fin.pubsetbuf(0, 0);
        fout.pubsetbuf(0, 0);
        ferr.pubsetbuf(0, 0); // access failure occurs here.
    }
}

std::__nInit::ninit_cnt_s equals 1 at the crash point, so it must have
been 0 when entering std::__nInit::nInit(). Taking the position of the
crash into account it must have been the case that it was 0 and got
postincremented to 1.

To be complete the position of the program counter in seekoff() is
indicated below. The 'this' pointer in seekoff() is 0x000000000.

template <class charT, class traits>
typename bufferedbuf<charT, traits>::pos_type
bufferedbuf<charT, traits>::seekoff(off_type off,
_STD::ios_base::seekdir way, _STD::ios_base::openmode which)
{
    if (!is_open() || ((which & (_STD::ios_base::in | _STD::ios_base::out))
== 0) || (off != 0 && encoding_ <= 0)) // access failure occurs here.
        return pos_type(-1);
    if (sync() < 0)
        return pos_type(-1);
    int whence;
    switch (way)
    {
    case _STD::ios_base::beg:
        whence = SEEK_SET;
        break;
    case _STD::ios_base::cur:
        whence = SEEK_CUR;
        break;
    case _STD::ios_base::end:
        whence = SEEK_END;
        break;
    default:
        return pos_type(-1);
    }
    int width = encoding_ > 0 ? encoding_ : 0;
    off_type result = seek_device(width * off, whence);
    if (result < 0)
        return pos_type(-1);
    return pos_type(result);
}

By the way, I tried to set a breakpoint on __sinit_/Cougar_cpp in the
Symbolics Window by hand. At first I could not find the functions. Then
looking through all files I found the in the file wiostream, where I can
find may of my __sinit_/... functions, but not all. A few are in the
file I would expect them to be. The source panel of the Symbolics Window
presents MSL/MSL_C++/MSL_Common/Include/wiostream as the source of these
 functions.

Some questions in general:
1. Would it be at all possible to use std::cout from a Bundle Package?
2. Redirect std::cout by replacing it's streambuf?
3. Is the debugger itself a factor, i.e. it looks like the debugger is
also redirecting to the 'Log Systems Window', Darwin console or a
Terminal. I can imagine it would somehow be more persistent than my
redirect?

With kind regards,
Peter Paulus

> Hello Howard,
>
[quoted text clipped - 79 lines]
>>
>> -Howard
Howard Hinnant - 25 Feb 2004 15:00 GMT
Hi Peter,

I am sorry you are having so much trouble.

> Hi Howard,
>
[quoted text clipped - 53 lines]
> long, std::ios_base::seekdir, Metrowerks::bufferedbuf<char, std,
> char_traits<char> >::openmode)

There is something going on here that can not be explained by looking at
the MSL C++ sources.

std::__nInit::__nInit()

does not call (directly or indirectly)

Metrowerks::bufferedbuf<char,> std::char_traits<char> >::seekoff

So we are looking at some kind of corruption (maybe scrambled virtual
function tables?) but I have no way of knowing exactly what.

> Some questions in general:
> 1. Would it be at all possible to use std::cout from a Bundle Package?

I'm sorry, but I do not know.

> 2. Redirect std::cout by replacing it's streambuf?

Yes, here is a simple example:

#include <iostream>
#include <fstream>

int main()
{
   std::cout << "Before redirect\n";
   std::ofstream out("console_output");
   std::streambuf* save = std::cout.rdbuf(out.rdbuf());
   std::cout << "During redirect\n";  // goes to file "console_output"
   std::cout.rdbuf(save);
   std::cout << "After redirect\n";
}

> 3. Is the debugger itself a factor, i.e. it looks like the debugger is
> also redirecting to the 'Log Systems Window', Darwin console or a
> Terminal. I can imagine it would somehow be more persistent than my
> redirect?

I really don't think so.

-Howard
Peter Paulus - 26 Feb 2004 16:04 GMT
Hello Howard,

Using a test-application I created around october 2003 to get some
experience with COMish things on MacOs, I've done some more tests to see
if one can actually redirect std::cout and then use it from a plugin.
Mind you that I needed to modify the CoreFoundation Header
CoreFoundation/CFPlugInCOM.h. Somehow between CW8 and CW9.1 inheriting
from __comobject to achieve binary compatibility got deprecated. I
modified thus:

class IUnknown
#if __MWERKS__ < 0x3200
 : __comobject
#endif
{
    public:
    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID
*ppv) = 0;
    virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0;
    virtual ULONG STDMETHODCALLTYPE Release(void) = 0;
};

Binary compatibility is not my concern at present. So with the
modification in place IUnknown is just your average abstract base class.

I've written some C++ around CFPlugin calls like CFPluginCreate,
CFPlugInFindFactoriesForPlugInTypeInPlugIn, CFPlugInInstanceCreate and
so on.

Then I use the bit of code you gave me to redirect outputto a file. I
did 3 tests:
1. Without redirection.
All output either appears on the Log System Messages Window (debugging)
or Darwin console (running).

Here is output for this scenario
I've tagged message with a qualifier 'Application' and 'Plugin'.
Furthermore they have an otherwise meaningless timestamp (microseconds
since ????) in order to reconstruct history in the redirected case (see 2.)

**** 'Log System Messages' window
Debugging started for TestApplication at 4:38:41 PM
Starting Mach-o App: /Projects/Code
Repository/projects/COM/TestApplication.app/Contents/MacOS/TestApplication
TestApplication loaded at 0x1000 from /Projects/Code
Repository/projects/COM/TestApplication.app/Contents/MacOS/TestApplication.
dyld loaded at 0x8fe00000 from /usr/lib/dyld.
libSystem.B.dylib loaded at 0x90000000 from /usr/lib/libSystem.B.dylib.
CoreFoundation loaded at 0x90130000 from
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation.
Carbon loaded at 0x90a80000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon.
libmathCommon.A.dylib loaded at 0x93a40000 from
/usr/lib/system/libmathCommon.A.dylib.
ImageCapture loaded at 0x91ca0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/ImageCapture.framework/Versions/A/ImageCapture.
SpeechRecognition loaded at 0x91c50000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/SpeechRecognition.framework/Versions/A/SpeechRecognition.
SecurityHI loaded at 0x91d60000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/SecurityHI.framework/Versions/A/SecurityHI.
Carbon loaded at 0x90a80000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon.
Help loaded at 0x91cc0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/Help.framework/Versions/A/Help.
OpenScripting loaded at 0x91c70000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/OpenScripting.framework/Versions/A/OpenScripting.
Print loaded at 0x94ed0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/Print.framework/Versions/A/Print.
HTMLRendering loaded at 0x919a0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HTMLRendering.framework/Versions/A/HTMLRendering.
NavigationServices loaded at 0x91e00000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/NavigationServices.framework/Versions/A/NavigationServices.
CarbonSound loaded at 0x91790000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/CarbonSound.framework/Versions/A/CarbonSound.
CommonPanels loaded at 0x91ce0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/CommonPanels.framework/Versions/A/CommonPanels.
HIToolbox loaded at 0x969a0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox.
Carbon loaded at 0x90a80000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon.
Security loaded at 0x92ba0000 from
/System/Library/Frameworks/Security.framework/Versions/A/Security.
AE loaded at 0x91b50000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/AE.framework/Versions/A/AE.
ATS loaded at 0x91930000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATS.framework/Versions/A/ATS.
ColorSync loaded at 0x917f0000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ColorSync.framework/Versions/A/ColorSync.
CoreGraphics loaded at 0x936f0000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics.
PrintCore loaded at 0x95230000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/PrintCore.framework/Versions/A/PrintCore.
QD loaded at 0x91a50000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/QD.framework/Versions/A/QD.
TestPlugin loaded at 0x0 from /Projects/Code
Repository/projects/COM/TestApplication.app/Contents/PlugIns/TestPlugin.plugin/Contents/MacOS/TestPlugin.
HIServices loaded at 0x93000000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/HIServices.framework/Versions/A/HIServices.
SpeechSynthesis loaded at 0x91910000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/SpeechSynthesis.framework/Versions/A/SpeechSynthesis.
FindByContent loaded at 0x923e0000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/FindByContent.framework/Versions/A/FindByContent.
LaunchServices loaded at 0x92800000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/LaunchServices.
libPPDLib.dylib loaded at 0x872b0000 from
/System/Library/Printers/Libraries/libPPDLib.dylib.
SpeechSynthesis loaded at 0x91910000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/SpeechSynthesis.framework/Versions/A/SpeechSynthesis.
DesktopServicesPriv loaded at 0x90730000 from
/System/Library/PrivateFrameworks/DesktopServicesPriv.framework/Versions/A/DesktopServicesPriv.
SystemConfiguration loaded at 0x90a50000 from
/System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration.
CoreAudio loaded at 0x94640000 from
/System/Library/Frameworks/CoreAudio.framework/Versions/A/CoreAudio.
DesktopServicesPriv loaded at 0x90730000 from
/System/Library/PrivateFrameworks/DesktopServicesPriv.framework/Versions/A/DesktopServicesPriv.
libmathCommon.A.dylib loaded at 0x93a40000 from
/usr/lib/system/libmathCommon.A.dylib.
libCGATS.A.dylib loaded at 0x91ec0000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/Versions/A/Resources/libCGATS.A.dylib.
ImageCapture loaded at 0x91ca0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/ImageCapture.framework/Versions/A/ImageCapture.
OpenScripting loaded at 0x91c70000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/OpenScripting.framework/Versions/A/OpenScripting.
ImageCapture loaded at 0x91ca0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/ImageCapture.framework/Versions/A/ImageCapture.
libRIP.A.dylib loaded at 0x91f50000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/Versions/A/Resources/libRIP.A.dylib.
CarbonCore loaded at 0x90220000 from
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/CarbonCore.
OSServices loaded at 0x90510000 from
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/OSServices.framework/Versions/A/OSServices.
TestPlugin loaded at 0x0 from /Projects/Code
Repository/projects/COM/TestApplication.app/Contents/PlugIns/TestPlugin.plugin/Contents/MacOS/TestPlugin.
SystemConfiguration loaded at 0x90a50000 from
/System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration.
libz.1.1.3.dylib loaded at 0x922a0000 from /usr/lib/libz.1.1.3.dylib.
libLW8Utils.dylib loaded at 0x87320000 from
/System/Library/Printers/Libraries/libLW8Utils.dylib.
libssl.0.9.dylib loaded at 0x92ad0000 from /usr/lib/libssl.0.9.dylib.
libcrypto.0.9.dylib loaded at 0x929f0000 from /usr/lib/libcrypto.0.9.dylib.
DirectoryService loaded at 0x90b10000 from
/System/Library/Frameworks/DirectoryService.framework/Versions/A/DirectoryService.
Application(3365188320): -->main(int, const char **)
Application(3365188698): Before redirect
Application(3365188788): During redirect
Application(3365188908): -->COM::TestApplication::main(int, const char **)
Application(3365189288): <--COM::TestApplication::TestApplication()
Application(3365189448): Creating plugin...
Plugin(3365189564): -->COM::Plugin::Plugin(const char *)
Plugin(3365189684): <--COM::Plugin::Plugin(const char *)
Application(3365191217): Plugin created.
Application(3365191598): Preloading plugin...
Plugin(3365191985): -->COM::Plugin::load()
Plugin(3365338050): <--COM::Plugin::load()
Application(3365338298): Plugin preloaded.
Application(3365338402): Retrieving object...
Plugin(3365338519): -->COM::Plugin::getObject(CFUUIDBytes)
Plugin(3365338686): Calling CFPluginInstanceCreate()...
TestPlugin loaded at 0x150000 from /Projects/Code
Repository/projects/COM/TestApplication.app/Contents/Plugins/TestPlugin.plugin/Contents/MacOS/TestPlugin.
Plugin(3366108233): -->COM::TestPlugin::createObject(const __CFAllocator
*, const __CFUUID *)
Plugin(3366108642): -->COM::TestObject::TestObject(CFUUIDBytes)
Plugin(3366108802): <--COM::TestObject::TestObject(CFUUIDBytes)
Plugin(3366108945): <--COM::TestPlugin::createObject(const __CFAllocator
*, const __CFUUID *)
Plugin(3366109194): Done calling CFPluginInstanceCreate().
Plugin(3366109444): <--COM::Plugin::getObject(CFUUIDBytes)
Application(3366109610): Object retrieved.
Application(3366109722): Narrowing object...
Plugin(3366109833): -->COM::TestObject::QueryInterface(CFUUIDBytes, void **)
Plugin(3371129856): <--COM::TestObject::QueryInterface(CFUUIDBytes, void **)
Application(3371130133): Object narrowed.
Application(3371130333): Calling test()...
Plugin(3371130432): -->COM::TestObject::test()
TestObject::test()
Plugin(3371130610): <--COM::TestObject::test()
Application(3371130724): test() called.
Application(3371130858): Releasing test()...
Application(3371130969): Test() released.
Plugin(3371131084): -->COM::TestObject::QueryInterface(CFUUIDBytes, void **)
Plugin(3371131277): <--COM::TestObject::QueryInterface(CFUUIDBytes, void **)
Plugin(3371131452): -->COM::TestObject::load()
TestObject::load()
Plugin(3371131603): <--COM::TestObject::load()
Plugin(3371131717): -->COM::TestObject::save()
TestObject::save()
Plugin(3371131898): <--COM::TestObject::save()
Plugin(3371132012): -->COM::TestObject::~TestObject()
Plugin(3371132141): <--COM::TestObject::~TestObject()
Application(3371132300): -->COM::TestApplication::TestApplication()
Application(3371132455): <--COM::TestApplication::main(int, const char **)
Application(3371132633): After redirect
Application(3371132722): <--main(int, const char **)
Debugging stopped for TestApplication at 4:38:54 PM. Process died.

2. With redirection in the host application (only).
Since I do have source of the host application, I redirected in the host
application, hoping that functions  called from the Bundle Package also
use the redirected std::cout. Well, guess what: they don't. Somehow,
just after CFPluginInstanceCreate is called, messages sent to std::cout
start appearing on either the Log System Messages Window or in the file
in some sort of interleaved fashion. It looks like everything from the
plugin gets sent to the Log System Messages window, while every message
sent to std::cout from the application gets indeed redirected to the file.

Output of running with redirection in place:
*** 'Log System Messages' window
Debugging started for TestApplication at 4:41:04 PM
Starting Mach-o App: /Projects/Code
Repository/projects/COM/TestApplication.app/Contents/MacOS/TestApplication
TestApplication loaded at 0x1000 from /Projects/Code
Repository/projects/COM/TestApplication.app/Contents/MacOS/TestApplication.
dyld loaded at 0x8fe00000 from /usr/lib/dyld.
libSystem.B.dylib loaded at 0x90000000 from /usr/lib/libSystem.B.dylib.
CoreFoundation loaded at 0x90130000 from
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation.
Carbon loaded at 0x90a80000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon.
libmathCommon.A.dylib loaded at 0x93a40000 from
/usr/lib/system/libmathCommon.A.dylib.
ImageCapture loaded at 0x91ca0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/ImageCapture.framework/Versions/A/ImageCapture.
SpeechRecognition loaded at 0x91c50000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/SpeechRecognition.framework/Versions/A/SpeechRecognition.
SecurityHI loaded at 0x91d60000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/SecurityHI.framework/Versions/A/SecurityHI.
Carbon loaded at 0x90a80000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon.
Help loaded at 0x91cc0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/Help.framework/Versions/A/Help.
OpenScripting loaded at 0x91c70000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/OpenScripting.framework/Versions/A/OpenScripting.
Print loaded at 0x94ed0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/Print.framework/Versions/A/Print.
HTMLRendering loaded at 0x919a0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HTMLRendering.framework/Versions/A/HTMLRendering.
NavigationServices loaded at 0x91e00000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/NavigationServices.framework/Versions/A/NavigationServices.
CarbonSound loaded at 0x91790000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/CarbonSound.framework/Versions/A/CarbonSound.
CommonPanels loaded at 0x91ce0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/CommonPanels.framework/Versions/A/CommonPanels.
HIToolbox loaded at 0x969a0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox.
Carbon loaded at 0x90a80000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon.
Security loaded at 0x92ba0000 from
/System/Library/Frameworks/Security.framework/Versions/A/Security.
AE loaded at 0x91b50000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/AE.framework/Versions/A/AE.
ATS loaded at 0x91930000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATS.framework/Versions/A/ATS.
ColorSync loaded at 0x917f0000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ColorSync.framework/Versions/A/ColorSync.
CoreGraphics loaded at 0x936f0000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics.
PrintCore loaded at 0x95230000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/PrintCore.framework/Versions/A/PrintCore.
QD loaded at 0x91a50000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/QD.framework/Versions/A/QD.
TestPlugin loaded at 0x0 from /Projects/Code
Repository/projects/COM/TestApplication.app/Contents/PlugIns/TestPlugin.plugin/Contents/MacOS/TestPlugin.
HIServices loaded at 0x93000000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/HIServices.framework/Versions/A/HIServices.
SpeechSynthesis loaded at 0x91910000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/SpeechSynthesis.framework/Versions/A/SpeechSynthesis.
FindByContent loaded at 0x923e0000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/FindByContent.framework/Versions/A/FindByContent.
LaunchServices loaded at 0x92800000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/LaunchServices.
libPPDLib.dylib loaded at 0x872b0000 from
/System/Library/Printers/Libraries/libPPDLib.dylib.
SpeechSynthesis loaded at 0x91910000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/SpeechSynthesis.framework/Versions/A/SpeechSynthesis.
DesktopServicesPriv loaded at 0x90730000 from
/System/Library/PrivateFrameworks/DesktopServicesPriv.framework/Versions/A/DesktopServicesPriv.
SystemConfiguration loaded at 0x90a50000 from
/System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration.
CoreAudio loaded at 0x94640000 from
/System/Library/Frameworks/CoreAudio.framework/Versions/A/CoreAudio.
DesktopServicesPriv loaded at 0x90730000 from
/System/Library/PrivateFrameworks/DesktopServicesPriv.framework/Versions/A/DesktopServicesPriv.
libmathCommon.A.dylib loaded at 0x93a40000 from
/usr/lib/system/libmathCommon.A.dylib.
libCGATS.A.dylib loaded at 0x91ec0000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/Versions/A/Resources/libCGATS.A.dylib.
ImageCapture loaded at 0x91ca0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/ImageCapture.framework/Versions/A/ImageCapture.
OpenScripting loaded at 0x91c70000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/OpenScripting.framework/Versions/A/OpenScripting.
ImageCapture loaded at 0x91ca0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/ImageCapture.framework/Versions/A/ImageCapture.
libRIP.A.dylib loaded at 0x91f50000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/Versions/A/Resources/libRIP.A.dylib.
CarbonCore loaded at 0x90220000 from
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/CarbonCore.
OSServices loaded at 0x90510000 from
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/OSServices.framework/Versions/A/OSServices.
TestPlugin loaded at 0x0 from /Projects/Code
Repository/projects/COM/TestApplication.app/Contents/PlugIns/TestPlugin.plugin/Contents/MacOS/TestPlugin.
SystemConfiguration loaded at 0x90a50000 from
/System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration.
libz.1.1.3.dylib loaded at 0x922a0000 from /usr/lib/libz.1.1.3.dylib.
libLW8Utils.dylib loaded at 0x87320000 from
/System/Library/Printers/Libraries/libLW8Utils.dylib.
libssl.0.9.dylib loaded at 0x92ad0000 from /usr/lib/libssl.0.9.dylib.
libcrypto.0.9.dylib loaded at 0x929f0000 from /usr/lib/libcrypto.0.9.dylib.
DirectoryService loaded at 0x90b10000 from
/System/Library/Frameworks/DirectoryService.framework/Versions/A/DirectoryService.
Application(3509024762): -->main(int, const char **)
Application(3509025079): Before redirect
TestPlugin loaded at 0x153000 from /Projects/Code
Repository/projects/COM/TestApplication.app/Contents/Plugins/TestPlugin.plugin/Contents/MacOS/TestPlugin.
Plugin(3509663349): -->COM::TestPlugin::createObject(const __CFAllocator
*, const __CFUUID *)
Plugin(3509663763): -->COM::TestObject::TestObject(CFUUIDBytes)
Plugin(3509663920): <--COM::TestObject::TestObject(CFUUIDBytes)
Plugin(3509664070): <--COM::TestPlugin::createObject(const __CFAllocator
*, const __CFUUID *)
Plugin(3509664519): -->COM::TestObject::QueryInterface(CFUUIDBytes, void **)
Plugin(3509664721): <--COM::TestObject::QueryInterface(CFUUIDBytes, void **)
Plugin(3509664980): -->COM::TestObject::test()
TestObject::test()
Plugin(3509665152): <--COM::TestObject::test()
Plugin(3509665394): -->COM::TestObject::QueryInterface(CFUUIDBytes, void **)
Plugin(3509665597): <--COM::TestObject::QueryInterface(CFUUIDBytes, void **)
Plugin(3509665774): -->COM::TestObject::load()
TestObject::load()
Plugin(3509666109): <--COM::TestObject::load()
Plugin(3509666232): -->COM::TestObject::save()
TestObject::save()
Plugin(3509666399): <--COM::TestObject::save()
Plugin(3509666497): -->COM::TestObject::~TestObject()
Plugin(3509666630): <--COM::TestObject::~TestObject()
Application(3509666905): After redirect
Application(3509667014): <--main(int, const char **)
Debugging stopped for TestApplication at 4:41:14 PM. Process died.

**** file "console_output"
Application(3509025441): During redirect
Application(3509025500): -->COM::TestApplication::main(int, const char **)
Application(3509025588): <--COM::TestApplication::TestApplication()
Application(3509025636): Creating plugin...
Plugin(3509025692): -->COM::Plugin::Plugin(const char *)
Plugin(3509025754): <--COM::Plugin::Plugin(const char *)
Application(3509025779): Plugin created.
Application(3509025815): Preloading plugin...
Plugin(3509025864): -->COM::Plugin::load()
Plugin(3509030981): <--COM::Plugin::load()
Application(3509031081): Plugin preloaded.
Application(3509031106): Retrieving object...
Plugin(3509031140): -->COM::Plugin::getObject(CFUUIDBytes)
Plugin(3509031211): Calling CFPluginInstanceCreate()...
Plugin(3509664296): Done calling CFPluginInstanceCreate().
Plugin(3509664412): <--COM::Plugin::getObject(CFUUIDBytes)
Application(3509664458): Object retrieved.
Application(3509664495): Narrowing object...
Application(3509664896): Object narrowed.
Application(3509664947): Calling test()...
Application(3509665290): test() called.
Application(3509665316): Releasing test()...
Application(3509665369): Test() released.
Application(3509666790): -->COM::TestApplication::TestApplication()
Application(3509666860): <--COM::TestApplication::main(int, const char **)

3. With redirection in the plugin, but not the host application
I've now got a bit of a problem as to where to put the redirection code,
because my test-code propably is not yet up to par. Info.plist contains:

plist
{
    dictionary
    {
        key "CFBundleIdentifier" value string kBundleIdentifier
       
        key "CFBundleName" value string __OUTPUT_FILENAME__
        key "CFBundleGetInfoString" value string kBundleGetInfo
        key "CFBundleShortVersionString" value string kBundleShortVersion
       
        key "CFBundlePackageType" value string __OUTPUT_TYPE__
        key "CFBundleSignature" value string __OUTPUT_CREATOR__
        key "CFBundleExecutable" value string __OUTPUT_FILENAME__
        key "CFBundleVersion" value string "1.0"
       
        key "CFBundleDevelopmentRegion" value string "English"
        key "CFBundleInfoDictionaryVersion" value string "6.0"
        key "LSRequiresCarbon" value boolean true
        key "CFPlugInDynamicRegistration" value boolean false
        key "CFPlugInDynamicRegisterFunction" value string ""
        key "CFPlugInFactories" value dictionary
         {
         key "6A753A44-4D6F-1226-9C60-0050E4C00067" value string
"_ZN3COM10TestPlugin12createObjectEPK13__CFAllocatorPK8__CFUUID"
         }
        key "CFPlugInTypes" value dictionary
         {
         key "69753A44-4D6F-1226-9C60-0050E4C00067" value array
           [
           string "6A753A44-4D6F-1226-9C60-0050E4C00067"
           ]
         }
        key "CFPlugInUnLoadFunction" value string ""
    }
}

So it directly creates an COMish object from the factory function. I'll
try and redirect here (only once).

I've already seen in the debugger that in the 'Global Variables' window,
there are 2 std::cout variables:
Application: std::cout 0x0017C1E8
Plugin:      std::cout 0x00176AC8

For now I'll redirect to a second file "plugin_output".

This crashes as follows:
start
start
main
COM::TestApplication::main(int, const char**)
COM::TestApplication::TestApplication()
COM::Object::narrow(CFUUIDBytes)
COM::TestObject::QueryInterface(CFUUIDBytes, void**)
_ZNSolsEPFRSoS0_E
std::basic_ostream<std::char_traits<char>, __T2>& std::endl<char,
std::char_traits<char> >(basic_ostream<std::char_traits<char>, __T2>)
std::ostream::flush()
std::basic_streambuf<char, std::char_traits<char> >::pubsync()
0xBFFFF4FC (PPC)

*** Log System Messages window
Debugging started for TestApplication at 4:47:11 PM
Starting Mach-o App: /Projects/Code
Repository/projects/COM/TestApplication.app/Contents/MacOS/TestApplication
TestApplication loaded at 0x1000 from /Projects/Code
Repository/projects/COM/TestApplication.app/Contents/MacOS/TestApplication.
dyld loaded at 0x8fe00000 from /usr/lib/dyld.
libSystem.B.dylib loaded at 0x90000000 from /usr/lib/libSystem.B.dylib.
CoreFoundation loaded at 0x90130000 from
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation.
Carbon loaded at 0x90a80000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon.
libmathCommon.A.dylib loaded at 0x93a40000 from
/usr/lib/system/libmathCommon.A.dylib.
ImageCapture loaded at 0x91ca0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/ImageCapture.framework/Versions/A/ImageCapture.
SpeechRecognition loaded at 0x91c50000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/SpeechRecognition.framework/Versions/A/SpeechRecognition.
SecurityHI loaded at 0x91d60000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/SecurityHI.framework/Versions/A/SecurityHI.
Carbon loaded at 0x90a80000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon.
Help loaded at 0x91cc0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/Help.framework/Versions/A/Help.
OpenScripting loaded at 0x91c70000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/OpenScripting.framework/Versions/A/OpenScripting.
Print loaded at 0x94ed0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/Print.framework/Versions/A/Print.
HTMLRendering loaded at 0x919a0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HTMLRendering.framework/Versions/A/HTMLRendering.
NavigationServices loaded at 0x91e00000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/NavigationServices.framework/Versions/A/NavigationServices.
CarbonSound loaded at 0x91790000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/CarbonSound.framework/Versions/A/CarbonSound.
CommonPanels loaded at 0x91ce0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/CommonPanels.framework/Versions/A/CommonPanels.
HIToolbox loaded at 0x969a0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox.
Carbon loaded at 0x90a80000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon.
Security loaded at 0x92ba0000 from
/System/Library/Frameworks/Security.framework/Versions/A/Security.
AE loaded at 0x91b50000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/AE.framework/Versions/A/AE.
ATS loaded at 0x91930000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATS.framework/Versions/A/ATS.
ColorSync loaded at 0x917f0000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ColorSync.framework/Versions/A/ColorSync.
CoreGraphics loaded at 0x936f0000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics.
PrintCore loaded at 0x95230000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/PrintCore.framework/Versions/A/PrintCore.
QD loaded at 0x91a50000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/QD.framework/Versions/A/QD.
TestPlugin loaded at 0x0 from /Projects/Code
Repository/projects/COM/TestApplication.app/Contents/PlugIns/TestPlugin.plugin/Contents/MacOS/TestPlugin.
HIServices loaded at 0x93000000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/HIServices.framework/Versions/A/HIServices.
SpeechSynthesis loaded at 0x91910000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/SpeechSynthesis.framework/Versions/A/SpeechSynthesis.
FindByContent loaded at 0x923e0000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/FindByContent.framework/Versions/A/FindByContent.
LaunchServices loaded at 0x92800000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/LaunchServices.
libPPDLib.dylib loaded at 0x872b0000 from
/System/Library/Printers/Libraries/libPPDLib.dylib.
SpeechSynthesis loaded at 0x91910000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/SpeechSynthesis.framework/Versions/A/SpeechSynthesis.
DesktopServicesPriv loaded at 0x90730000 from
/System/Library/PrivateFrameworks/DesktopServicesPriv.framework/Versions/A/DesktopServicesPriv.
SystemConfiguration loaded at 0x90a50000 from
/System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration.
CoreAudio loaded at 0x94640000 from
/System/Library/Frameworks/CoreAudio.framework/Versions/A/CoreAudio.
DesktopServicesPriv loaded at 0x90730000 from
/System/Library/PrivateFrameworks/DesktopServicesPriv.framework/Versions/A/DesktopServicesPriv.
libmathCommon.A.dylib loaded at 0x93a40000 from
/usr/lib/system/libmathCommon.A.dylib.
libCGATS.A.dylib loaded at 0x91ec0000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/Versions/A/Resources/libCGATS.A.dylib.
ImageCapture loaded at 0x91ca0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/ImageCapture.framework/Versions/A/ImageCapture.
OpenScripting loaded at 0x91c70000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/OpenScripting.framework/Versions/A/OpenScripting.
ImageCapture loaded at 0x91ca0000 from
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/ImageCapture.framework/Versions/A/ImageCapture.
libRIP.A.dylib loaded at 0x91f50000 from
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/Versions/A/Resources/libRIP.A.dylib.
CarbonCore loaded at 0x90220000 from
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/CarbonCore.
OSServices loaded at 0x90510000 from
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/OSServices.framework/Versions/A/OSServices.
TestPlugin loaded at 0x0 from /Projects/Code
Repository/projects/COM/TestApplication.app/Contents/PlugIns/TestPlugin.plugin/Contents/MacOS/TestPlugin.
SystemConfiguration loaded at 0x90a50000 from
/System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration.
libz.1.1.3.dylib loaded at 0x922a0000 from /usr/lib/libz.1.1.3.dylib.
libLW8Utils.dylib loaded at 0x87320000 from
/System/Library/Printers/Libraries/libLW8Utils.dylib.
libssl.0.9.dylib loaded at 0x92ad0000 from /usr/lib/libssl.0.9.dylib.
libcrypto.0.9.dylib loaded at 0x929f0000 from /usr/lib/libcrypto.0.9.dylib.
DirectoryService loaded at 0x90b10000 from
/System/Library/Frameworks/DirectoryService.framework/Versions/A/DirectoryService.
Application(3874400846): -->main(int, const char **)
Application(3874401150): Before redirect
Application(3874401256): During redirect
Application(3874401351): -->COM::TestApplication::main(int, const char **)
Application(3874401527): <--COM::TestApplication::TestApplication()
Application(3874401687): Creating plugin...
Plugin(3874401822): -->COM::Plugin::Plugin(const char *)
Plugin(3874401963): <--COM::Plugin::Plugin(const char *)
Application(3874402126): Plugin created.
Application(3874402238): Preloading plugin...
Plugin(3874402342): -->COM::Plugin::load()
Plugin(3874408326): <--COM::Plugin::load()
Application(3874408527): Plugin preloaded.
Application(3874408624): Retrieving object...
Plugin(3874408761): -->COM::Plugin::getObject(CFUUIDBytes)
Plugin(3874408920): Calling CFPluginInstanceCreate()...
TestPlugin loaded at 0x157000 from /Projects/Code
Repository/projects/COM/TestApplication.app/Contents/Plugins/TestPlugin.plugin/Contents/MacOS/TestPlugin.
Plugin(3875196025): Done calling CFPluginInstanceCreate().
Plugin(3875196245): <--COM::Plugin::getObject(CFUUIDBytes)
Application(3875196415): Object retrieved.
Application(3875196515): Narrowing object...

The file 'plugin_output' is empty but created.

I think this corresponds more or less to the situation I have with my
QuarkXPress Plugin. what I do not understand is why there is a duplicate
std::cout. I assumed that sharing the same address space also meant
sharing the same global variables.

I'm not sure where to go next with the QuarkXPress plugin. This has
already taken an disproportionate amount of my time and it looks like it
is leading nowhere soon. If you would like to investigate this further
please do keep me informed. As I said, it worked fine under MacOS 9 and
it enabled me to use third party software that reported message on the
standard streams. Not being able to do that anymore is quite a step
backwards.

Would this be a problem of the Core Foundation, i.e. should I talk with
   Apple about?

Would it be the same for dyld?

Would using the unix libs salvage it?

Anyway, Thank you for your assistance.

With kind regards,
Peter Paulus

> Hi Peter,
>
[quoted text clipped - 100 lines]
>
> -Howard
Howard Hinnant - 26 Feb 2004 16:39 GMT
> Binary compatibility is not my concern at present.
<snip>
> Since I do have source of the host application,
<snip>
> I've already seen in the debugger that in the 'Global Variables' window,
> there are 2 std::cout variables:
> Application: std::cout 0x0017C1E8
> Plugin:      std::cout 0x00176AC8
<snip>

I think you have binary compatibility problems.  It sounds like you have
both Pro 8 and Pro 9 cout running around in different code fragments
(and they are not binary compatibile with each other).

If cout is going to work in a shared lib environment, then all modules
must link to one shared version of the C++ lib.  There should be only
one cout in a program.

-Howard
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.