为什么"约会"使用" mmap"来映射如此多的内存?

时间:2014-10-24 14:03:16

标签: linux instrumentation system-calls

我写了一个简单的仪器工具(使用Intel Pin API) 跟踪对mmap系统调用的每次调用。 然后我将pintool应用于“date”命令并获得以下输出。 请问几个问题:

1)为什么像“date”这样的简单命令会映射~15 MB?

2)每次调用mmap时,进程的页表都会更新为 包括新创建的映射 - 我是否正确?

3)使用文件描述符-1,内核将0初始化页面。 文件描述符4用于什么?

thread begin 0
   entry: addr 0 , length 8 KB , fd -1
   exit: returned with 0x2b5d7bc08000
   entry: addr 0 , length 101 KB , fd 4
   exit: returned with 0x2b5d7bc66000
   entry: addr 0 , length 2079 KB , fd 4
   exit: returned with 0x2b5d7bcb2000
   entry: addr 0x2b5d7beb8000 , length 8 KB , fd 4
   exit: returned with 0x2b5d7beb8000
   entry: addr 0 , length 3833 KB , fd 4
   exit: returned with 0x2b5d7bed0000
   entry: addr 0x2b5d7c284000 , length 24 KB , fd 4
   exit: returned with 0x2b5d7c284000
   entry: addr 0x2b5d7c28a000 , length 17 KB , fd -1
   exit: returned with 0x2b5d7c28a000
   entry: addr 0 , length 4 KB , fd -1
   exit: returned with 0x2b5d7c2b0000
   entry: addr 0 , length 2161 KB , fd 4
   exit: returned with 0x2b5d7c2ba000
   entry: addr 0x2b5d7c4d1000 , length 8 KB , fd 4
   exit: returned with 0x2b5d7c4d1000
   entry: addr 0x2b5d7c4d3000 , length 13 KB , fd -1
   exit: returned with 0x2b5d7c4d3000
   entry: addr 0 , length 4 KB , fd -1
   exit: returned with 0x2b5d7c4e7000
   entry: addr 0 , length 4 KB , fd -1
   exit: returned with 0x2b5d7c4ee000
   entry: addr 0 , length 4 KB , fd -1
   exit: returned with 0x2b5d7c4f3000
   entry: addr 0 , length 7051 KB , fd 4
   exit: returned with 0x2b5d7c777000
   entry: addr 0 , length 4 KB , fd -1
   exit: returned with 0x2b5d7c5ff000
   entry: addr 0 , length 4 KB , fd -1
   exit: returned with 0x2b5d7c665000
thread end 0 code 0
total mapped 15328 KB

如果有人有兴趣,pintool代码是:

#include <iostream>
#include <fstream>
#include <string>
#include <cassert>
#include <syscall.h>
#include "pin.H"

KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool",
    "o", "PintoolResults.out", "specify output file name");

// Thread specific data
TLS_KEY mlog_key;

void PrintIndent(std::ostream& os, int indent) {
    for (int i=0 ; i<indent ; ++i)
        os << " ";
}

// MLOG - thread specific data that is not handled by the buffering API.
class MLOG {
public:
    MLOG(THREADID tid)
        : indent(3), syscall_num(0), total_mapped(0) {
        std::string output_file_name = KnobOutputFile.Value() + "-" + decstr(tid);
        out.open(output_file_name.c_str());

        if (!out) {
            std::cerr << "Error: could not open output file." << std::endl;
        }
    }

    ~MLOG() {
        out.close();
    }

    /* Public class members */
    std::ofstream out;  // where to write the results
    int indent;
    // 3 integers to save the context before syscalls
    UINT64 syscall_num;
    UINT64 total_mapped;
};

//==============================================================
//  Analysis Routines
//==============================================================

// This routine is executed every time a thread is created.
VOID ThreadStart(THREADID tid, CONTEXT *ctxt, INT32 flags, VOID *v) {
    // There is a new MLOG for every thread
    MLOG * mlog = new MLOG(tid);
    // A thread will need to look up its MLOG, so save pointer in TLS
    PIN_SetThreadData(mlog_key, mlog, tid);

    mlog->out << "thread begin " << tid << std::endl;
}

// This routine is executed every time a thread is destroyed.
VOID ThreadFini(THREADID tid, const CONTEXT *ctxt, INT32 code, VOID *v) {
    MLOG * mlog = static_cast<MLOG*>(PIN_GetThreadData(mlog_key, tid));
    mlog->out << "thread end " << tid << " code " << code << std::endl;
    mlog->out << "total mapped " << std::dec << (mlog->total_mapped>>10ul) << " KB" << std::endl;
    delete mlog;
    PIN_SetThreadData(mlog_key, 0, tid);    
}

VOID SyscallEntry(THREADID tid, CONTEXT *ctxt, SYSCALL_STANDARD std, VOID *v) {
    MLOG * mlog = static_cast<MLOG*>(PIN_GetThreadData(mlog_key, tid));
    mlog->syscall_num = PIN_GetSyscallNumber(ctxt, std);
    UINT64 syscall_arg0 = PIN_GetSyscallArgument(ctxt, std, 0);
    UINT64 syscall_arg1 = PIN_GetSyscallArgument(ctxt, std, 1);
    UINT64 syscall_arg4 = PIN_GetSyscallArgument(ctxt, std, 4);
    if (mlog->syscall_num == SYS_mmap) {
        PrintIndent(mlog->out, mlog->indent);
        mlog->out << "entry: addr " << std::hex << std::showbase << syscall_arg0
            << " , length " << std::dec << (syscall_arg1 >> 10ul) << " KB"
            << " , fd " << std::dec << static_cast<int>(syscall_arg4) << "\n";
        mlog->indent += 1;
        mlog->total_mapped += syscall_arg1;
    }
}

VOID SyscallExit(THREADID tid, CONTEXT *ctxt, SYSCALL_STANDARD std, VOID *v) {
    MLOG* mlog = static_cast<MLOG*>(PIN_GetThreadData(mlog_key, tid));
    UINT64 syscall_num = mlog->syscall_num;
    if (syscall_num == SYS_mmap) {
        mlog->indent -= 1;
        assert(mlog->indent >= 0);
        PrintIndent(mlog->out, mlog->indent);
        mlog->out << "exit: returned with " << std::hex << std::showbase
            << PIN_GetSyscallReturn(ctxt, std) << "\n";
    }
}

/* ===================================================================== */
/* Print Help Message                                                    */
/* ===================================================================== */

INT32 Usage() {
    PIN_ERROR("This Pintool prints a trace of malloc calls in the guest application\n"
              + KNOB_BASE::StringKnobSummary() + "\n");
    return -1;
}

/* ===================================================================== */
/* Main                                                                  */
/* ===================================================================== */

int main(INT32 argc, CHAR **argv) {
    // Initialize pin
    if (PIN_Init(argc, argv)) return Usage();
    PIN_InitSymbols();

    // Register Analysis routines to be called when a thread begins/ends
    PIN_AddThreadStartFunction(ThreadStart, 0);
    PIN_AddThreadFiniFunction(ThreadFini, 0);

    PIN_AddSyscallEntryFunction(SyscallEntry, 0);
    PIN_AddSyscallExitFunction(SyscallExit, 0);

    // Never returns
    PIN_StartProgram();

    return 0;
}

0 个答案:

没有答案