!C99Shell v. 2.0 [PHP 7 Update] [25.02.2019]!

Software: Apache. PHP/5.6.40 

uname -a: Linux cpanel06wh.bkk1.cloud.z.com 2.6.32-954.3.5.lve1.4.80.el6.x86_64 #1 SMP Thu Sep 24
01:42:00 EDT 2020 x86_64
 

uid=851(cp949260) gid=853(cp949260) groups=853(cp949260) 

Safe-mode: OFF (not secure)

/opt/passenger-5.3.7-4.el6.cloudlinux/src/cxx_supportlib/SystemTools/   drwxr-xr-x
Free 235.39 GB of 981.82 GB (23.97%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     ProcessMetricsCollector.h (13.76 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
 *  Phusion Passenger - https://www.phusionpassenger.com/
 *  Copyright (c) 2010-2018 Phusion Holding B.V.
 *
 *  "Passenger", "Phusion Passenger" and "Union Station" are registered
 *  trademarks of Phusion Holding B.V.
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"), to deal
 *  in the Software without restriction, including without limitation the rights
 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *  copies of the Software, and to permit persons to whom the Software is
 *  furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *  THE SOFTWARE.
 */
#ifndef _PASSENGER_SYSTEM_TOOLS_PROCESS_METRICS_COLLECTOR_H_
#define _PASSENGER_SYSTEM_TOOLS_PROCESS_METRICS_COLLECTOR_H_

#include <boost/cstdint.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <oxt/system_calls.hpp>
#include <string>
#include <vector>
#include <map>

#ifdef __APPLE__
    #include <mach/mach_traps.h>
    #include <mach/mach_init.h>
    #include <mach/mach_vm.h>
    #include <mach/mach_port.h>
#endif
#if !defined(__NetBSD__) && !defined(__OpenBSD__)
    // NetBSD does not support -p with multiple PIDs.
    // https://code.google.com/p/phusion-passenger/issues/detail?id=736
    // OpenBSD 5.2 doesn't support it either
    #define PS_SUPPORTS_MULTIPLE_PIDS
    #include <set>
#endif

#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <signal.h>
#include <cstdlib>
#include <cerrno>
#include <cstring>

#include <StaticString.h>
#include <Exceptions.h>
#include <ProcessManagement/Spawn.h>
#include <FileTools/FileManip.h>
#include <Utils/ScopeGuard.h>
#include <IOTools/IOUtils.h>
#include <StrIntTools/StringScanning.h>

namespace Passenger {

using namespace boost;
using namespace std;
using namespace oxt;

/** All sizes are in KB. */
struct ProcessMetrics {
    pid_t   pid;
    pid_t   ppid;
    boost::uint8_t cpu;
    /** Resident Set Size, amount of memory in RAM. Does not include swap.
     * -1 if not yet known, 0 if completely swapped out.
     */
    ssize_t  rss;
    /** Proportional Set Size, see measureRealMemory(). Does not include swap.
     * -1 if unknown, 0 if completely swapped out.
     */
    ssize_t  pss;
    /** Private dirty RSS, see measureRealMemory(). Does not include swap.
     * -1 if unknown, 0 if completely swapped out.
     */
    ssize_t  privateDirty;
    /** Amount of memory in swap.
     * -1 if unknown, 0 if no swap used.
     */
    ssize_t  swap;
    /** OS X Snow Leopard does not report the VM size correctly, so don't use this. */
    ssize_t  vmsize;
    pid_t   processGroupId;
    uid_t   uid;
    string  command;

    ProcessMetrics() {
        pid = (pid_t) -1;
        ppid = (pid_t) -1;
        cpu = -1;
        rss = -1;
        pss = -1;
        privateDirty = -1;
        swap = -1;
        vmsize = -1;
        processGroupId = (pid_t) -1;
        uid = (uid_t) -1;
    }

    bool isValid() const {
        return pid != (pid_t) -1;
    }

    /**
     * Returns an estimate of the "real" memory usage of a process in KB.
     * We don't use the PSS here because that would mean if another
     * process that shares memory quits, this process's memory usage
     * would suddenly go up.
     */
    size_t realMemory() const {
        ssize_t swap;
        if (this->swap != -1) {
            swap = this->swap;
        } else {
            swap = 0;
        }
        if (privateDirty != -1) {
            return privateDirty + swap;
        } else if (rss != -1) {
            return rss + swap;
        } else {
            return 0;
        }
    }
};

class ProcessMetricMap: public map<pid_t, ProcessMetrics> {
public:
    /**
     * Returns the total memory usage of all processes in KB, possibly
     * including shared memory.
     * If measurable, the return value only includes the processes' private
     * memory usage (swap is accounted for), and <em>shared</em> is set to the
     * amount of shared memory.
     * If not measurable, then the return value is an estimate of the total
     * memory usage of all processes (which may or may not include shared memory
     * as well), and <em>shared</em> is set to -1.
     */
    size_t totalMemory(ssize_t &shared) const {
        const_iterator it, end = this->end();
        bool pssAndPrivateDirtyAvailable = true;

        for (it = begin(); it != end && pssAndPrivateDirtyAvailable; it++) {
            const ProcessMetrics &metric = it->second;
            pssAndPrivateDirtyAvailable = pssAndPrivateDirtyAvailable &&
                metric.pss != -1 && metric.privateDirty != -1;
        }

        if (pssAndPrivateDirtyAvailable) {
            size_t total = 0;
            size_t priv = 0;

            for (it = begin(); it != end; it++) {
                const ProcessMetrics &metric = it->second;
                total += metric.pss;
                priv += metric.privateDirty;
            }

            shared = total - priv;
            return total;
        } else {
            size_t total = 0;

            for (it = begin(); it != end; it++) {
                const ProcessMetrics &metric = it->second;
                total += metric.realMemory();
            }

            shared = -1;
            return total;
        }
    }
};

/**
 * Utility class for collection metrics on processes, such as CPU usage, memory usage,
 * command name, etc.
 */
class ProcessMetricsCollector {
private:
    bool canMeasureRealMemory;
    string psOutput;

    template<typename Collection, typename ConstIterator>
    ProcessMetricMap parsePsOutput(const string &output, const Collection &allowedPids) const {
        ProcessMetricMap result;
        const char *start = output.c_str();

        // Ignore first line, it contains the column names.
        if (!skipToNextLine(&start) || *start == '\0') {
            start = NULL;
        }

        #ifndef PS_SUPPORTS_MULTIPLE_PIDS
            set<pid_t> pids;
            ConstIterator it, end = allowedPids.end();
            for (it = allowedPids.begin(); it != allowedPids.end(); it++) {
                pids.insert(*it);
            }
        #endif

        // Parse each line.
        while (start != NULL) {
            ProcessMetrics metrics;

            metrics.pid  = (pid_t) readNextWordAsLongLong(&start);
            metrics.ppid = (pid_t) readNextWordAsLongLong(&start);
            metrics.cpu  = readNextWordAsInt(&start);
            metrics.rss  = (size_t) readNextWordAsLongLong(&start);
            metrics.vmsize  = (size_t) readNextWordAsLongLong(&start);
            metrics.processGroupId = (pid_t) readNextWordAsLongLong(&start);
            metrics.uid  = (uid_t) readNextWordAsLongLong(&start);
            metrics.command = readRestOfLine(start);

            bool pidAllowed;
            #ifdef PS_SUPPORTS_MULTIPLE_PIDS
                pidAllowed = true;
            #else
                pidAllowed = pids.find(metrics.pid) != pids.end();
            #endif

            if (pidAllowed) {
                result[metrics.pid] = metrics;

                start = strchr(start, '\n');
                if (start != NULL) {
                    // Skip to beginning of next line.
                    start++;
                    if (*start == '\0') {
                        start = NULL;
                    }
                }
            }
        }
        return result;
    }

    static void afterFork() {
        // Make ps nicer, we want to have as little impact on the rest
        // of the system as possible while collecting the metrics.
        int prio = getpriority(PRIO_PROCESS, getpid());
        prio++;
        if (prio > 20) {
            prio = 20;
        }
        setpriority(PRIO_PROCESS, getpid(), prio);
    }

public:
    ProcessMetricsCollector() {
        #ifdef __APPLE__
            canMeasureRealMemory = true;
        #else
            canMeasureRealMemory = fileExists("/proc/self/smaps");
        #endif
    }

    /** Mock 'ps' output, used by unit tests. */
    void setPsOutput(const string &data) {
        this->psOutput = data;
    }

    /**
     * Collect metrics for the given process IDs. Nonexistant PIDs are not
     * included in the result.
     *
     * Returns a map which maps a given PID to its collected metrics.
     *
     * @throws ParseException The ps output cannot be parsed.
     * @throws SystemException Error collecting the ps output or error querying memory usage.
     */
    template<typename Collection, typename ConstIterator>
    ProcessMetricMap collect(const Collection &pids) const {
        if (pids.empty()) {
            return ProcessMetricMap();
        }

        ConstIterator it;
        // The list of PIDs must follow -p without a space.
        // https://groups.google.com/forum/#!topic/phusion-passenger/WKXy61nJBMA
        string pidsArg = "-p";

        for (it = pids.begin(); it != pids.end(); it++) {
            pidsArg.append(toString(*it));
            pidsArg.append(",");
        }
        if (pidsArg[pidsArg.size() - 1] == ',') {
            pidsArg.resize(pidsArg.size() - 1);
        }

        // The list of format arguments must also follow -o
        // without a space.
        // https://github.com/phusion/passenger/pull/94
        string fmtArg = "-o";
        #if defined(sun) || defined(__sun)
            fmtArg.append("pid,ppid,pcpu,rss,vsz,pgid,uid,args");
        #else
            fmtArg.append("pid,ppid,%cpu,rss,vsize,pgid,uid,command");
        #endif

        const char *command[] = {
            "ps", fmtArg.c_str(),
            #ifdef PS_SUPPORTS_MULTIPLE_PIDS
                pidsArg.c_str(),
            #endif
            NULL
        };

        SubprocessOutput psOutput;
        psOutput.data = this->psOutput;
        if (psOutput.data.empty()) {
            SubprocessInfo info;
            runCommandAndCaptureOutput(command, info, psOutput,
                1024 * 1024, true, afterFork);
            if (psOutput.data.empty()) {
                throw RuntimeException("The 'ps' command failed");
            }
        }
        pidsArg.resize(0);
        fmtArg.resize(0);
        ProcessMetricMap result = parsePsOutput<Collection, ConstIterator>(
            psOutput.data, pids);
        psOutput.data.resize(0);
        if (canMeasureRealMemory) {
            ProcessMetricMap::iterator it;
            for (it = result.begin(); it != result.end(); it++) {
                ProcessMetrics &metric = it->second;
                measureRealMemory(metric.pid, metric.pss,
                    metric.privateDirty, metric.swap);
            }
        }
        return result;
    }

    ProcessMetricMap collect(const vector<pid_t> &pids) const {
        return collect< vector<pid_t>, vector<pid_t>::const_iterator >(pids);
    }

    /**
     * Attempt to measure various parts of a process's memory usage that may
     * contribute to insight as to what its "real" memory usage might be.
     * Collected information are:
     * - The proportional set size: total size of a process's pages that are in
     *   memory, where the size of each page is divided by the number of processes
     *   sharing it.
     * - The private dirty RSS.
     * - Amount of memory in swap.
     *
     * At this time only OS X and recent Linux versions (>= 2.6.25) support
     * measuring the proportional set size. Usually root privileges are required.
     *
     * pss, privateDirty and swap can each be individually set to -1 if that
     * part cannot be measured, e.g. because we do not have permission
     * to do so or because the OS does not support measuring it.
     */
    static void measureRealMemory(pid_t pid, ssize_t &pss, ssize_t &privateDirty, ssize_t &swap) {
        #ifdef __APPLE__
            kern_return_t ret;
            mach_port_t task;

            swap = -1;

            ret = task_for_pid(mach_task_self(), pid, &task);
            if (ret != KERN_SUCCESS) {
                pss = -1;
                privateDirty = -1;
                return;
            }

            mach_vm_address_t addr = 0;
            int pagesize = getpagesize();

            // In bytes.
            pss = 0;
            privateDirty = 0;

            while (true) {
                mach_vm_address_t size;
                vm_region_top_info_data_t info;
                mach_msg_type_number_t count = VM_REGION_TOP_INFO_COUNT;
                mach_port_t object_name;

                ret = mach_vm_region(task, &addr, &size, VM_REGION_TOP_INFO,
                    (vm_region_info_t) &info, &count, &object_name);
                if (ret != KERN_SUCCESS) {
                    break;
                }

                if (info.share_mode == SM_PRIVATE) {
                    // shared_pages_resident here means that region
                    // has shared memory only "shared" between 1 process.
                    pss += info.private_pages_resident * pagesize;
                    pss += info.shared_pages_resident * pagesize;
                    privateDirty += info.private_pages_resident * pagesize;
                } else if (info.share_mode == SM_COW) {
                    pss += info.private_pages_resident * pagesize;
                    pss += info.shared_pages_resident * pagesize / info.ref_count;
                    privateDirty += info.private_pages_resident * pagesize;
                } else if (info.share_mode == SM_SHARED) {
                    pss += info.shared_pages_resident * pagesize / info.ref_count;
                }

                addr += size;
            }

            mach_port_deallocate(mach_task_self(), task);

            // Convert result back to KB.
            pss /= 1024;
            privateDirty /= 1024;
        #else
            string smapsFilename = "/proc/";
            smapsFilename.append(toString(pid));
            smapsFilename.append("/smaps");

            FILE *f = syscalls::fopen(smapsFilename.c_str(), "r");
            if (f == NULL) {
                error:
                pss = -1;
                privateDirty = -1;
                swap = -1;
                return;
            }

            StdioGuard guard(f, NULL, 0);
            bool hasPss = false;
            bool hasPrivateDirty = false;
            bool hasSwap = false;

            // In KB.
            pss = 0;
            privateDirty = 0;
            swap = 0;

            while (!feof(f)) {
                char line[1024 * 4];
                const char *buf;

                buf = fgets(line, sizeof(line), f);
                if (buf == NULL) {
                    if (ferror(f)) {
                        goto error;
                    } else {
                        break;
                    }
                }
                try {
                    if (startsWith(line, "Pss:")) {
                        /* Linux supports Proportional Set Size since kernel 2.6.25.
                         * See kernel commit ec4dd3eb35759f9fbeb5c1abb01403b2fde64cc9.
                         */
                        hasPss = true;
                        readNextWord(&buf);
                        pss += readNextWordAsLongLong(&buf);
                        if (readNextWord(&buf) != "kB") {
                            goto error;
                        }
                    } else if (startsWith(line, "Private_Dirty:")) {
                        hasPrivateDirty = true;
                        readNextWord(&buf);
                        privateDirty += readNextWordAsLongLong(&buf);
                        if (readNextWord(&buf) != "kB") {
                            goto error;
                        }
                    } else if (startsWith(line, "Swap:")) {
                        hasSwap = true;
                        readNextWord(&buf);
                        swap += readNextWordAsLongLong(&buf);
                        if (readNextWord(&buf) != "kB") {
                            goto error;
                        }
                    }
                } catch (const ParseException &) {
                    goto error;
                }
            }

            if (!hasPss) {
                pss = -1;
            }
            if (!hasPrivateDirty) {
                privateDirty = -1;
            }
            if (!hasSwap) {
                swap = -1;
            }
        #endif
    }
};

} // namespace Passenger

#endif /* _PASSENGER_SYSTEM_TOOLS_PROCESS_METRICS_COLLECTOR_H_ */

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.0 [PHP 7 Update] [25.02.2019] maintained by KaizenLouie | C99Shell Github | Generation time: 0.1275 ]--