bug 523894: wstrings are bad news in OPT builds due to chromium/Mozilla -fshort-wchar mismatch

This commit is contained in:
Chris Jones 2009-11-05 18:24:27 -06:00
parent 3d8a76e521
commit 721479dcd3
7 changed files with 103 additions and 53 deletions

View File

@ -61,8 +61,8 @@ PluginProcessParent::~PluginProcessParent()
bool
PluginProcessParent::Launch()
{
std::vector<std::wstring> args;
args.push_back(UTF8ToWide(mPluginFilePath));
std::vector<std::string> args;
args.push_back(mPluginFilePath);
return SyncLaunch(args);
}

View File

@ -66,15 +66,27 @@ PluginThreadChild::Init()
{
GeckoThread::Init();
// FIXME/cjones: set up channel stuff, etc.
std::string pluginFilename;
#if defined(OS_POSIX)
// NB: need to be very careful in ensuring that the first arg
// (after the binary name) here is indeed the plugin module path.
// Keep in sync with dom/plugins/PluginModuleParent.
std::vector<std::string> values = CommandLine::ForCurrentProcess()->argv();
NS_ABORT_IF_FALSE(values.size() >= 2, "not enough args");
pluginFilename = values[1];
#elif defined(OS_WIN)
std::vector<std::wstring> values =
CommandLine::ForCurrentProcess()->GetLooseValues();
NS_ABORT_IF_FALSE(values.size() >= 1, "not enough loose args");
// XXX need to handle plugin args!
DCHECK(values.size() >= 1);
pluginFilename = WideToUTF8(values[0]);
std::string pluginFilename = WideToUTF8(values[0]);
#else
# error Sorry
#endif
// FIXME owner_loop() is bad here
mPlugin.Init(pluginFilename,

View File

@ -250,8 +250,10 @@ AsyncChannel::OnChannelError()
// Must exit the IO loop, which will then join with the UI loop.
MessageLoop::current()->Quit();
#else
// Go ahead and abort here.
NS_DebugBreak(NS_DEBUG_ABORT, nsnull, nsnull, nsnull, 0);
// FIXME need to devote some thought to the most
// effective/least easily overrideable, yet quiet, way to
// exit. abort() is a little loud
_exit(0);
#endif
}
}

View File

