netwerk/protocol/about/nsAboutBloat.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/netwerk/protocol/about/nsAboutBloat.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,140 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#include "nsTraceRefcnt.h"
    1.10 +
    1.11 +// if NS_BUILD_REFCNT_LOGGING isn't defined, don't try to build
    1.12 +#ifdef NS_BUILD_REFCNT_LOGGING
    1.13 +
    1.14 +#include "nsAboutBloat.h"
    1.15 +#include "nsStringStream.h"
    1.16 +#include "nsIURI.h"
    1.17 +#include "nsCOMPtr.h"
    1.18 +#include "nsNetUtil.h"
    1.19 +#include "nsDirectoryServiceDefs.h"
    1.20 +#include "nsIFile.h"
    1.21 +
    1.22 +static void GC_gcollect() {}
    1.23 +
    1.24 +NS_IMPL_ISUPPORTS(nsAboutBloat, nsIAboutModule)
    1.25 +
    1.26 +NS_IMETHODIMP
    1.27 +nsAboutBloat::NewChannel(nsIURI *aURI, nsIChannel **result)
    1.28 +{
    1.29 +    NS_ENSURE_ARG_POINTER(aURI);
    1.30 +    nsresult rv;
    1.31 +    nsAutoCString path;
    1.32 +    rv = aURI->GetPath(path);
    1.33 +    if (NS_FAILED(rv)) return rv;
    1.34 +
    1.35 +    nsTraceRefcnt::StatisticsType statType = nsTraceRefcnt::ALL_STATS;
    1.36 +    bool clear = false;
    1.37 +    bool leaks = false;
    1.38 +
    1.39 +    int32_t pos = path.Find("?");
    1.40 +    if (pos > 0) {
    1.41 +        nsAutoCString param;
    1.42 +        (void)path.Right(param, path.Length() - (pos+1));
    1.43 +        if (param.EqualsLiteral("new"))
    1.44 +            statType = nsTraceRefcnt::NEW_STATS;
    1.45 +        else if (param.EqualsLiteral("clear"))
    1.46 +            clear = true;
    1.47 +        else if (param.EqualsLiteral("leaks"))
    1.48 +            leaks = true;
    1.49 +    }
    1.50 +
    1.51 +    nsCOMPtr<nsIInputStream> inStr;
    1.52 +    if (clear) {
    1.53 +        nsTraceRefcnt::ResetStatistics();
    1.54 +
    1.55 +        rv = NS_NewCStringInputStream(getter_AddRefs(inStr),
    1.56 +            NS_LITERAL_CSTRING("Bloat statistics cleared."));
    1.57 +        if (NS_FAILED(rv)) return rv;
    1.58 +    }
    1.59 +    else if (leaks) {
    1.60 +        // dump the current set of leaks.
    1.61 +        GC_gcollect();
    1.62 +    	
    1.63 +        rv = NS_NewCStringInputStream(getter_AddRefs(inStr),
    1.64 +            NS_LITERAL_CSTRING("Memory leaks dumped."));
    1.65 +        if (NS_FAILED(rv)) return rv;
    1.66 +    }
    1.67 +    else {
    1.68 +        nsCOMPtr<nsIFile> file;
    1.69 +        rv = NS_GetSpecialDirectory(NS_OS_CURRENT_PROCESS_DIR, 
    1.70 +                                    getter_AddRefs(file));       
    1.71 +        if (NS_FAILED(rv)) return rv;
    1.72 +
    1.73 +        rv = file->AppendNative(NS_LITERAL_CSTRING("bloatlogs"));
    1.74 +        if (NS_FAILED(rv)) return rv;
    1.75 +
    1.76 +        bool exists;
    1.77 +        rv = file->Exists(&exists);
    1.78 +        if (NS_FAILED(rv)) return rv;
    1.79 +
    1.80 +        if (!exists) {
    1.81 +            // On all the platforms that I know use permissions,
    1.82 +            // directories need to have the executable flag set
    1.83 +            // if you want to do anything inside the directory.
    1.84 +            rv = file->Create(nsIFile::DIRECTORY_TYPE, 0755);
    1.85 +            if (NS_FAILED(rv)) return rv;
    1.86 +        }
    1.87 +
    1.88 +        nsAutoCString dumpFileName;
    1.89 +        if (statType == nsTraceRefcnt::ALL_STATS)
    1.90 +            dumpFileName.AssignLiteral("all-");
    1.91 +        else
    1.92 +            dumpFileName.AssignLiteral("new-");
    1.93 +        PRExplodedTime expTime;
    1.94 +        PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &expTime);
    1.95 +        char time[128];
    1.96 +        PR_FormatTimeUSEnglish(time, 128, "%Y-%m-%d-%H%M%S.txt", &expTime);
    1.97 +        dumpFileName += time;
    1.98 +        rv = file->AppendNative(dumpFileName);
    1.99 +        if (NS_FAILED(rv)) return rv;
   1.100 +
   1.101 +        FILE* out;
   1.102 +        rv = file->OpenANSIFileDesc("w", &out);
   1.103 +        if (NS_FAILED(rv)) return rv;
   1.104 +
   1.105 +        rv = nsTraceRefcnt::DumpStatistics(statType, out);
   1.106 +        ::fclose(out);
   1.107 +        if (NS_FAILED(rv)) return rv;
   1.108 +
   1.109 +        rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), file);
   1.110 +        if (NS_FAILED(rv)) return rv;
   1.111 +    }
   1.112 +
   1.113 +    nsIChannel* channel = nullptr;
   1.114 +    rv = NS_NewInputStreamChannel(&channel, aURI, inStr,
   1.115 +                                  NS_LITERAL_CSTRING("text/plain"),
   1.116 +                                  NS_LITERAL_CSTRING("utf-8"));
   1.117 +    if (NS_FAILED(rv)) return rv;
   1.118 +
   1.119 +    *result = channel;
   1.120 +    return rv;
   1.121 +}
   1.122 +
   1.123 +NS_IMETHODIMP
   1.124 +nsAboutBloat::GetURIFlags(nsIURI *aURI, uint32_t *result)
   1.125 +{
   1.126 +    *result = 0;
   1.127 +    return NS_OK;
   1.128 +}
   1.129 +
   1.130 +nsresult
   1.131 +nsAboutBloat::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
   1.132 +{
   1.133 +    nsAboutBloat* about = new nsAboutBloat();
   1.134 +    if (about == nullptr)
   1.135 +        return NS_ERROR_OUT_OF_MEMORY;
   1.136 +    NS_ADDREF(about);
   1.137 +    nsresult rv = about->QueryInterface(aIID, aResult);
   1.138 +    NS_RELEASE(about);
   1.139 +    return rv;
   1.140 +}
   1.141 +
   1.142 +////////////////////////////////////////////////////////////////////////////////
   1.143 +#endif /* NS_BUILD_REFCNT_LOGGING */

mercurial