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 */