@ -67,12 +67,11 @@ GeckoChildProcessHost::GeckoChildProcessHost(GeckoProcessType aProcessType,
}
bool
GeckoChildProcessHost::SyncLaunch(std::vector<std::wstring> aExtraOpts)
GeckoChildProcessHost::SyncLaunch(std::vector<std::string> aExtraOpts)
{
MessageLoop* loop = MessageLoop::current();
MessageLoop* ioLoop =
BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO);
NS_ASSERTION(loop != ioLoop, "sync launch from the IO thread NYI");
NS_ASSERTION(MessageLoop::current() != ioLoop, "sync launch from the IO thread NYI");
ioLoop->PostTask(FROM_HERE,
NewRunnableMethod(this,
@ -90,7 +89,7 @@ GeckoChildProcessHost::SyncLaunch(std::vector<std::wstring> aExtraOpts)
}
bool
GeckoChildProcessHost::AsyncLaunch(std::vector<std::wstring> aExtraOpts)
GeckoChildProcessHost::AsyncLaunch(std::vector<std::string> aExtraOpts)
{
// FIXME/cjones: make this work from non-IO threads, too
@ -98,45 +97,74 @@ GeckoChildProcessHost::AsyncLaunch(std::vector<std::wstring> aExtraOpts)
return false;
}
FilePath exePath =
FilePath::FromWStringHack(CommandLine::ForCurrentProcess()->program());
exePath = exePath.DirName();
exePath = exePath.AppendASCII(MOZ_CHILD_PROCESS_NAME);
// remap the IPC socket fd to a well-known int, as the OS does for
// STDOUT_FILENO, for example
#if defined(OS_POSIX)
int srcChannelFd, dstChannelFd;
channel().GetClientFileDescriptorMapping(&srcChannelFd, &dstChannelFd);
mFileMap.push_back(std::pair<int,int>(srcChannelFd, dstChannelFd));
#endif
CommandLine cmdLine(exePath.ToWStringHack());
cmdLine.AppendSwitchWithValue(switches::kProcessChannelID, channel_id());
for (std::vector<std::wstring>::iterator it = aExtraOpts.begin();
it != aExtraOpts.end();
++it) {
cmdLine.AppendLooseValue((*it).c_str());
}
base::ProcessHandle process;
// send the child the PID so that it can open a ProcessHandle back to us.
// probably don't want to do this in the long run
char pidstring[32];
PR_snprintf(pidstring, sizeof(pidstring) - 1,
"%ld", base::Process::Current().pid());
const char* const childProcessType =
XRE_ChildProcessTypeToString(mProcessType);
//--------------------------------------------------
#if defined(OS_POSIX)
// For POSIX, we have to be extremely anal about *not* using
// std::wstring in code compiled with Mozilla's -fshort-wchar
// configuration, because chromium is compiled with -fno-short-wchar
// and passing wstrings from one config to the other is unsafe. So
// we split the logic here.
FilePath exePath = FilePath(CommandLine::ForCurrentProcess()->argv()[0]);
exePath = exePath.DirName();
exePath = exePath.AppendASCII(MOZ_CHILD_PROCESS_NAME);
// remap the IPC socket fd to a well-known int, as the OS does for
// STDOUT_FILENO, for example
int srcChannelFd, dstChannelFd;
channel().GetClientFileDescriptorMapping(&srcChannelFd, &dstChannelFd);
mFileMap.push_back(std::pair<int,int>(srcChannelFd, dstChannelFd));
// no need for kProcessChannelID, the child process inherits the
// other end of the socketpair() from us
std::vector<std::string> childArgv;
childArgv.push_back(exePath.value());
childArgv.insert(childArgv.end(), aExtraOpts.begin(), aExtraOpts.end());
childArgv.push_back(pidstring);
childArgv.push_back(childProcessType);
base::LaunchApp(childArgv, mFileMap, false, &process);
//--------------------------------------------------
#elif defined(OS_WIN)
FilePath exePath =
FilePath::FromWStringHack(CommandLine::ForCurrentProcess()->program());
exePath = exePath.DirName();
exePath = exePath.AppendASCII(MOZ_CHILD_PROCESS_NAME);
CommandLine cmdLine(exePath.ToWStringHack());
cmdLine.AppendSwitchWithValue(switches::kProcessChannelID, channel_id());
for (std::vector<std::string>::iterator it = aExtraOpts.begin();
it != aExtraOpts.end();
++it) {
cmdLine.AppendLooseValue(UTF8ToWide(*it));
}
cmdLine.AppendLooseValue(UTF8ToWide(pidstring));
cmdLine.AppendLooseValue(UTF8ToWide(childProcessType));
cmdLine.AppendLooseValue(UTF8ToWide(XRE_ChildProcessTypeToString(mProcessType)));
base::ProcessHandle process;
#if defined(OS_WIN)
base::LaunchApp(cmdLine, false, false, &process);
#elif defined(OS_POSIX)
base::LaunchApp(cmdLine.argv(), mFileMap, false, &process);
#else
#error Bad!
# error Sorry
#endif
if (!process) {

View File

@ -61,8 +61,8 @@ public:
GeckoChildProcessHost(GeckoProcessType aProcessType=GeckoProcessType_Default,
base::WaitableEventWatcher::Delegate* aDelegate=nsnull);
bool SyncLaunch(std::vector<std::wstring> aExtraOpts=std::vector<std::wstring>());
bool AsyncLaunch(std::vector<std::wstring> aExtraOpts=std::vector<std::wstring>());
bool SyncLaunch(std::vector<std::string> aExtraOpts=std::vector<std::string>());
bool AsyncLaunch(std::vector<std::string> aExtraOpts=std::vector<std::string>());
virtual void OnChannelConnected(int32 peer_pid);
virtual void OnMessageReceived(const IPC::Message& aMsg);

View File

@ -64,7 +64,14 @@ ScopedXREEmbed::~ScopedXREEmbed()
void
ScopedXREEmbed::Start()
{
std::string path = WideToUTF8(CommandLine::ForCurrentProcess()->program());
std::string path;
#if defined(OS_WIN)
path = WideToUTF8(CommandLine::ForCurrentProcess()->program());
#elif defined(OS_POSIX)
path = CommandLine::ForCurrentProcess()->argv()[0];
#else
# error Sorry
#endif
nsCOMPtr<nsILocalFile> localFile;
nsresult rv = XRE_GetBinaryPath(path.c_str(), getter_AddRefs(localFile));

View File

@ -35,15 +35,17 @@ const char* const
IPDLUnitTestName()
{
if (!gIPDLUnitTestName) {
#if defined(OS_WIN)
std::vector<std::wstring> args =
CommandLine::ForCurrentProcess()->GetLooseValues();
gIPDLUnitTestName = strdup(WideToUTF8(args[
#ifndef OS_WIN
args.size()-1
gIPDLUnitTestName = strdup(WideToUTF8(args[0]).c_str());
#elif defined(OS_POSIX)
std::vector<std::string> argv =
CommandLine::ForCurrentProcess()->argv();
gIPDLUnitTestName = strdup(argv[1].c_str());
#else
args.size()-2
# error Sorry
#endif
]).c_str());
}
return gIPDLUnitTestName;
}
@ -129,9 +131,8 @@ IPDLUnitTestMain(void* aData)
}
gIPDLUnitTestName = testString;
std::wstring testWString = UTF8ToWide(testString);
std::vector<std::wstring> testCaseArgs;
testCaseArgs.push_back(testWString);
std::vector<std::string> testCaseArgs;
testCaseArgs.push_back(testString);
IPDLUnitTestSubprocess* subprocess = new IPDLUnitTestSubprocess();
if (!subprocess->SyncLaunch(testCaseArgs))