From f082de03ff24ae8cc6a2de103bc643c392135742 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Thu, 12 Jan 2012 16:36:56 -0700 Subject: fix for SH-2845, SH-2846, SH-2847, SH-2851: curl crashes and out-of-memory crashes. --- .../updater/llupdatedownloader.cpp | 23 +++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'indra/viewer_components/updater') diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index e88d1bf811..19ac418e9e 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -39,7 +39,7 @@ #include "llsdserialize.h" #include "llthread.h" #include "llupdaterservice.h" - +#include "llcurl.h" class LLUpdateDownloader::Implementation: public LLThread @@ -198,13 +198,19 @@ LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client & LLUpdateDownloader::Implementation::~Implementation() { - if(isDownloading()) { + if(isDownloading()) + { cancel(); shutdown(); - } else { + } + else + { ; // No op. } - if(mCurl) curl_easy_cleanup(mCurl); + if(mCurl) + { + LLCurl::deleteEasyHandle(mCurl); + } } @@ -406,9 +412,12 @@ void LLUpdateDownloader::Implementation::run(void) void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & url, bool processHeader) { - if(mCurl == 0) { - mCurl = curl_easy_init(); - } else { + if(mCurl == 0) + { + mCurl = LLCurl::newEasyHandle(); + } + else + { curl_easy_reset(mCurl); } -- cgit v1.2.3 From c0731c1c05cafe508c91c5f583301234ba3b8403 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 17 Jan 2012 18:55:42 -0500 Subject: Add log message if LLProcessLauncher child fails to execv(). On a Posix platform (vfork()/execv() implementation), if for any reason the execv() failed (e.g. executable not on PATH), the viewer would never know, nor the user: the vfork() child produced no output, and terminated with rc 0! Add logging, make child terminate with nonzero rc. Remove pointless addArgument(const char*) overload: this does nothing for you that the compiler won't do implicitly. In llupdateinstaller.cpp, remove pointless c_str() call in addArgument() arg: we were starting with a std::string, then extracting its c_str(), only to construct a whole new std::string from it! --- indra/viewer_components/updater/llupdateinstaller.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/viewer_components/updater') diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp index c7b70c2de8..84f23b3acc 100644 --- a/indra/viewer_components/updater/llupdateinstaller.cpp +++ b/indra/viewer_components/updater/llupdateinstaller.cpp @@ -81,7 +81,7 @@ int ll_install_update(std::string const & script, LLProcessLauncher launcher; launcher.setExecutable(actualScriptPath); launcher.addArgument(updatePath); - launcher.addArgument(ll_install_failed_marker_path().c_str()); + launcher.addArgument(ll_install_failed_marker_path()); launcher.addArgument(boost::lexical_cast(required)); int result = launcher.launch(); launcher.orphan(); -- cgit v1.2.3 From f0dbb878337082d3f581874c12e6df2f4659a464 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 20 Jan 2012 18:10:40 -0500 Subject: Per Richard, replace LLProcessLauncher with LLProcess. LLProcessLauncher had the somewhat fuzzy mandate of (1) accumulating parameters with which to launch a child process and (2) sometimes tracking the lifespan of the ensuing child process. But a valid LLProcessLauncher object might or might not have ever been associated with an actual child process. LLProcess specifically tracks a child process. In effect, it's a fairly thin wrapper around a process HANDLE (on Windows) or pid_t (elsewhere), with lifespan management thrown in. A static LLProcess::create() method launches a new child; create() accepts an LLSD bundle with child parameters. So building up a parameter bundle is deferred to LLSD rather than conflated with the process management object. Reconcile all known LLProcessLauncher consumers in the viewer code base, notably the class unit tests. --- .../viewer_components/updater/llupdateinstaller.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'indra/viewer_components/updater') diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp index 84f23b3acc..e99fd0af7e 100644 --- a/indra/viewer_components/updater/llupdateinstaller.cpp +++ b/indra/viewer_components/updater/llupdateinstaller.cpp @@ -26,10 +26,10 @@ #include "linden_common.h" #include #include "llapr.h" -#include "llprocesslauncher.h" +#include "llprocess.h" #include "llupdateinstaller.h" #include "lldir.h" - +#include "llsd.h" #if defined(LL_WINDOWS) #pragma warning(disable: 4702) // disable 'unreachable code' so we can use lexical_cast (really!). @@ -78,15 +78,13 @@ int ll_install_update(std::string const & script, llinfos << "UpdateInstaller: installing " << updatePath << " using " << actualScriptPath << LL_ENDL; - LLProcessLauncher launcher; - launcher.setExecutable(actualScriptPath); - launcher.addArgument(updatePath); - launcher.addArgument(ll_install_failed_marker_path()); - launcher.addArgument(boost::lexical_cast(required)); - int result = launcher.launch(); - launcher.orphan(); - - return result; + LLSD params; + params["executable"] = actualScriptPath; + params["args"].append(updatePath); + params["args"].append(ll_install_failed_marker_path()); + params["args"].append(boost::lexical_cast(required)); + params["autokill"] = false; + return LLProcess::create(params)? 0 : -1; } -- cgit v1.2.3 From 47d94757075e338c480ba4d7d24948242a85a9bb Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Sat, 21 Jan 2012 11:45:15 -0500 Subject: Convert LLProcess consumers from LLSD to LLProcess::Params block. Using a Params block gives compile-time checking against attribute typos. One might inadvertently set myLLSD["autofill"] = false and only discover it when things behave strangely at runtime; but trying to set myParams.autofill will produce a compile error. However, it's excellent that the same LLProcess::create() method can accept either LLProcess::Params or a properly-constructed LLSD block. --- indra/viewer_components/updater/llupdateinstaller.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'indra/viewer_components/updater') diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp index e99fd0af7e..2f87d59373 100644 --- a/indra/viewer_components/updater/llupdateinstaller.cpp +++ b/indra/viewer_components/updater/llupdateinstaller.cpp @@ -78,12 +78,12 @@ int ll_install_update(std::string const & script, llinfos << "UpdateInstaller: installing " << updatePath << " using " << actualScriptPath << LL_ENDL; - LLSD params; - params["executable"] = actualScriptPath; - params["args"].append(updatePath); - params["args"].append(ll_install_failed_marker_path()); - params["args"].append(boost::lexical_cast(required)); - params["autokill"] = false; + LLProcess::Params params; + params.executable = actualScriptPath; + params.args.add(updatePath); + params.args.add(ll_install_failed_marker_path()); + params.args.add(boost::lexical_cast(required)); + params.autokill = false; return LLProcess::create(params)? 0 : -1; } -- cgit v1.2.3