зеркало из https://github.com/mozilla/gecko-dev.git
bug 523894: wstrings are bad news in OPT builds due to chromium/Mozilla -fshort-wchar mismatch
This commit is contained in:
Родитель
6586059db9
Коммит
2eb8767355
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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))
|
||||
|
|
Загрузка…
Ссылка в новой задаче