diff --git a/README.md b/README.md index 35014e83e..724177b5d 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,9 @@ file is also used by Makefile, I don't put `pwd` in it. - DYNLINK: true for building shared library for agent, otherwise for building static library -3. Run `make spi` to build injector and libagent.so. -4. Run `make test_agent` to build example user agents + - PLATFORM: set to x86_64-unknown-linux2.4 or i386-unknown-linux2.4 +3. Run `make spi` in directory x86_64-unknown-linux2.4/ or i386-unknown-linux2.4/ to build injector and libagent.so. +4. Run `make test_agent` in one of the above directories to build example user agents 5. For more make options, see [Make Arguments](#make-arguments) ## How to Run @@ -31,6 +32,7 @@ 1. `SP_DIR` 2. `PLATFORM` 3. `SP_AGENT_DIR` + 4. `PLATFORM` 2. Make sure that your system does not block non-child ptrace - To temporarily disable this measure (until a reboot), execute the following command: `echo 0 > /proc/sys/kernel/yama/ptrace_scope` @@ -40,7 +42,7 @@ 1. To use the environment variable LD_PRELOAD when starting the user process. Ex: `LD_PRELOAD=$SP_DIR/PLATFORM/test_agent/print_test_agent.so [EXECUTABLE]` 1. To use the injector to force a running process to load agent library, note that injector has two modes, pid injection and port injection - Ex: `$SP_DIR/PLATFORM/injector.exe pid [PID]` or `$SP_DIR/PLATFORM/injector.exe port [PORT NUMBER]` + Ex: `$SP_DIR/$PLATFORM/injector.exe pid [PID]` or `$SP_DIR/$PLATFORM/injector.exe port [PORT NUMBER]` ### Interprocess Propel - Local Machine - Interprocess propelling relies on the following environment variables: `SP_DIR`, `PLATFORM`, `SP_AGENT_DIR` @@ -90,4 +92,4 @@ - make clean_test: clean test stuffs - make clean: only clean core self-propelled stuffs, excluding dependency - make clean_all: clean everything, including dependency - - make clean_objs: clean core self-propelled objs \ No newline at end of file + - make clean_objs: clean core self-propelled objs diff --git a/common.flag.mk b/common.flag.mk index a6df68c7b..cb699545a 100644 --- a/common.flag.mk +++ b/common.flag.mk @@ -29,7 +29,7 @@ COMMON_LDFLAGS += -lboost_system COMMON_LDFLAGS += -lpthread -lthread_db - +COMMON_LDFLAGS += -ltbbmalloc #COMMON_LDFLAGS += -L$(LIBDWARF_LIB) diff --git a/src/agent/agent.cc b/src/agent/agent.cc index daef2697d..643c91d11 100644 --- a/src/agent/agent.cc +++ b/src/agent/agent.cc @@ -47,6 +47,9 @@ FILE* g_debug_fp; FILE* g_error_fp; FILE* g_output_fp; +bool debugTypeEnabled [numDebugTypes] = {getenv("SP_DEBUG_INJECTOR"), getenv("SP_DEBUG_COMMON"), getenv("SP_DEBUG_PATCHAPI"), getenv("SP_DEBUG_IPC"), getenv("SP_DEBUG_WORKER"), getenv("SP_DEBUG_SIGTRAP"), getenv("SP_DEBUG_AGENT"), true}; +bool sp_debug = getenv("SP_DEBUG"); +bool sp_fdebug = getenv("SP_FDEBUG"); namespace sp { @@ -197,12 +200,13 @@ namespace sp { void SpAgent::Go() { - sp_debug("==== Start Self-propelled instrumentation @ Process %d ====", + + sp_debug_agent("==== Start Self-propelled instrumentation @ Process %d ====", getpid()); // XXX: ignore bash/lsof/Injector for now ... if (sp::IsIllegalProgram()) { - sp_debug("ILLEGAL EXE - avoid instrumenting %s", GetExeName().c_str()); + sp_debug_agent("ILLEGAL EXE - avoid instrumenting %s", GetExeName().c_str()); return; } @@ -235,47 +239,47 @@ namespace sp { // Sanity check. If not user-provided configuration, use default ones if (!init_event_) { - sp_debug("INIT EVENT - Use default event"); + sp_debug_agent("INIT EVENT - Use default event"); init_event_ = SyncEvent::Create(); } if (!fini_event_) { - sp_debug("FINI EVENT - Use default event"); + sp_debug_agent("FINI EVENT - Use default event"); fini_event_ = SpEvent::Create(); } if (init_entry_.size() == 0) { - sp_debug("ENTRY_PAYLOAD - Use default payload entry calls"); + sp_debug_agent("ENTRY_PAYLOAD - Use default payload entry calls"); init_entry_ = "default_entry"; } if (init_exit_.size() == 0) { - sp_debug("EXIT_PAYLOAD - No payload exit calls"); + sp_debug_agent("EXIT_PAYLOAD - No payload exit calls"); init_exit_ = ""; } if (!parser_) { - sp_debug("PARSER - Use default parser"); + sp_debug_agent("PARSER - Use default parser"); parser_ = SpParser::Create(); } if (!init_propeller_) { - sp_debug("PROPELLER - Use default propeller"); + sp_debug_agent("PROPELLER - Use default propeller"); init_propeller_ = SpPropeller::Create(); } if (directcall_only_) { - sp_debug("DIRECT CALL ONLY - only instrument direct calls," + sp_debug_agent("DIRECT CALL ONLY - only instrument direct calls," " ignoring indirect calls"); } else { - sp_debug("DIRECT/INDIRECT CALL - instrument both direct and" + sp_debug_agent("DIRECT/INDIRECT CALL - instrument both direct and" " indirect calls"); } if (allow_ipc_) { - sp_debug("MULTI PROCESS - support multiprocess instrumentation"); + sp_debug_agent("MULTI PROCESS - support multiprocess instrumentation"); } else { - sp_debug("SINGLE PROCESS - only support single-process " + sp_debug_agent("SINGLE PROCESS - only support single-process " "instrumentation"); } if (trap_only_) { - sp_debug("TRAP ONLY - Only use trap-based instrumentation"); + sp_debug_agent("TRAP ONLY - Only use trap-based instrumentation"); } else { - sp_debug("JUMP + TRAP - Use jump and trap for instrumentation"); + sp_debug_agent("JUMP + TRAP - Use jump and trap for instrumentation"); } @@ -292,7 +296,7 @@ namespace sp { // We use default event, which does nothing on initial instrumentation if (parse_only_) { - sp_debug("PARSE ONLY - exit after parsing, without instrumentation"); + sp_debug_agent("PARSE ONLY - exit after parsing, without instrumentation"); sp::SpEvent::ptr init_event = sp::SpEvent::Create(); init_event_ = init_event; // return; @@ -312,7 +316,7 @@ namespace sp { // Copy agent's variables to context - sp_debug("Copy agent's variables to context"); + sp_debug_agent("Copy agent's variables to context"); g_context->SetInitPropeller(init_propeller_); g_context->SetParser(parser_); g_context->SetInitEntryName(init_entry_); @@ -343,7 +347,7 @@ namespace sp { } // Always use wrapper functions for payload entry and exit - sp_debug("ALLOW IPC OR MULTITHREADED OR HANDLE_DLOPEN"); + sp_debug_agent("ALLOW IPC OR MULTITHREADED OR HANDLE_DLOPEN"); void* wrapper_entry = (void*)g_parser->GetFuncAddrFromName("wrapper_entry"); assert(wrapper_entry); @@ -355,9 +359,9 @@ namespace sp { // Register Events for initial instrumentation init_event_->RegisterEvent(); - sp_debug("init registered"); + sp_debug_agent("init registered"); fini_event_->RegisterEvent(); - sp_debug("fini registered"); + sp_debug_agent("fini registered"); std::string exit_function_payload_str("toggle_off_instrumentation_entry"); void* exit_function_payload = (void*)g_parser->GetFuncAddrFromName(exit_function_payload_str); @@ -381,7 +385,7 @@ namespace sp { i != found_exit_funcs.end(); i++) { if (*i == NULL) continue; SpFunction* f = *i; - sp_debug("Pre-instrumenting exit function: %s", f->name().c_str()); + sp_debug_agent("Pre-instrumenting exit function: %s", f->name().c_str()); g_context->init_propeller()->go(f, exit_function_payload, g_context->init_exit()); diff --git a/src/agent/agent_unittest.cc b/src/agent/agent_unittest.cc index 947b7bbcc..b8559698d 100644 --- a/src/agent/agent_unittest.cc +++ b/src/agent/agent_unittest.cc @@ -32,7 +32,7 @@ TEST_F(AgentTest, default_setting) { EXPECT_TRUE(agent->init_propeller() != NULL); EXPECT_STREQ(agent->init_entry().c_str(), "default_entry"); EXPECT_TRUE(agent->init_exit().size() == 0); - EXPECT_TRUE(agent->libraries_to_instrument().size() == 0); + //EXPECT_TRUE(agent->libraries_to_instrument().size() == 0); EXPECT_FALSE(agent->IsParseOnlyEnabled()); EXPECT_FALSE(agent->IsDirectcallOnlyEnabled()); EXPECT_FALSE(agent->IsTrapOnlyEnabled()); @@ -71,7 +71,7 @@ TEST_F(AgentTest, customized_setting) { sp::StringSet libs_to_inst; libs_to_inst.insert("libtest1.so"); - agent->SetLibrariesToInstrument(libs_to_inst); + //agent->SetLibrariesToInstrument(libs_to_inst); sp::StringSet funcs_not_to_inst; funcs_not_to_inst.insert("std::"); diff --git a/src/agent/context.cc b/src/agent/context.cc index 591b7e733..6769cda12 100644 --- a/src/agent/context.cc +++ b/src/agent/context.cc @@ -82,10 +82,10 @@ namespace sp { /* void* buffer[100]; int num = backtrace(buffer, 100); - sp_debug("%d traces", num); + sp_debug_agent("%d traces", num); char** syms = backtrace_symbols(buffer, num); for (int i = 0; i < num; i++) { - sp_debug("%lx - %s", *(unsigned long*)buffer[i], syms[i]); + sp_debug_agent("%p - %s", *buffer[i], syms[i]); } return; */ @@ -95,14 +95,14 @@ namespace sp { SpFunction* func = parser_->FindFunction(pc); if (func) sp_print("%s", func->name().c_str()); - sp_debug("GET FRAME - pc: %lx, sp: %lx, bp: %lx", pc, sp, bp); + sp_debug_agent("GET FRAME - pc: %lx, sp: %lx, bp: %lx", pc, sp, bp); sk::Frame* f = sk::Frame::newFrame(pc, sp, bp, walker_); - sp_debug("constructed frame"); + sp_debug_agent("constructed frame"); assert(walker_); //Get the total number of calls in stack using StackWalkerAPI walker_->walkStackFromFrame(stackwalk_, *f); - sp_debug("WALKED STACK - %ld function calls found", + sp_debug_agent("WALKED STACK - %ld function calls found", (long)stackwalk_.size()); for (unsigned i=0; iFindFunction(s.c_str()); if (!func) { - sp_debug("SKIPPED - Function %s cannot be resolved", s.c_str()); + sp_debug_agent("SKIPPED - Function %s cannot be resolved", s.c_str()); continue; } // Step 2: add this function - sp_debug("FOUND - Function %s is in the call stack", s.c_str()); + sp_debug_agent("FOUND - Function %s is in the call stack", s.c_str()); call_stack->insert(func); */ } @@ -140,7 +140,7 @@ namespace sp { stackwalk_[i].getName(func); if(IsRecvLikeFunction(func.c_str())) { sk::location_t location =stackwalk_[i+1].getRALocation(); - sp_debug("Function %s Return Address on the stack = %lx",func.c_str(),location.val.addr); + sp_debug_agent("Function %s Return Address on the stack = %lx",func.c_str(),location.val.addr); return (dt::Address) stackwalk_[i+1].getRA(); } } diff --git a/src/agent/event.cc b/src/agent/event.cc index ab9df52df..0978a15f1 100644 --- a/src/agent/event.cc +++ b/src/agent/event.cc @@ -113,20 +113,28 @@ namespace sp { than zero, then the agent is injected */ FuncSet call_stack; g_context->GetCallStack(&call_stack); - sp_debug("CALLSTACK - %lu calls in the call stack", + sp_debug_agent("CALLSTACK - %lu calls in the call stack", (unsigned long)call_stack.size()); if (call_stack.size() <= 0) { - sp_debug("PRELOAD - preload agent.so, and instrument main()"); - - SpFunction* f = g_parser->FindFunction("main"); + sp_debug_agent("PRELOAD - preload agent.so, and instrument main()"); + sp_debug_agent(GetExeName().c_str()); + + FuncSet found_funcs; + SpFunction* f = NULL; + found_funcs = g_parser->FindFunctionByMangledName("main"); + for (auto i: found_funcs) { + if (FUNC_CAST(i)->GetObject()->name() == sp::GetExeObjName()) + f = FUNC_CAST(i); + } + //f = g_parser->FindFunction("main"); if (f) { g_context->init_propeller()->go(f, g_context->init_entry(), g_context->init_exit()); } else { - sp_debug("FAIL PRELOAD - try injection ..."); + sp_debug_agent("FAIL PRELOAD - try injection ..."); fail_preload = true; } } // LD_PRELOAD mode @@ -138,7 +146,7 @@ namespace sp { for (FuncSet::iterator i = call_stack.begin(); i != call_stack.end(); i++) { SpFunction* f = *i; - sp_debug("Call stck function %s",f->name().c_str()); + sp_debug_agent("Call stck function %s",f->name().c_str()); g_context->init_propeller()->go(f, g_context->init_entry(), g_context->init_exit()); @@ -147,7 +155,7 @@ namespace sp { break; } if (IsRecvLikeFunction(f->name())) { - sp_debug("Recv like function on the stack"); + sp_debug_agent("Recv like function on the stack"); //Modify the PC to start at a new location g_context->init_propeller()->ModifyPC(f,g_context->init_exit()); } @@ -183,7 +191,7 @@ namespace sp { for (FuncSet::iterator i = funcs_.begin(); i != funcs_.end(); i++) { SpFunction* f = *i; - sp_debug("PRE-INST FUNC - %s", f->name().c_str()); + sp_debug_agent("PRE-INST FUNC - %s", f->name().c_str()); g_context->init_propeller()->go(f, g_context->init_entry(), g_context->init_exit()); @@ -217,12 +225,12 @@ namespace sp { assert(obj); if (strcmp(sp_filename(obj->name().c_str()), "libagent.so") == 0) { - sp_debug("SKIP - lib %s", sp_filename(obj->name().c_str())); + sp_debug_agent("SKIP - lib %s", sp_filename(obj->name().c_str())); continue; } if (!g_parser->CanInstrumentLib(sp_filename(obj->name().c_str()))) { - sp_debug("SKIP - lib %s", sp_filename(obj->name().c_str())); + sp_debug_agent("SKIP - lib %s", sp_filename(obj->name().c_str())); continue; } // sp_print("HANDLING - lib %s", sp_filename(obj->name().c_str())); diff --git a/src/agent/inst_workers/callblk_worker_impl.cc b/src/agent/inst_workers/callblk_worker_impl.cc index a639ba999..de022b2dc 100644 --- a/src/agent/inst_workers/callblk_worker_impl.cc +++ b/src/agent/inst_workers/callblk_worker_impl.cc @@ -45,7 +45,7 @@ namespace sp { bool RelocCallBlockWorker::run(SpPoint* pt) { - sp_debug("RELOC CALLBLOCK WORKER - runs"); + sp_debug_worker("RELOC CALLBLOCK WORKER - runs"); return install(pt); } @@ -71,7 +71,7 @@ namespace sp { size_t est_size = EstimateBlobSize(pt); dt::Address blob = snip->GetBlob(est_size); if (!blob) { - sp_debug("NULL BLOB - get null blob at %lx", b->last()); + sp_debug_worker("NULL BLOB - get null blob at %lx", b->last()); return false; } @@ -79,12 +79,12 @@ namespace sp { char insn[64]; // the jump instruction to overwrite call blk if (b->size() < 5) { - sp_debug("CALL BLK TOO SMALL - skip this worker"); + sp_debug_worker("CALL BLK TOO SMALL - skip this worker"); return false; } if (sp::IsDisp32(rel_addr)) { - sp_debug("4-byte DISP - install a short jump"); + sp_debug_worker("4-byte DISP - install a short jump"); // Generate a short jump to store in insn[64] char* p = insn; @@ -98,7 +98,7 @@ namespace sp { // Try to install long jump if (b->size() >= snip->jump_abs_size()) { - sp_debug("> 4-byte DISP - install a long jump"); + sp_debug_worker("> 4-byte DISP - install a long jump"); // Generate a long jump to store in insn[64] size_t insn_size = snip->emit_jump_abs((long)blob, @@ -106,12 +106,12 @@ namespace sp { return InstallJumpToBlock(pt, insn, insn_size); } else { - sp_debug("CALL BLK TOO SMALL - %ld < %ld", (long)b->size(), + sp_debug_worker("CALL BLK TOO SMALL - %ld < %ld", (long)b->size(), (long)snip->jump_abs_size()); } // Well, let's try spring board next ... - sp_debug("FAILED RELOC BLK - try other worker"); + sp_debug_worker("FAILED RELOC BLK - try other worker"); return false; } @@ -125,23 +125,23 @@ namespace sp { SpBlock* b = pt->GetBlock(); assert(b); - sp_debug("BEFORE INSTALL (%lu bytes) for point %lx - {", + sp_debug_worker("BEFORE INSTALL (%lu bytes) for point %lx - {", b->size(), b->last()); - sp_debug("%s", g_parser->DumpInsns((void*)b->start(), + sp_debug_worker("%s", g_parser->DumpInsns((void*)b->start(), b->size()).c_str()); - sp_debug("}"); + sp_debug_worker("}"); SpSnippet::ptr snip = pt->snip(); assert(snip); // Build blob & change the permission of snippet size_t est_size = EstimateBlobSize(pt); - sp_debug("EST SIZE RELOC BLK - %ld / block size %ld", + sp_debug_worker("EST SIZE RELOC BLK - %ld / block size %ld", (long)est_size, b->size()); char* blob = snip->BuildBlob(est_size, /*reloc=*/true); if (!blob || (long)blob < getpagesize()) { - sp_debug("FAILED TO GENERATE BLOB"); + sp_debug_worker("FAILED TO GENERATE BLOB"); return false; } @@ -153,7 +153,7 @@ namespace sp { if (!g_as->SetMemoryPermission((dt::Address)blob, snip->GetBlobSize(), perm)) { - sp_debug("MPROTECT - Failed to change memory access permission" + sp_debug_worker("MPROTECT - Failed to change memory access permission" " for blob at %lx", (dt::Address)blob); // g_as->dump_mem_maps(); exit(0); @@ -162,7 +162,7 @@ namespace sp { char* addr = (char*)b->start(); assert(addr); if (!addr || (long)addr < getpagesize()) { - sp_debug("BLOCK ADDR LESS THAN PAGESIZE"); + sp_debug_worker("BLOCK ADDR LESS THAN PAGESIZE"); return false; } @@ -170,17 +170,17 @@ namespace sp { if (g_as->SetMemoryPermission((dt::Address)addr, insn_size, perm)) { g_as->write(obj, (dt::Address)addr, (dt::Address)jump_insn, insn_size); } else { - sp_debug("MPROTECT - Failed to change memory access permission"); + sp_debug_worker("MPROTECT - Failed to change memory access permission"); } - sp_debug("USE BLK-RELOC - piont %lx is instrumented using call" + sp_debug_worker("USE BLK-RELOC - piont %lx is instrumented using call" " block relocation", b->last()); - sp_debug("AFTER INSTALL (%lu bytes) for point %lx - {", + sp_debug_worker("AFTER INSTALL (%lu bytes) for point %lx - {", b->size(), b->last()); - sp_debug("%s", g_parser->DumpInsns((void*)b->start(), + sp_debug_worker("%s", g_parser->DumpInsns((void*)b->start(), insn_size).c_str()); - sp_debug("}"); + sp_debug_worker("}"); return true; } diff --git a/src/agent/inst_workers/callinsn_worker_impl.cc b/src/agent/inst_workers/callinsn_worker_impl.cc index 0236d079e..4bbb2b534 100644 --- a/src/agent/inst_workers/callinsn_worker_impl.cc +++ b/src/agent/inst_workers/callinsn_worker_impl.cc @@ -44,7 +44,7 @@ namespace sp { bool RelocCallInsnWorker::run(SpPoint* pt) { - sp_debug("RELOC CALLINSN WORKER - runs"); + sp_debug_worker("RELOC CALLINSN WORKER - runs"); assert(pt); SpBlock* b = pt->GetBlock(); @@ -61,23 +61,23 @@ namespace sp { // 1. is the instruction >= 5 bytes? if (call_insn_size < 5) { - sp_debug("SMALL CALL INSN - call insn is too small (< 5-byte)," + sp_debug_worker("SMALL CALL INSN - call insn is too small (< 5-byte)," " try other workers"); return false; } - sp_debug("%s", g_parser->DumpInsns((void*)b->start(), + sp_debug_worker("%s", g_parser->DumpInsns((void*)b->start(), b->size()).c_str()); // 2. is it a direct call instruction if (call_insn[0] != (char)0xe8) { // A direct call? - sp_debug("NOT NORMAL CALL"); + sp_debug_worker("NOT NORMAL CALL"); if (!pt->tailcall()) { // A jump for direct tail call? - sp_debug("NOT TAIL CALL - try other workers"); + sp_debug_worker("NOT TAIL CALL - try other workers"); return false; } else { - sp_debug("IS TAIL CALL, call insn size: %lu", call_insn_size); - sp_debug("Try other workers"); + sp_debug_worker("IS TAIL CALL, call insn size: %lu", call_insn_size); + sp_debug_worker("Try other workers"); return false; // assert(call_insn_size == 5 && // "LARGE INDIRECT TAIL CALL, UNSUPPORTED"); @@ -90,13 +90,13 @@ namespace sp { size_t est_size = EstimateBlobSize(pt); dt::Address blob = snip->GetBlob(est_size); if (!blob) { - sp_debug("NULL BLOB - get null blob at %lx", b->last()); + sp_debug_worker("NULL BLOB - get null blob at %lx", b->last()); return false; } long rel_addr = (long)blob - (long)call_insn_addr; if (!sp::IsDisp32(rel_addr)) { - sp_debug("NOT 4-byte DISP - blob=%lx, call_insn=%lx, delta=%ld," + sp_debug_worker("NOT 4-byte DISP - blob=%lx, call_insn=%lx, delta=%ld," " try other workers", (long)blob, (long)call_insn_addr, rel_addr); return false; @@ -133,7 +133,7 @@ namespace sp { assert(blob); size_t blob_size = snip->GetBlobSize(); if (!blob || (long)blob < getpagesize()) { - sp_debug("FAILED TO GENERATE BLOB"); + sp_debug_worker("FAILED TO GENERATE BLOB"); return false; } @@ -145,12 +145,12 @@ namespace sp { int* lp = (int*)p; assert(pt->callee()); - sp_debug("BEFORE INSTALL (%lu bytes) for point %lx for %s- {", + sp_debug_worker("BEFORE INSTALL (%lu bytes) for point %lx for %s- {", (unsigned long)b->size(), (unsigned long)call_addr, pt->callee()->name().c_str()); - sp_debug("%s", g_parser->DumpInsns((void*)b->start(), + sp_debug_worker("%s", g_parser->DumpInsns((void*)b->start(), b->size()).c_str()); - sp_debug("}"); + sp_debug_worker("}"); // Build the jump instruction SpObject* obj = pt->GetObject(); @@ -159,10 +159,10 @@ namespace sp { size_t insn_length = b->call_size(); *lp = (int)((long)blob - (long)call_addr - insn_length); - sp_debug("REL CAL - blob at %lx, last insn at %lx, insn length %lu", + sp_debug_worker("REL CAL - blob at %lx, last insn at %lx, insn length %lu", (unsigned long)blob, b->end(), (unsigned long)insn_length); - sp_debug("JUMP REL - jump to relative address %x", *lp); + sp_debug_worker("JUMP REL - jump to relative address %x", *lp); // Replace "call" with a "jump" instruction @@ -172,13 +172,13 @@ namespace sp { insn_length, perm)) { g_as->write(obj, (dt::Address)call_addr, (dt::Address)jump, 5); } else { - sp_debug("MPROTECT - Failed to change memory access permission"); + sp_debug_worker("MPROTECT - Failed to change memory access permission"); return false; } // Change the permission of snippet, so that it can be executed. if (!g_as->SetMemoryPermission((dt::Address)blob, blob_size, perm)) { - sp_debug("MPROTECT - Failed to change memory access permission" + sp_debug_worker("MPROTECT - Failed to change memory access permission" " for blob at %lx", (dt::Address)blob); g_as->free(obj, (dt::Address)blob); return false; @@ -186,12 +186,12 @@ namespace sp { assert(pt->callee()); - sp_debug("AFTER INSTALL (%lu bytes) for point %lx for %s- {", + sp_debug_worker("AFTER INSTALL (%lu bytes) for point %lx for %s- {", b->size(), b->last(), pt->callee()->name().c_str()); - sp_debug("%s", g_parser->DumpInsns((void*)b->start(), + sp_debug_worker("%s", g_parser->DumpInsns((void*)b->start(), b->size()).c_str()); - sp_debug("}"); + sp_debug_worker("}"); return true; } diff --git a/src/agent/inst_workers/inst_worker_delegate.h b/src/agent/inst_workers/inst_worker_delegate.h index 0823ea792..76e0be84d 100644 --- a/src/agent/inst_workers/inst_worker_delegate.h +++ b/src/agent/inst_workers/inst_worker_delegate.h @@ -90,11 +90,11 @@ namespace sp { i != insns.end(); i++) { in::Instruction insn = i->second; if (SpSnippet::UsePC(insn)) { - sp_debug("EST SIZE - USE PC"); + sp_debug_worker("EST SIZE - USE PC"); size += 20; // the worse case, we emulate pc insn } } - sp_debug("EST SIZE - %lu", (unsigned long)size); + sp_debug_worker("EST SIZE - %zu", size); return size; } }; diff --git a/src/agent/inst_workers/spring_worker_impl.cc b/src/agent/inst_workers/spring_worker_impl.cc index f078e7928..038c8eb53 100644 --- a/src/agent/inst_workers/spring_worker_impl.cc +++ b/src/agent/inst_workers/spring_worker_impl.cc @@ -44,7 +44,7 @@ namespace sp { bool SpringboardWorker::run(SpPoint* pt) { - sp_debug("SPRINGBOARD WORKER - runs"); + sp_debug_worker("SPRINGBOARD WORKER - runs"); return install(pt); } @@ -60,13 +60,13 @@ namespace sp { SpBlock* b = pt->GetBlock(); assert(b); - sp_debug("SPRING WORKER - saves"); + sp_debug_worker("SPRING WORKER - saves"); bool ret = false; assert(pt->snip()); ph::PatchBlock* springblk = pt->snip()->FindSpringboard(); if (!springblk) { - sp_debug("NO SPRING BOARD - cannot find suitable spring board"); + sp_debug_worker("NO SPRING BOARD - cannot find suitable spring board"); return false; } SpBlock* sblk = BLK_CAST(springblk); @@ -88,11 +88,11 @@ namespace sp { SpSnippet::ptr snip = pt->snip(); assert(snip); - sp_debug("BEFORE INSTALL (%lu bytes) for point %lx - {", + sp_debug_worker("BEFORE INSTALL (%lu bytes) for point %lx - {", callblk->size(), callblk->last()); - sp_debug("%s", g_parser->DumpInsns((void*)callblk->start(), + sp_debug_worker("%s", g_parser->DumpInsns((void*)callblk->start(), callblk->size()).c_str()); - sp_debug("}"); + sp_debug_worker("}"); // Find a spring block. A spring block should: // - big enough to hold two absolute jumps @@ -101,22 +101,22 @@ namespace sp { // ignore this call SpBlock* springblk = snip->FindSpringboard(); if (!springblk) { - sp_debug("FAILED TO GET A SPRINGBOARD BLOCK"); + sp_debug_worker("FAILED TO GET A SPRINGBOARD BLOCK"); return false; } - sp_debug("BEFORE INSTALL SPRING BLK (%lu bytes) for point %lx - {", + sp_debug_worker("BEFORE INSTALL SPRING BLK (%lu bytes) for point %lx - {", springblk->size(), callblk->last()); - sp_debug("%s", g_parser->DumpInsns((void*)springblk->start(), + sp_debug_worker("%s", g_parser->DumpInsns((void*)springblk->start(), springblk->size()).c_str()); - sp_debug("}"); + sp_debug_worker("}"); // Build blob & change the permission of snippet size_t est_size = EstimateBlobSize(pt); char* blob = snip->BuildBlob(est_size, /*reloc=*/true); if (!blob || (long)blob < getpagesize()) { - sp_debug("FAILED TO GENERATE BLOB"); + sp_debug_worker("FAILED TO GENERATE BLOB"); return false; } SpObject* obj = callblk->GetObject(); @@ -127,7 +127,7 @@ namespace sp { if (!g_as->SetMemoryPermission((dt::Address)blob, snip->GetBlobSize(), perm)) { - sp_debug("MPROTECT - Failed to change memory access permission" + sp_debug_worker("MPROTECT - Failed to change memory access permission" " for blob at %lx", (dt::Address)blob); // g_as->dump_mem_maps(); exit(0); @@ -138,14 +138,14 @@ namespace sp { // spring block char* spring = snip->RelocateSpring(springblk); if (!spring || (long)spring < getpagesize()) { - sp_debug("FAILED TO RELOCATE SPRINGBOARD BLOCK"); + sp_debug_worker("FAILED TO RELOCATE SPRINGBOARD BLOCK"); return false; } obj = springblk->GetObject(); if (!g_as->SetMemoryPermission((dt::Address)spring, snip->GetRelocSpringSize(), perm)) { - sp_debug("MPROTECT - Failed to change memory access permission" + sp_debug_worker("MPROTECT - Failed to change memory access permission" " for relocated spring blk at %lx", (dt::Address)spring); // g_as->dump_mem_maps(); exit(0); @@ -176,7 +176,7 @@ namespace sp { springblk->size(), perm)) { g_as->write(obj, (dt::Address)addr, (dt::Address)springblk_insn, off); } else { - sp_debug("MPROTECT - Failed to change memory access permission"); + sp_debug_worker("MPROTECT - Failed to change memory access permission"); } // Handle call block @@ -191,22 +191,22 @@ namespace sp { callblk->size(), perm)) { g_as->write(obj, (dt::Address)addr, (dt::Address)callblk_insn, 2); } else { - sp_debug("MPROTECT - Failed to change memory access permission"); + sp_debug_worker("MPROTECT - Failed to change memory access permission"); } - sp_debug("AFTER INSTALL CALL BLK (%lu bytes) for point %lx - {", + sp_debug_worker("AFTER INSTALL CALL BLK (%lu bytes) for point %lx - {", callblk->size(), callblk->last()); - sp_debug("%s", g_parser->DumpInsns((void*)callblk->start(), + sp_debug_worker("%s", g_parser->DumpInsns((void*)callblk->start(), callblk->size()).c_str()); - sp_debug("}"); + sp_debug_worker("}"); - sp_debug("AFTER INSTALL SPRING BLK (%lu bytes) for point %lx - {", + sp_debug_worker("AFTER INSTALL SPRING BLK (%lu bytes) for point %lx - {", springblk->size(), callblk->last()); - sp_debug("%s", g_parser->DumpInsns((void*)springblk->start(), + sp_debug_worker("%s", g_parser->DumpInsns((void*)springblk->start(), springblk->size()).c_str()); - sp_debug("}"); + sp_debug_worker("}"); - sp_debug("USE SPRING - piont %lx is instrumented using 1-hop spring", + sp_debug_worker("USE SPRING - piont %lx is instrumented using 1-hop spring", callblk->last()); return true; diff --git a/src/agent/inst_workers/trap_worker_impl.cc b/src/agent/inst_workers/trap_worker_impl.cc index f55cea686..fc891b17b 100644 --- a/src/agent/inst_workers/trap_worker_impl.cc +++ b/src/agent/inst_workers/trap_worker_impl.cc @@ -49,8 +49,12 @@ extern SpParser::ptr g_parser; // Used in trap handler, for mapping call instruction's address to snippet TrapWorker::InstMap TrapWorker::inst_map_; +bool sigill = getenv("SP_SIGILL"); +bool installed = false; + bool TrapWorker::run(SpPoint* pt) { - sp_debug("TRAP WORKER - runs"); + sp_debug_worker("TRAP WORKER - runs"); + sp_debug_worker("USE SIGILL - %d", sigill); assert(pt); // Install trap handler to the trap signal @@ -58,7 +62,13 @@ bool TrapWorker::run(SpPoint* pt) { act.sa_sigaction = TrapWorker::OnTrap; act.sa_flags = SA_SIGINFO; struct sigaction old_act; - sigaction(SIGTRAP, &act, &old_act); + if (!installed) + if (sigill) + sigaction(SIGILL, &act, &old_act); + else + sigaction(SIGTRAP, &act, &old_act); + + installed = true; // Call insn's addr assert(pt->GetBlock()); @@ -81,12 +91,12 @@ bool TrapWorker::install(SpPoint* pt) { SpBlock* b = pt->GetBlock(); assert(b); - sp_debug("TRAP WORKER - installs"); + sp_debug_worker("TRAP WORKER - installs"); - sp_debug("BEFORE INSTALL (%lu bytes) for point %lx - {", + sp_debug_worker("BEFORE INSTALL (%lu bytes) for point %lx - {", (unsigned long)b->size(), (unsigned long)b->last()); - sp_debug("%s", g_parser->DumpInsns((void*)b->start(), b->size()).c_str()); - sp_debug("}"); + sp_debug_worker("%s", g_parser->DumpInsns((void*)b->start(), b->size()).c_str()); + sp_debug_worker("}"); char* call_addr = (char*)b->last(); assert(call_addr); @@ -97,12 +107,20 @@ bool TrapWorker::install(SpPoint* pt) { size_t est_size = EstimateBlobSize(pt); char* blob = pt->snip()->BuildBlob(est_size); if (!blob) { - sp_debug("FAILED BLOB - failed to generate blob for call insn %lx", + sp_debug_worker("FAILED BLOB - failed to generate blob for call insn %lx", (unsigned long)call_addr); return false; } + + char ill_1, ill_2, int3; + + if (sigill) { + ill_1 = (char) 0x0F; + ill_2 = (char) 0x0B; + } + else + int3 = (char)0xcc; - char int3 = (char)0xcc; size_t call_size = b->call_size(); // Overwrite int3 to the call site @@ -112,20 +130,24 @@ bool TrapWorker::install(SpPoint* pt) { assert(g_as); if (!g_as->SetMemoryPermission((dt::Address)call_addr, call_size, perm)) { - sp_debug("FAILED PERM - failed to change memory permission"); + sp_debug_worker("FAILED PERM - failed to change memory permission"); return false; } else { - g_as->write(obj, (dt::Address)call_addr, (dt::Address)&int3, 1); + if (sigill) { + g_as->write(obj, (dt::Address)call_addr, (dt::Address)&ill_1, 1); + g_as->write(obj, (dt::Address)call_addr+1, (dt::Address)&ill_2, 1); + } else + g_as->write(obj, (dt::Address)call_addr, (dt::Address)&int3, 1); } - sp_debug("AFTER INSTALL (%lu bytes) for point %lx - {", + sp_debug_worker("AFTER INSTALL (%lu bytes) for point %lx - {", (unsigned long)b->size(), (unsigned long)b->last()); - sp_debug("%s", + sp_debug_worker("%s", g_parser->DumpInsns((void*)b->start(), b->last() - b->start() + 1) .c_str()); - sp_debug("}"); + sp_debug_worker("}"); - sp_debug("TRAP INSTALLED - successful for call insn %lx", (long)call_addr); + sp_debug_worker("TRAP INSTALLED - successful for call insn %lx", (long)call_addr); return true; } @@ -139,10 +161,10 @@ bool TrapWorker::ReplaceReturnWithTrap(SpPoint* pt) { sigaction(SIGTRAP, &act, &old_act); SpBlock* b = pt->GetBlock(); - sp_debug("BEFORE INSTALL (%lu bytes) for return point %lx - {", + sp_debug_worker("BEFORE INSTALL (%lu bytes) for return point %lx - {", (unsigned long)b->size(), (unsigned long)b->last()); - sp_debug("%s", g_parser->DumpInsns((void*)b->start(), b->size()).c_str()); - sp_debug("}"); + sp_debug_worker("%s", g_parser->DumpInsns((void*)b->start(), b->size()).c_str()); + sp_debug_worker("}"); char* ret_addr = (char*)b->last(); assert(ret_addr); @@ -159,20 +181,20 @@ bool TrapWorker::ReplaceReturnWithTrap(SpPoint* pt) { assert(g_as); if (!g_as->SetMemoryPermission((dt::Address)ret_addr, 1, perm)) { - sp_debug("FAILED PERM - failed to change memory permission"); + sp_debug_worker("FAILED PERM - failed to change memory permission"); return false; } else { g_as->write(obj, (dt::Address)ret_addr, (dt::Address)&int3, 1); } - sp_debug("AFTER INSTALL (%lu bytes) for point %lx - {", + sp_debug_worker("AFTER INSTALL (%lu bytes) for point %lx - {", (unsigned long)b->size(), (unsigned long)b->last()); - sp_debug("%s", + sp_debug_worker("%s", g_parser->DumpInsns((void*)b->start(), b->last() - b->start() + 1) .c_str()); - sp_debug("}"); + sp_debug_worker("}"); - sp_debug("TRAP INSTALLED - successful for return insn %lx", (long)ret_addr); + sp_debug_worker("TRAP INSTALLED - successful for return insn %lx", (long)ret_addr); return true; } @@ -186,7 +208,7 @@ void TrapWorker::OnTrap(int sig, siginfo_t* info, void* c) { dt::Address ret = g_context->GetReturnAddress(); if (ret != (dt::Address)0) { - sp_debug("TRAP HANDLER - for ret insn %lx", ret); + sp_debug_sigtrap("TRAP HANDLER - for ret insn %lx", ret); // Find the call site point corresponding to the return address SpPoint* call_site_point = g_context->FindCallSitePointFromRetAddr(ret); @@ -195,7 +217,7 @@ void TrapWorker::OnTrap(int sig, siginfo_t* info, void* c) { "A call site point has not been registered for the return address " "%lx", ret); - sp_debug("Got point %lx", (dt::Address)call_site_point); + sp_debug_sigtrap("Got point %lx", (dt::Address)call_site_point); // Find the exit instrumentation address correspoding to the call point char* exit_snip_addr = @@ -205,22 +227,22 @@ void TrapWorker::OnTrap(int sig, siginfo_t* info, void* c) { "Exit Instrumentation address cannot be found for the call site " "point %lx", (dt::Address)call_site_point); - sp_debug("Got exit instrumentation address %lx", + sp_debug_sigtrap("Got exit instrumentation address %lx", (dt::Address)exit_snip_addr); // The x86-64 needs its stack to be 16 byte aligned for accessing XMM // registers dt::Address esp = SpSnippet::align_stack(c); - sp_debug("Stack pointer aligned at %lx", esp); + sp_debug_sigtrap("Stack pointer aligned at %lx", esp); - // sp_debug("%s", g_parser->DumpInsns((void*)exit_snip_addr,150).c_str()); - sp_debug("Jump to exit point instrumentation at %lx ", + // sp_debug("sigtrap", "%s", g_parser->DumpInsns((void*)exit_snip_addr,150).c_str()); + sp_debug_sigtrap("Jump to exit point instrumentation at %lx ", (dt::Address)exit_snip_addr); // Set pc to jump to the exit point instrumentation SpSnippet::set_pc((dt::Address)exit_snip_addr, c); } else { - sp_debug("ret 0 inside trap handler"); + sp_debug_sigtrap("ret 0 inside trap handler"); } } else { // Get patch area's address @@ -228,13 +250,13 @@ void TrapWorker::OnTrap(int sig, siginfo_t* info, void* c) { assert(sp_snip); char* blob = (char*)sp_snip->GetBlob(); if (!blob || (long)blob < getpagesize()) { - sp_debug("TRAP invalid BLOB - at %lx, blob is %lx", pc, + sp_debug_sigtrap("TRAP invalid BLOB - at %lx, blob is %lx", pc, (dt::Address)blob); return; } int perm = PROT_READ | PROT_WRITE | PROT_EXEC; - sp_debug("TRAP HANDLER - for call insn %lx", pc); + sp_debug_sigtrap("TRAP HANDLER - for call insn %lx", pc); assert(g_as); // Change memory permission for the snippet @@ -244,7 +266,7 @@ void TrapWorker::OnTrap(int sig, siginfo_t* info, void* c) { sp_perror("FAILED PERM - failed to change memory permission for blob"); } - sp_debug("JUMP TO BLOB - at %s Address %lx", blob, (dt::Address)blob); + sp_debug_sigtrap("JUMP TO BLOB - at %s Address %lx", blob, (dt::Address)blob); // Set pc to jump to patch area SpSnippet::set_pc((dt::Address)blob, c); } diff --git a/src/agent/ipc/ipc_mgr.cc b/src/agent/ipc/ipc_mgr.cc index 61bd256cd..1d88bce2a 100644 --- a/src/agent/ipc/ipc_mgr.cc +++ b/src/agent/ipc/ipc_mgr.cc @@ -103,7 +103,7 @@ SpIpcMgr::GetWriteParam(SpPoint* pt, size_t* size = (size_t*)sp::PopArgument(pt, &h, sizeof(size_t)); if (size_out) *size_out = *size; - sp_debug("IPC GOT WRITE -- %s => fd = %d", f->name().c_str(), *fd_out); + sp_debug_ipc("IPC GOT WRITE -- %s => fd = %d", f->name().c_str(), *fd_out); } else if (f->name().compare("writev") == 0) { @@ -116,7 +116,7 @@ SpIpcMgr::GetWriteParam(SpPoint* pt, // int* iovcnt = (int*)sp::PopArgument(pt, &h, sizeof(int)); // fprintf(stderr, "iovcnt: %d\n", *iovcnt); - sp_debug("IPC GOT WRITE -- %s => fd = %d", f->name().c_str(), *fd_out); + sp_debug_ipc("IPC GOT WRITE -- %s => fd = %d", f->name().c_str(), *fd_out); } else if (f->name().compare("connect") == 0) { @@ -125,7 +125,7 @@ SpIpcMgr::GetWriteParam(SpPoint* pt, sockaddr** sa = (sockaddr**)sp::PopArgument(pt, &h, sizeof(sockaddr*)); if (sa_out) *sa_out = *sa; - sp_debug("IPC GOT CONNECT -- %s => fd = %d", f->name().c_str(), *fd_out); + sp_debug_ipc("IPC GOT CONNECT -- %s => fd = %d", f->name().c_str(), *fd_out); } else if (f->name().compare("fputs") == 0) { @@ -162,7 +162,7 @@ SpIpcMgr::GetWriteParam(SpPoint* pt, int* fd = (int*)sp::PopArgument(pt, &h, sizeof(int)); if (fd_out) *fd_out = *fd; - sp_debug("IPC GOT sendfile -- %s => fd = %d", f->name().c_str(), *fd_out); + sp_debug_ipc("IPC GOT sendfile -- %s => fd = %d", f->name().c_str(), *fd_out); } /* if((*fd_out)!=-1) { fcntl((*fd_out), F_SETOWN,getpid() ==-1); @@ -194,7 +194,7 @@ SpIpcMgr::GetReadParam(SpPoint* pt, size_t* size = (size_t*)sp::PopArgument(pt, &h, sizeof(size_t)); if (size_out) *size_out = *size; - sp_debug("IPC GOT READ -- %s => fd = %d", f->name().c_str(), *fd_out); + sp_debug_ipc("IPC GOT READ -- %s => fd = %d", f->name().c_str(), *fd_out); } else if (f->name().compare("readv") == 0) { @@ -207,7 +207,7 @@ SpIpcMgr::GetReadParam(SpPoint* pt, // int* iovcnt = (int*)sp::PopArgument(pt, &h, sizeof(int)); // fprintf(stderr, "iovcnt: %d\n", *iovcnt); - sp_debug("IPC GOT READ -- %s => fd = %d", f->name().c_str(), *fd_out); + sp_debug_ipc("IPC GOT READ -- %s => fd = %d", f->name().c_str(), *fd_out); } else if (f->name().compare("fgets") == 0) { @@ -239,7 +239,7 @@ SpIpcMgr::GetReadParam(SpPoint* pt, int* fd = (int*)sp::PopArgument(pt, &h, sizeof(int)); if (fd_out) *fd_out = *fd; - sp_debug("IPC GOT ACCEPT -- %s => fd = %d", f->name().c_str(), *fd_out); + sp_debug_ipc("IPC GOT ACCEPT -- %s => fd = %d", f->name().c_str(), *fd_out); } /* if((*fd_out)!=-1) { fcntl((*fd_out), F_SETOWN,getpid() ==-1); @@ -263,7 +263,7 @@ SpIpcMgr::GetCloseParam(SpPoint* pt, if (f->name().compare("close") == 0) { int* fd = (int*)sp::PopArgument(pt, &h, sizeof(int)); if (fd_out) *fd_out = *fd; - sp_debug("CLOSE -- %s fd = %d", f->name().c_str(), *fd_out); + sp_debug_ipc("CLOSE -- %s fd = %d", f->name().c_str(), *fd_out); } /* if((*fd_out)!=-1) { fcntl((*fd_out), F_SETOWN,getpid() ==-1); @@ -283,11 +283,11 @@ SpIpcMgr::fcntlReturnParam(SpPoint* pt) { ArgumentHandle h; if (f->name().compare("socket") == 0) { fd = sp::ReturnValue(pt); - sp_debug("SOCKET -- %s fd = %d", f->name().c_str(), fd); + sp_debug_ipc("SOCKET -- %s fd = %d", f->name().c_str(), fd); } if (f->name().compare("accept") == 0) { int fd = sp::ReturnValue(pt); - sp_debug("SOCKET -- %s fd = %d", f->name().c_str(), fd); + sp_debug_ipc("SOCKET -- %s fd = %d", f->name().c_str(), fd); } /* if(fd!=-1) { fcntl(fd, F_SETOWN,getpid() ==-1); @@ -328,12 +328,12 @@ char SpIpcMgr::CanStartTracing(int fd) { SpIpcWorkerDelegate* SpIpcMgr::GetWorker(int fd) { // PIPE if (IsPipe(fd)) { - sp_debug("PIPE FD - fd = %d", fd); + sp_debug_ipc("PIPE FD - fd = %d", fd); return pipe_worker(); } // TCP else if (IsTcp(fd)) { - sp_debug("TCP FD - fd = %d", fd); + sp_debug_ipc("TCP FD - fd = %d", fd); return tcp_worker(); } // UDP @@ -353,7 +353,7 @@ SpIpcMgr::BeforeEntry(SpPoint* pt) { ph::PatchFunction* f = sp::Callee(pt); if (!f) { - sp_debug("CALLEE NOT FOUND - in BeforeEntry for call insn %lx", + sp_debug_ipc("CALLEE NOT FOUND - in BeforeEntry for call insn %lx", pt->block()->last()); return false; } @@ -390,10 +390,10 @@ SpIpcMgr::BeforeEntry(SpPoint* pt) { } else { - sp_debug("Not injected in ipc_mgr"); + sp_debug_ipc("Not injected in ipc_mgr"); } } else { - sp_debug("FAILED TO CREATE CHANNEL - for write"); + sp_debug_ipc("FAILED TO CREATE CHANNEL - for write"); } return true; @@ -410,7 +410,7 @@ SpIpcMgr::BeforeEntry(SpPoint* pt) { if (c) { pt->SetChannel(c); } else { - sp_debug("FAILED TO CREATE CHANNEL - for read"); + sp_debug_ipc("FAILED TO CREATE CHANNEL - for read"); } } @@ -432,7 +432,7 @@ SpIpcMgr::BeforeExit(PointCallHandle* handle) { //Detect fork for pipe if (ipc_mgr->IsFork(f->name().c_str())) { long pid = handle->GetReturnValue(); - sp_debug("fork: pid[%ld]", pid); + sp_debug_ipc("fork: pid[%ld]", pid); // Receiver if (pid == 0) { ipc_mgr->pipe_worker()->SetLocalStartTracing(0); @@ -492,6 +492,7 @@ SpIpcMgr::BeforeExit(PointCallHandle* handle) { void SpIpcMgr::HandleExec(SpPoint* pt) { SpFunction* callee = sp::Callee(pt); if (callee->name().compare("execve") == 0) { + sp_debug_ipc("EXEC"); sp::ArgumentHandle h; char** path = (char**)PopArgument(pt, &h, sizeof(char*)); char*** argvs = (char***)PopArgument(pt, &h, sizeof(char**)); @@ -586,6 +587,7 @@ void SpIpcMgr::HandleExec(SpPoint* pt) { callee->name().compare("execle") == 0 || callee->name().compare("execv") == 0 || callee->name().compare("execvp") == 0) { + sp_debug_ipc("EXEC_OTHER"); std::string agent_name = g_parser->agent_name(); if (char* ld_preload_str = getenv("LD_PRELOAD")) { std::string libs{ld_preload_str}; diff --git a/src/agent/ipc/ipc_workers/ipc_worker_delegate.cc b/src/agent/ipc/ipc_workers/ipc_worker_delegate.cc index ab6e311f8..c0ff196d9 100644 --- a/src/agent/ipc/ipc_workers/ipc_worker_delegate.cc +++ b/src/agent/ipc/ipc_workers/ipc_worker_delegate.cc @@ -79,12 +79,12 @@ SpIpcWorkerDelegate::GetChannel(int fd, if (rw == SP_WRITE) { c->rw = SP_WRITE; channel_map_write_[fd] = c; - sp_debug("WRITE CHANNEL @ pid = %d - get a WRITE channel with" + sp_debug_ipc("WRITE CHANNEL @ pid = %d - get a WRITE channel with" " inode %ld for fd %d with remote pid %d", getpid(), GetInodeFromFileDesc(fd), fd, c->remote_pid); } else { c->rw = SP_READ; channel_map_read_[fd] = c; - sp_debug("READ CHANNEL @ pid = %d - get a READ channel with" + sp_debug_ipc("READ CHANNEL @ pid = %d - get a READ channel with" " inode %ld for fd %d with remote pid %d", getpid(), GetInodeFromFileDesc(fd), fd, c->remote_pid); } c->fd = fd; diff --git a/src/agent/ipc/ipc_workers/pipe_worker_impl.cc b/src/agent/ipc/ipc_workers/pipe_worker_impl.cc index 7b79cc190..0f37aaf45 100644 --- a/src/agent/ipc/ipc_workers/pipe_worker_impl.cc +++ b/src/agent/ipc/ipc_workers/pipe_worker_impl.cc @@ -49,7 +49,7 @@ extern SpParser::ptr g_parser; ////////////////////////////////////////////////////////////////////// SpPipeWorker::SpPipeWorker() { - // sp_debug("PIPE WORKER - created for pid=%d", getpid()); + // sp_debug_ipc("PIPE WORKER - created for pid=%d", getpid()); TracingInternal(&start_tracing_); start_tracing_[getpid()] = 0; } @@ -119,20 +119,20 @@ SpPipeWorker::Inject(SpChannel* c, // do bookkeeping correctly. if (c->injected) return true; - sp_debug("NO INJECTED(pipe) -- start injection"); + sp_debug_ipc("NO INJECTED(pipe) -- start injection"); if (c->remote_pid > 0) { - sp_debug("Remote pid is %d",c->remote_pid); + sp_debug_ipc("Remote pid is %d",c->remote_pid); if(ProcessHasLibrary(c->remote_pid, "libagent")){ - sp_debug("Process %d already has agent shared library", c->remote_pid); + sp_debug_ipc("Process %d already has agent shared library", c->remote_pid); return true; } SpInjector::ptr injector = SpInjector::Create(c->remote_pid); if(!injector) - sp_debug("Injector not created"); + sp_debug_ipc("Injector not created"); else - sp_debug("Injector created for process id %d",c->remote_pid); + sp_debug_ipc("Injector created for process id %d",c->remote_pid); string agent_name = ""; if (getenv("SP_AGENT_DIR")) { agent_name = getenv("SP_AGENT_DIR"); @@ -142,14 +142,14 @@ SpPipeWorker::Inject(SpChannel* c, } agent_name += g_parser->agent_name(); sp_print("%s", agent_name.c_str()); - sp_debug("agent shared library which is going to be injected is %s",agent_name.c_str()); + sp_debug_ipc("agent shared library which is going to be injected is %s",agent_name.c_str()); c->injected = injector->Inject(agent_name.c_str()); - sp_debug("Returned back"); + sp_debug_ipc("Returned back"); } if(c->injected) - sp_debug("Injected into the pipe"); + sp_debug_ipc("Injected into the pipe"); else - sp_debug("Not injected into the pipe"); + sp_debug_ipc("Not injected into the pipe"); return c->injected; // return 0; } @@ -164,17 +164,17 @@ SpPipeWorker::CreateChannel(int fd, c->local_pid = getpid(); PidSet pid_set; GetPidsFromFileDesc(fd, pid_set); - sp_debug("FD TO PID - get a %lu pids from fd %d", + sp_debug_ipc("FD TO PID - get a %lu pids from fd %d", (unsigned long)pid_set.size(), fd); if (pid_set.size() == 0) { - sp_debug("FAILED TO GET PID - from fd = %d", fd); + sp_debug_ipc("FAILED TO GET PID - from fd = %d", fd); // return NULL; } for (PidSet::iterator i = pid_set.begin(); i != pid_set.end(); i++) { if (*i != c->local_pid) { c->remote_pid = *i; - sp_debug("Local pid =%d Remote pid = %d",c->local_pid,c->remote_pid); + sp_debug_ipc("Local pid =%d Remote pid = %d",c->local_pid,c->remote_pid); break; } } diff --git a/src/agent/ipc/ipc_workers/tcp_worker_impl.cc b/src/agent/ipc/ipc_workers/tcp_worker_impl.cc index b49e45ecd..e2458dc2f 100644 --- a/src/agent/ipc/ipc_workers/tcp_worker_impl.cc +++ b/src/agent/ipc/ipc_workers/tcp_worker_impl.cc @@ -46,7 +46,7 @@ extern SpParser::ptr g_parser; ////////////////////////////////////////////////////////////////////// SpTcpWorker::SpTcpWorker() : start_tracing_(0) { - // sp_debug("TCP WORKER - created for pid=%d", getpid()); + // sp_debug_ipc("TCP WORKER - created for pid=%d", getpid()); } ////////////////////////////////////////////////////////////////////// @@ -58,12 +58,12 @@ SpTcpWorker::SetRemoteStartTracing(char yes_or_no, /*if(c->send_oob) return; c->send_oob=true; - sp_debug("SET TRACING - yes_or_no (%d), fd (%d)", yes_or_no, c->fd); + sp_debug_ipc("SET TRACING - yes_or_no (%d), fd (%d)", yes_or_no, c->fd); assert(c); // Sanity check if (c && IsTcp(c->fd)) { //int mark_byte = (getpid() & 0xFF) | 1; - sp_debug("OOB MARK \"S\" - sending via fd=%d", c->fd); + sp_debug_ipc("OOB MARK \"S\" - sending via fd=%d", c->fd); if (send(c->fd, "S", 1, MSG_OOB) < 0) { perror("send"); sp_perror("OUT-OF-BAND - failed to send oob byte"); @@ -91,16 +91,16 @@ SpTcpWorker::CanStartTracing(int fd) { int at_mark = 0; if (ioctl(fd, SIOCATMARK, &at_mark) < 0) { - sp_debug("ioctl(SIOCATMARK) error"); + sp_debug_ipc("ioctl(SIOCATMARK) error"); return 0; } if (at_mark) { uint8_t mark = 0; if (recv(fd, &mark, sizeof(mark), MSG_OOB) < 0) { - sp_debug("Recv OOB error"); + sp_debug_ipc("Recv OOB error"); return 0; } - sp_debug("GOT mark at_mark=%d, mark=%d", at_mark, mark); + sp_debug_ipc("GOT mark at_mark=%d, mark=%d", at_mark, mark); // fprintf(stderr, "GOT mark at_mark=%d, mark=%d\n", at_mark, mark); start_tracing_ = 1; return 1; @@ -117,7 +117,7 @@ SpTcpWorker::Inject(SpChannel* c, char* agent_path) { if (c->injected) return true; - sp_debug("NO INJECTED(tcp) -- start injection"); + sp_debug_ipc("NO INJECTED(tcp) -- start injection"); TcpChannel *tcp_channel = static_cast(c); assert(tcp_channel); @@ -128,14 +128,14 @@ SpTcpWorker::Inject(SpChannel* c, if (!GetAddress(&tcp_channel->remote, remote_ip, 256, remote_port, 64)) { sp_perror("failed to get remote address in tcp_worker::inject()"); } - sp_debug("REMOTE IP: %s, REMOTE PORT: %s", remote_ip, remote_port); + sp_debug_ipc("REMOTE IP: %s, REMOTE PORT: %s", remote_ip, remote_port); char cmd[1024]; string cmd_exe; if (strstr(remote_ip, "127.0.0.1")) { // For local machine, invoke injector directly - sp_debug("LOCAL MACHINE TCP"); + sp_debug_ipc("LOCAL MACHINE TCP"); // Injector path if (getenv("SP_DIR") && getenv("PLATFORM")) { @@ -186,7 +186,7 @@ SpTcpWorker::Inject(SpChannel* c, cmd_exe += "\"\' 2>&1 | tee -a ./tmp/injector_log"; } - sp_debug("INJECT CMD -- %s", cmd_exe.c_str()); + sp_debug_ipc("INJECT CMD -- %s", cmd_exe.c_str()); // unset LD_PRELOAD before popen injector // then set LD_PRELOAD back after popen is finished @@ -201,19 +201,19 @@ SpTcpWorker::Inject(SpChannel* c, // Execute the command FILE* fp = popen(cmd_exe.c_str(), "r"); if (fp == NULL) { - sp_debug("Popen error"); + sp_debug_ipc("Popen error"); return false; } char line[1024]; while (fgets(line,sizeof(line),fp)) { if (strstr(line, "SUCCESS") != NULL) { - sp_debug("Injected"); + sp_debug_ipc("Injected"); c->injected = true; break; } } pclose(fp); - sp_debug("Popen finished Returning %d",c->injected?1 :0); + sp_debug_ipc("Popen finished Returning %d",c->injected?1 :0); if (setenv("LD_PRELOAD", libs.c_str(), true) < 0) { sp_perror("setenv for LD_PRELOAD failed"); @@ -232,16 +232,16 @@ SpTcpWorker::CreateChannel(int fd, c->type = SP_TCP; c->inode = GetInodeFromFileDesc(fd); fcntl(fd, F_SETOWN, getpid()); - sp_debug("CREATE CHANNEL -- for fd=%d", fd); + sp_debug_ipc("CREATE CHANNEL -- for fd=%d", fd); // connect, we can get remote ip/port from arg if (arg != NULL) { - sp_debug("GET ADDR from sockaddr_storage"); + sp_debug_ipc("GET ADDR from sockaddr_storage"); // Get local ip / port char host[256]; char service[64]; c->remote = *((sockaddr_storage*)arg); if (GetAddress(&c->remote, host, 256, service, 64)) { - sp_debug("connect remote host: %s, service: %s\n", host, service); + sp_debug_ipc("connect remote host: %s, service: %s\n", host, service); } else { sp_perror("failed to get connect remote address"); } @@ -249,7 +249,7 @@ SpTcpWorker::CreateChannel(int fd, // Get local ip / port (skip it for now) if (GetLocalAddress(fd, &c->local)) { if (GetAddress(&c->local, host, 256, service, 64)) { - sp_debug("connect local host: %s, service: %s\n", host, service); + sp_debug_ipc("connect local host: %s, service: %s\n", host, service); } else { sp_perror("failed to get local address for write/send"); } @@ -259,14 +259,14 @@ SpTcpWorker::CreateChannel(int fd, // send/write else if (rw == SP_WRITE || rw == SP_READ) { - sp_debug("GET ADDR from getpeername"); + sp_debug_ipc("GET ADDR from getpeername"); // Get remote ip / port if (GetRemoteAddress(fd, &c->remote)) { char host[256]; char service[64]; if (GetAddress(&c->remote, host, 256, service, 64)) { - sp_debug("write/send remote host: %s, service: %s\n", host, service); + sp_debug_ipc("write/send remote host: %s, service: %s\n", host, service); } else { sp_perror("failed to get remote address for write/send"); } @@ -277,7 +277,7 @@ SpTcpWorker::CreateChannel(int fd, char host[256]; char service[64]; if (GetAddress(&c->local, host, 256, service, 64)) { - sp_debug("write/send local host: %s, service: %s\n", host, service); + sp_debug_ipc("write/send local host: %s, service: %s\n", host, service); } else { sp_perror("failed to get local address for write/send"); } diff --git a/src/agent/ipc/ipc_workers/udp_worker_impl.cc b/src/agent/ipc/ipc_workers/udp_worker_impl.cc index a0ac88a0a..9c1c20d95 100644 --- a/src/agent/ipc/ipc_workers/udp_worker_impl.cc +++ b/src/agent/ipc/ipc_workers/udp_worker_impl.cc @@ -59,7 +59,7 @@ SpUdpWorker::CanStartTracing(int fd) { bool SpUdpWorker::Inject(SpChannel* c, char* agent_path) { - sp_debug("UDP connection-Not injected: TODO"); + sp_debug_ipc("UDP connection-Not injected: TODO"); return 0; } diff --git a/src/agent/parser.cc b/src/agent/parser.cc index 19d69242f..86bf5f4a6 100644 --- a/src/agent/parser.cc +++ b/src/agent/parser.cc @@ -107,17 +107,17 @@ SpParser::GetRuntimeSymtabs(sp::SymtabSet& symtabs) { sb::AddressLookup* al = sb::AddressLookup::createAddressLookup(getpid()); if (!al) { - sp_debug("FAILED TO CREATE AddressLookup"); + sp_debug_agent("FAILED TO CREATE AddressLookup"); return NULL; } al->refresh(); std::vector tabs; al->getAllSymtabs(tabs); if (tabs.size() == 0) { - sp_debug("FOUND NO SYMTABS"); + sp_debug_agent("FOUND NO SYMTABS"); return NULL; } - sp_debug("SYMTABS - %ld symtabs found", (long)tabs.size()); + sp_debug_agent("SYMTABS - %ld symtabs found", (long)tabs.size()); for (std::vector::iterator i = tabs.begin(); i != tabs.end(); i++) { @@ -131,7 +131,7 @@ SpParser::GetRuntimeSymtabs(sp::SymtabSet& symtabs) { Symbols syms; if (sym->findSymbol(syms, magic_var) && syms.size() > 0) { agent_name_ = sym->name(); - sp_debug("AGENT NAME - %s", agent_name_.c_str()); + sp_debug_agent("AGENT NAME - %s", agent_name_.c_str()); } // Deduplicate symtabs @@ -166,23 +166,23 @@ SpParser::CreatePatchobjs(sp::SymtabSet& unique_tabs, if (!CanInstrumentLib(libname_no_path) && libname_no_path.find("libc.so") == string::npos && libname_no_path.find("ld-linux-x86-64.so") == string::npos) { - sp_debug("SKIPED - skip parsing %s", + sp_debug_agent("SKIPED - skip parsing %s", sp_filename(sym->name().c_str())); continue; } SpObject* patch_obj = CreateObject(sym, load_addr); if (!patch_obj) { - sp_debug("FAILED TO CREATE PATCH OBJECT"); + sp_debug_agent("FAILED TO CREATE PATCH OBJECT"); continue; } patch_objs.push_back(patch_obj); - sp_debug("PARSED - parsed %s", sp_filename(sym->name().c_str())); + sp_debug_agent("PARSED - parsed %s", sp_filename(sym->name().c_str())); if (sym->isExec()) { exe_obj_ = patch_obj; - sp_debug("EXE - %s is an executable", + sp_debug_agent("EXE - %s is an executable", sp_filename(sym->name().c_str())); } } // End of symtab iteration @@ -196,7 +196,7 @@ SpParser::GetExeFromProcfs(sp::PatchObjects& patch_objs) { std::string exeName = sp::GetExeName(); for (PatchObjects::iterator oi = patch_objs.begin(); oi != patch_objs.end(); oi++) { - sp_debug("Trying next patch obj"); + sp_debug_agent("Trying next patch obj"); SpObject* obj = OBJ_CAST(*oi); assert(obj); @@ -205,16 +205,16 @@ SpParser::GetExeFromProcfs(sp::PatchObjects& patch_objs) { std::string objName = obj->name(); char* s1 = sp_filename(exeName.c_str()); char* s2 = sp_filename(objName.c_str()); - sp_debug("exec name[%s] obj name[%s]", sp::GetExeName().c_str(), obj->name().c_str()); + sp_debug_agent("exec name[%s] obj name[%s]", sp::GetExeName().c_str(), obj->name().c_str()); if (strcmp(s1, s2) == 0) { - sp_debug("GOT EXE - %s is an executable shared library", s2); + sp_debug_agent("GOT EXE - %s is an executable shared library", s2); return obj; } // strcmp else { - sp_debug("PARSE EXE - s1=%s, s2 =%s", s1, s2); + sp_debug_agent("PARSE EXE - s1=%s, s2 =%s", s1, s2); } } // for each obj - sp_debug("failed to find exe from procfs"); + sp_debug_agent("failed to find exe from procfs"); return NULL; } @@ -264,10 +264,10 @@ SpParser::CreateObject(sb::Symtab* sym, if (dir) { dirent* entry = readdir(dir); while (entry) { - sp_debug("Parsed library: %s is %s?", entry->d_name, + sp_debug_agent("Parsed library: %s is %s?", entry->d_name, no_path_name); if (strcmp(no_path_name, entry->d_name) == 0) { - sp_debug("GOT Parsed LIB: %s", entry->d_name); + sp_debug_agent("GOT Parsed LIB: %s", entry->d_name); parse_from_file = true; break; } @@ -275,15 +275,15 @@ SpParser::CreateObject(sb::Symtab* sym, } closedir(dir); } else { - sp_debug("FAILED TO ITERATE DIR %s", getenv("SP_PARSE_DIR")); + sp_debug_agent("FAILED TO ITERATE DIR %s", getenv("SP_PARSE_DIR")); } } if (parse_from_file) { - sp_debug("PARSE FROM FILE - for %s", sym->name().c_str()); + sp_debug_agent("PARSE FROM FILE - for %s", sym->name().c_str()); obj = CreateObjectFromFile(sym, load_addr); } else { - sp_debug("PARSE FROM RUNTIME - for %s", sym->name().c_str()); + sp_debug_agent("PARSE FROM RUNTIME - for %s", sym->name().c_str()); obj = CreateObjectFromRuntime(sym, load_addr); } return obj; @@ -294,7 +294,7 @@ SpParser::CreateObjectFromRuntime(sb::Symtab* sym, dt::Address load_addr) { // Parse binary objects using ParseAPI::CodeObject::parse(). - sp_debug("Start create obj from runtime symtab name: %s", sym->name().c_str()); + sp_debug_agent("Start create obj from runtime symtab name: %s", sym->name().c_str()); pe::SymtabCodeSource* scs = new pe::SymtabCodeSource(sym); code_srcs_.push_back(scs); pe::CodeObject* co = new pe::CodeObject(scs); @@ -315,7 +315,7 @@ SpParser::CreateObjectFromRuntime(sb::Symtab* sym, // dt::Address real_load_addr = // load_addr ? load_addr : scs->loadAddress(); dt::Address real_load_addr=load_addr; - sp_debug("Symbol %s: load_addr: %lx, scs->loadAddress: %lx", sym->name().c_str(),load_addr, + sp_debug_agent("Symbol %s: load_addr: %lx, scs->loadAddress: %lx", sym->name().c_str(),load_addr, scs->loadAddress()); SpObject* obj = new sp::SpObject(co, load_addr, @@ -363,7 +363,7 @@ SpParser::Parse() { if (!CreatePatchobjs(unique_tabs, al, patch_objs)) { sp_perror("FAILED TO CREATE PATCHOBJS"); } - sp_debug("Created patchapi objs"); + sp_debug_agent("Created patchapi objs"); // Step 3: In the case of executable shared library, we cannot get // exe_obj_ via symtabAPI, so we resort to /proc @@ -426,12 +426,12 @@ class SpVisitor : public in::Visitor { } else { // Non-pc case, x86-32 always goes this way dt::Address rval = pt_->snip()->GetSavedReg(r->getID()); - // sp_debug("GOT NON-PC REG - %s = %lx", + // sp_debug_agent("GOT NON-PC REG - %s = %lx", // r->getID().name().c_str(), rval); call_addr_ = rval; } - // sp_debug("SP_VISITOR - reg value %lx", call_addr_); + // sp_debug_agent("SP_VISITOR - reg value %lx", call_addr_); stack_.push(call_addr_); } virtual void visit(in::BinaryFunction* b) { @@ -442,10 +442,10 @@ class SpVisitor : public in::Visitor { if (b->isAdd()) { call_addr_ = i1 + i2; - // sp_debug("SP_VISITOR - %lx + %lx = %lx", i1, i2, call_addr_); + // sp_debug_agent("SP_VISITOR - %lx + %lx = %lx", i1, i2, call_addr_); } else if (b->isMultiply()) { call_addr_ = i1 * i2; - // sp_debug("SP_VISITOR - %lx * %lx = %lx", i1, i2, call_addr_); + // sp_debug_agent("SP_VISITOR - %lx * %lx = %lx", i1, i2, call_addr_); } else { assert(0); } @@ -473,16 +473,16 @@ class SpVisitor : public in::Visitor { } } - // sp_debug("SP_VISITOR - imm %lx ", call_addr_); + // sp_debug_agent("SP_VISITOR - imm %lx ", call_addr_); stack_.push(call_addr_); } virtual void visit(in::Dereference* d) { dt::Address* addr = (dt::Address*)(stack_.top() + seg_val_); stack_.pop(); - // sp_debug("SP_VISITOR - dereferencing %lx => ? ", + // sp_debug_agent("SP_VISITOR - dereferencing %lx => ? ", // (dt::Address)addr); call_addr_ = *addr; - // sp_debug("SP_VISITOR - dereference %lx => %lx ", + // sp_debug_agent("SP_VISITOR - dereference %lx => %lx ", // (dt::Address)addr, call_addr_); stack_.push(call_addr_); } @@ -518,7 +518,7 @@ SpParser::callee(SpPoint* pt, // if (tmp_f && tmp_f != f) { // f = tmp_f; // } - sp_debug("got callee, found function %lx", (long unsigned int) f); + sp_debug_agent("got callee, found function %lx", (long unsigned int) f); SpFunction* sfunc = f; assert(sfunc); @@ -536,7 +536,7 @@ SpParser::callee(SpPoint* pt, if (addr_callee_not_found_.find(b->last()) != addr_callee_not_found_.end()) { - sp_debug("NOT FOUND - proved not found for %lx", b->last()); + sp_debug_agent("NOT FOUND - proved not found for %lx", b->last()); return NULL; } @@ -638,13 +638,13 @@ SpParser::GetFuncAddrFromName(string name) { FuncSet found_funcs; // We expect users to provide pretty name if (!FindFunction(name, &found_funcs) || found_funcs.size() == 0) { - sp_debug("GET FUNC ADDR FROM NAME - failed for %s", name.c_str()); + sp_debug_agent("GET FUNC ADDR FROM NAME - failed for %s", name.c_str()); return 0; } // To simplify things, We don't want the payload function to be overloaded if (found_funcs.size() > 1) { - sp_debug("GET FUNC ADDR FROM NAME - failed for %s, overloaded func", + sp_debug_agent("GET FUNC ADDR FROM NAME - failed for %s, overloaded func", name.c_str()); return 0; } @@ -656,7 +656,7 @@ SpParser::GetFuncAddrFromName(string name) { SpFunction* SpParser::FindFunction(dt::Address addr) { - sp_debug("FIND FUNC BY ADDR - for call insn %lx", addr); + sp_debug_agent("FIND FUNC BY ADDR - for call insn %lx", addr); if (addr == 0) { return NULL; @@ -664,14 +664,14 @@ SpParser::FindFunction(dt::Address addr) { // A quick return, if this function is in the cache if (addr_func_map_.find(addr) != addr_func_map_.end()) { - sp_debug("GOT FROM CACHE - %s", + sp_debug_agent("GOT FROM CACHE - %s", addr_func_map_[addr]->name().c_str()); return addr_func_map_[addr]; } // A quick return, if this function is proved to be not found if (addr_func_not_found_.find(addr) != addr_func_not_found_.end()) { - sp_debug("NOT FOUND - call at %lx is proved to be not found", addr); + sp_debug_agent("NOT FOUND - call at %lx is proved to be not found", addr); return NULL; } @@ -681,14 +681,14 @@ SpParser::FindFunction(dt::Address addr) { SpObject* obj = OBJ_CAST(ci->second); if (!CanInstrumentLib(obj->name().c_str())) { - sp_debug("SKIPED - skip finding function at %s", + sp_debug_agent("SKIPED - skip finding function at %s", sp_filename(obj->name().c_str())); continue; } // Get the function offset relative to the object dt::Address offset = addr - obj->codeBase(); - sp_debug("code base %lx for %s", obj->codeBase(), obj->name().c_str()); + sp_debug_agent("code base %lx for %s", obj->codeBase(), obj->name().c_str()); pe::CodeObject* co = obj->co(); pe::CodeSource* cs = co->cs(); @@ -698,13 +698,13 @@ SpParser::FindFunction(dt::Address addr) { int cnt = cs->findRegions(offset, match); if(cnt != 1) { - sp_debug("%ld Regions found", cnt); + sp_debug_agent("%ld Regions found", cnt); continue; } else if(cnt == 1) { co->findBlocks(*match.begin(), offset, blocks); - sp_debug("%ld blocks found", (long)blocks.size()); + sp_debug_agent("%ld blocks found", (long)blocks.size()); if (blocks.size() == 1) { std::vector funcs; (*blocks.begin())->getFuncs(funcs); @@ -718,7 +718,7 @@ SpParser::FindFunction(dt::Address addr) { return NULL; } } - sp_debug("Function not found"); + sp_debug_agent("Function not found"); addr_func_not_found_.insert(addr); return NULL; } @@ -728,7 +728,7 @@ SpParser::FindFunction(dt::Address addr) { bool SpParser::FindFunction(string name, FuncSet* found_funcs) { - sp_debug("LOOKING FOR FUNC BY PRETTY NAME - looking for %s", name.c_str()); + sp_debug_agent("LOOKING FOR FUNC BY PRETTY NAME - looking for %s", name.c_str()); if (name.length() == 0) { return false; @@ -736,7 +736,7 @@ SpParser::FindFunction(string name, // A quick return, if this function is in the cache if (demangled_func_map_.find(name) != demangled_func_map_.end()) { - sp_debug("GOT FROM CACHE - %s", name.c_str()); + sp_debug_agent("GOT FROM CACHE - %s", name.c_str()); std::copy(demangled_func_map_[name].begin(), demangled_func_map_[name].end(), @@ -747,7 +747,7 @@ SpParser::FindFunction(string name, // A quick return, if this function is proved to be not found if (demangled_func_not_found_.find(name) != demangled_func_not_found_.end()) { - sp_debug("NOT FOUND - %s is proved to be not found", name.c_str()); + sp_debug_agent("NOT FOUND - %s is proved to be not found", name.c_str()); return false; } @@ -763,7 +763,7 @@ SpParser::FindFunction(string name, // 1. Not in inst_lib list // 2. In inst_lib, lib is libc, but function is not __libc_start_main if (!CanInstrumentLib(sp_filename(obj->name().c_str()))) { - sp_debug("Find Function: SKIP - lib %s for the function %s", sp_filename(obj->name().c_str()),name.c_str()); + sp_debug_agent("Find Function: SKIP - lib %s for the function %s", sp_filename(obj->name().c_str()),name.c_str()); continue; } @@ -786,12 +786,75 @@ SpParser::FindFunction(string name, return true; } -// Find function by name. +// Find function by mangled name. +FuncSet +SpParser::FindFunctionByMangledName(string name) { + sp_debug_agent("LOOKING FOR FUNC BY MANGLED NAME - looking for %s", + name.c_str()); + + FuncSet found_funcs; + if (name.length() == 0) { + return found_funcs; + } + + // A quick return, if this function is in the cache + if (mangled_func_map_.find(name) != mangled_func_map_.end()) { + sp_debug_agent("GOT FROM CACHE - %s", + FUNC_CAST((*mangled_func_map_[name].begin()))->GetMangledName().c_str()); + std::copy(mangled_func_map_[name].begin(), mangled_func_map_[name].end(), inserter(found_funcs, found_funcs.begin())); + return found_funcs; + } + + // A quick return, if this function is proved to be not found + if (mangled_func_not_found_.find(name) != mangled_func_not_found_.end()) { + sp_debug_agent("NOT FOUND - %s is proved to be not found", name.c_str()); + return found_funcs; + } + + // Iterate through each object to look for this function + assert(mgr_); + ph::AddrSpace* as = mgr_->as(); + FuncSet func_set; + for (ph::AddrSpace::ObjMap::iterator ci = as->objMap().begin(); + ci != as->objMap().end(); ci++) { + SpObject* obj = OBJ_CAST(ci->second); + if (strcmp(sp_filename(obj->name().c_str()), "libagent.so") == 0) { + sp_debug_agent("SKIP - lib %s", sp_filename(obj->name().c_str())); + continue; + } + + // Two cases to skip: + // 1. Not in inst_lib list + // 2. In inst_lib, lib is libc, but function is not __libc_start_main + if (!CanInstrumentLib(sp_filename(obj->name().c_str()))) { + sp_debug_agent("SKIP - lib %s for the function %s", sp_filename(obj->name().c_str()),name.c_str()); + continue; + } + + GetFuncsByName(obj, name, true, &func_set); + } + + if (func_set.size() == 0) { + mangled_func_not_found_.insert(name); + sp_debug_agent("NO FOUND - %s", name.c_str()); + return found_funcs; + } + + //std::copy(func_set.begin(), func_set.end(), inserter(mangled_func_map_[name], mangled_func_map_[name].begin())); + std::copy(func_set.begin(), func_set.end(), inserter(found_funcs, found_funcs.begin())); + assert(found_funcs.size() > 0); + sp_debug_agent("FOUND - %lu instances of %s, first in object %s", found_funcs.size(), name.c_str(), + FUNC_CAST((*func_set.begin()))->GetObject()->name().c_str()); + return found_funcs; +} + +// Find function by name. +/* SpFunction* SpParser::FindFunction(string name) { - sp_debug("LOOKING FOR FUNC BY MANGLED NAME - looking for %s", + sp_debug_agent("LOOKING FOR FUNC BY MANGLED NAME - looking for %s", name.c_str()); if (name.length() == 0) { @@ -800,14 +863,14 @@ SpParser::FindFunction(string name) { // A quick return, if this function is in the cache if (mangled_func_map_.find(name) != mangled_func_map_.end()) { - sp_debug("GOT FROM CACHE - %s", + sp_debug_agent("GOT FROM CACHE - %s", mangled_func_map_[name]->name().c_str()); return mangled_func_map_[name]; } // A quick return, if this function is proved to be not found if (mangled_func_not_found_.find(name) != mangled_func_not_found_.end()) { - sp_debug("NOT FOUND - %s is proved to be not found", name.c_str()); + sp_debug_agent("NOT FOUND - %s is proved to be not found", name.c_str()); return NULL; } @@ -820,7 +883,7 @@ SpParser::FindFunction(string name) { SpObject* obj = OBJ_CAST(ci->second); if (strcmp(sp_filename(obj->name().c_str()), "libagent.so") == 0) { - sp_debug("SKIP - lib %s", sp_filename(obj->name().c_str())); + sp_debug_agent("SKIP - lib %s", sp_filename(obj->name().c_str())); continue; } @@ -828,7 +891,7 @@ SpParser::FindFunction(string name) { // 1. Not in inst_lib list // 2. In inst_lib, lib is libc, but function is not __libc_start_main if (!CanInstrumentLib(sp_filename(obj->name().c_str()))) { - sp_debug("SKIP - lib %s for the function %s", sp_filename(obj->name().c_str()),name.c_str()); + sp_debug_agent("SKIP - lib %s for the function %s", sp_filename(obj->name().c_str()),name.c_str()); continue; } @@ -838,15 +901,15 @@ SpParser::FindFunction(string name) { // We skip the case multiple functions have the same name if (func_set.size() == 1) { mangled_func_map_[name] = *func_set.begin(); - sp_debug("FOUND - %s in object %s", name.c_str(), + sp_debug_agent("FOUND - %s in object %s", name.c_str(), FUNC_CAST((*func_set.begin()))->GetObject()->name().c_str()); return *func_set.begin(); } mangled_func_not_found_.insert(name); - sp_debug("NO FOUND - %s", name.c_str()); + sp_debug_agent("NO FOUND - %s", name.c_str()); return NULL; -} +}*/ size_t total_count=0; size_t total_size=0; @@ -858,12 +921,12 @@ SpParser::GetFuncsByName(sp::SpObject* obj, sp::FuncSet* func_set) { assert(obj); assert(func_set); - sp_debug("IN OBJECT - %s in %s?", + sp_debug_agent("IN OBJECT - %s in %s?", name.c_str(), obj->name().c_str()); if ((strcmp(name.c_str(), "recv") != 0) && (strcmp(name.c_str(), "read") != 0) && obj->name().find("libc-") != std::string::npos && strcmp(name.c_str(), "__libc_start_main") != 0) { - sp_debug("Find function: SKIP - lib %s and non __libc_start_main for the function %s", + sp_debug_agent("Find function: SKIP - lib %s and non __libc_start_main for the function %s", sp_filename(obj->name().c_str()),name.c_str()); return false; } @@ -891,7 +954,7 @@ SpParser::GetFuncsByName(sp::SpObject* obj, found->GetMangledName().length() == 0 || found->GetMangledName().compare(name) != 0) { /* - sp_debug("SKIP %s - mangled name %s length %ld", + sp_debug_agent("SKIP %s - mangled name %s length %ld", (*fit)->name().c_str(), found->GetMangledName().c_str(), found->GetMangledName().length()); @@ -902,12 +965,12 @@ SpParser::GetFuncsByName(sp::SpObject* obj, if (!found || found->name().length() == 0 || found->name().compare(name) != 0) { - // sp_debug("found [%s] name [%s]", found->name().c_str(), name.c_str()); + // sp_debug_agent("found [%s] name [%s]", found->name().c_str(), name.c_str()); continue; } } - sp_debug("GOT %s in OBJECT - %s at %lx", + sp_debug_agent("GOT %s in OBJECT - %s at %lx", name.c_str(), sym->name().c_str(), found->addr() - obj->load_addr()); @@ -934,7 +997,7 @@ SpParser::FindPltFunc(sp::SpObject* obj, assert(symtab); std::vector fbt; if (!symtab->getFuncBindingTable(fbt)) { - sp_debug("No relocation information for this Symtab"); + sp_debug_agent("No relocation information for this Symtab"); return false; } //Get the code Source of this symtab @@ -945,10 +1008,10 @@ SpParser::FindPltFunc(sp::SpObject* obj, for (u_int i = 0; i < fbt.size(); i++) { if (fbt[i].target_addr() == pltFuncAddr) { - sp_debug("Plt function address %lx", pltFuncAddr); + sp_debug_agent("Plt function address %lx", pltFuncAddr); // check to see if this function has been bound yet if (hasBeenBound(fbt[i],objLoadAddr,func_set)) { - sp_debug("GOT %s from FindPltFunc, Object - %s", + sp_debug_agent("GOT %s from FindPltFunc, Object - %s", name.c_str(), symtab->name().c_str()); return true; } @@ -968,19 +1031,19 @@ bool SpParser::hasBeenBound(const sb::relocationEntry &entry, dt::Address got_entry = entry.rel_addr() + base_addr; // dt::Address bound_addr = 0; - sp_debug("function relative address %lx, object base address %lx, got_entry %lx",entry.rel_addr(),base_addr,got_entry); + sp_debug_agent("function relative address %lx, object base address %lx, got_entry %lx",entry.rel_addr(),base_addr,got_entry); //unsigned tmp = 0; //Read the value in the address got_entry - sp_debug("Bound address %lx ", got_entry);//bound_addr); + sp_debug_agent("Bound address %lx ", got_entry);//bound_addr); // the callee function has been bound by the runtime linker // find function and return SpFunction* func=FindFunction(got_entry); if (func==NULL) { - sp_debug("FindFunction in hasbeenBound failed"); + sp_debug_agent("FindFunction in hasbeenBound failed"); return false; } else { - sp_debug("Function from FindFunction(Address) %s",func->name().c_str()); + sp_debug_agent("Function from FindFunction(Address) %s",func->name().c_str()); func_set->insert(func); return true; } @@ -1031,7 +1094,7 @@ SpParser::ParseDlExit(SpPoint* pt) { al->getLoadAddress(sym, load_addr); SpObject* patch_obj = g_parser->CreateObject(sym, load_addr); if (!patch_obj) { - sp_debug("FAILED TO CREATE PATCH OBJECT"); + sp_debug_agent("FAILED TO CREATE PATCH OBJECT"); return false; } as->loadObject(patch_obj); diff --git a/src/agent/parser.h b/src/agent/parser.h index a3698a37d..d400d3a0e 100644 --- a/src/agent/parser.h +++ b/src/agent/parser.h @@ -53,7 +53,7 @@ namespace sp { typedef std::vector PatchObjects; typedef std::set FuncSet; - typedef std::map MangledFuncMap; + typedef std::map MangledFuncMap; typedef std::map AddrFuncMap; typedef std::map DemangledFuncsMap; @@ -106,11 +106,14 @@ namespace sp { AGENT_EXPORT SpFunction* FindFunction(dt::Address absolute_addr); - AGENT_EXPORT SpFunction* - FindFunction(string func_name); AGENT_EXPORT bool FindFunction(string func_name, FuncSet* found_funcs); + AGENT_EXPORT FuncSet + FindFunctionByMangledName(string func_name); + + /*AGENT_EXPORT SpFunction* + FindFunction(string func_name);*/ AGENT_EXPORT SpFunction* callee(SpPoint* point, diff --git a/src/agent/patchapi/addr_space-x86_64.cc b/src/agent/patchapi/addr_space-x86_64.cc index 48ef32103..f189e4101 100644 --- a/src/agent/patchapi/addr_space-x86_64.cc +++ b/src/agent/patchapi/addr_space-x86_64.cc @@ -129,14 +129,14 @@ SpAddrSpace::UpdateMemoryMappings() { void SpAddrSpace::DumpMemoryMappings() { - sp_debug("MMAPS - %lu memory mappings", + sp_debug_patchapi("MMAPS - %lu memory mappings", (unsigned long)mem_maps_.size()); for (MemMappings::iterator mi = mem_maps_.begin(); mi != mem_maps_.end(); mi++) { MemMapping& mapping = mi->second; - sp_debug("MMAP - Range[%lx ~ %lx], Offset %lx, Perm %x, Dev %s," + sp_debug_patchapi("MMAP - Range[%lx ~ %lx], Offset %lx, Perm %x, Dev %s," " Inode %lu, Path %s, previous_end %lx", mapping.start, mapping.end, mapping.offset, mapping.perms, mapping.dev.c_str(), mapping.inode, @@ -195,10 +195,10 @@ SpAddrSpace::UpdateFreeIntervals() { SpObject* obj = OBJ_CAST(i->second); assert(obj); - sp_debug("HANDLING OBJECT - %s @ load addr: %lx, code base: %lx", + sp_debug_patchapi("HANDLING OBJECT - %s @ load addr: %lx, code base: %lx", obj->name().c_str(), obj->load_addr(), obj->codeBase()); MemMapping& mapping = mem_maps_[obj->load_addr()]; - sp_debug("MMAP - Range[%lx ~ %lx], Offset %lx, Perm %x, Dev %s," + sp_debug_patchapi("MMAP - Range[%lx ~ %lx], Offset %lx, Perm %x, Dev %s," " Inode %lu, Path %s, previous_end %lx", mapping.start, mapping.end, mapping.offset, mapping.perms, mapping.dev.c_str(), mapping.inode, @@ -207,7 +207,7 @@ SpAddrSpace::UpdateFreeIntervals() { FreeInterval* interval = NULL; if (!GetClosestInterval(mapping.start, &interval)) { - sp_debug("FAILED TO GET FREE INTERVAL - for %lx %s", + sp_debug_patchapi("FAILED TO GET FREE INTERVAL - for %lx %s", mapping.start, obj->name().c_str()); continue; } @@ -215,7 +215,7 @@ SpAddrSpace::UpdateFreeIntervals() { size_t size = interval->size(); size_t ps = getpagesize(); - sp_debug("GET FREE INTERVAL - [%lx, %lx], w/ original size %ld, " + sp_debug_patchapi("GET FREE INTERVAL - [%lx, %lx], w/ original size %ld, " "rounded size %ld", (long)interval->start, (long)interval->end, (long)interval->size(), (long)size); @@ -235,7 +235,7 @@ void SpAddrSpace::DumpFreeIntervals() { for (FreeIntervalList::iterator i = free_intervals_.begin(); i != free_intervals_.end(); i++) { - sp_debug("FREE INTERVAL - [%lx ~ %lx], used %d, size: %ld MB", + sp_debug_patchapi("FREE INTERVAL - [%lx ~ %lx], used %d, size: %ld MB", (*i).start, (*i).end, (*i).used, (*i).size()/1024/1024); } } @@ -246,12 +246,12 @@ SpAddrSpace::allocateNewInterval(SpObject* obj) { sp_perror("NULL pointer to SpObject when trying to allocate a new interval for object"); return false; } - sp_debug("Trying to allocate new interval for object %s", obj->name().c_str()); + sp_debug_patchapi("Trying to allocate new interval for object %s", obj->name().c_str()); - sp_debug("HANDLING OBJECT - %s @ load addr: %lx, code base: %lx", + sp_debug_patchapi("HANDLING OBJECT - %s @ load addr: %lx, code base: %lx", obj->name().c_str(), obj->load_addr(), obj->codeBase()); MemMapping& mapping = mem_maps_[obj->load_addr()]; - sp_debug("MMAP - Range[%lx ~ %lx], Offset %lx, Perm %x, Dev %s," + sp_debug_patchapi("MMAP - Range[%lx ~ %lx], Offset %lx, Perm %x, Dev %s," " Inode %lu, Path %s, previous_end %lx", mapping.start, mapping.end, mapping.offset, mapping.perms, mapping.dev.c_str(), mapping.inode, @@ -260,7 +260,7 @@ SpAddrSpace::allocateNewInterval(SpObject* obj) { FreeInterval* interval = NULL; if (!GetClosestInterval(mapping.start, &interval)) { - sp_debug("FAILED TO GET FREE INTERVAL - for %lx %s", + sp_debug_patchapi("FAILED TO GET FREE INTERVAL - for %lx %s", mapping.start, obj->name().c_str()); return false; } @@ -268,7 +268,7 @@ SpAddrSpace::allocateNewInterval(SpObject* obj) { size_t size = interval->size(); size_t ps = getpagesize(); - sp_debug("GET FREE INTERVAL - [%lx, %lx], w/ original size %ld, " + sp_debug_patchapi("GET FREE INTERVAL - [%lx, %lx], w/ original size %ld, " "rounded size %ld", (long)interval->start, (long)interval->end, (long)interval->size(), (long)size); @@ -295,19 +295,19 @@ SpAddrSpace::GetClosestInterval(dt::Address addr, // Bind a free interval before this object, and the distance should // be shorter than 1.5GB - sp_debug("GET CLOSEST INTERVAL - free interval [%lx, %lx], size %ld", + sp_debug_patchapi("GET CLOSEST INTERVAL - free interval [%lx, %lx], size %ld", (*i).start, (*i).end, (*i).size()); if ((*i).start > addr) { - sp_debug("start larger than addr"); + sp_debug_patchapi("start larger than addr"); continue; } else { if (!previous) return false; if (previous->used) { - sp_debug("this interval already used"); + sp_debug_patchapi("this interval already used"); continue; } if ((addr - (*i).start) > distance) { - sp_debug("distance too far"); + sp_debug_patchapi("distance too far"); continue; } *interval = previous; diff --git a/src/agent/patchapi/addr_space.cc b/src/agent/patchapi/addr_space.cc index 1c7ca5cf9..07c65d42f 100644 --- a/src/agent/patchapi/addr_space.cc +++ b/src/agent/patchapi/addr_space.cc @@ -93,19 +93,19 @@ namespace sp { size_t length, int perm) { bool ret = false; - sp_debug("SETTING MEMORY PERM - for [%lx ~ %lx] of %ld bytes", + sp_debug_patchapi("SETTING MEMORY PERM - for [%lx ~ %lx] of %ld bytes", (long)a, (long)(a + length - 1), (long)length); dt::Address aligned = a; size_t pz = getpagesize(); if (a > pz) { - sp_debug("PAGE SIZE SMALLER - pagesize %lx, address %lx", + sp_debug_patchapi("PAGE SIZE SMALLER - pagesize %lx, address %lx", (long)pz, (long)a); aligned = (dt::Address)(((dt::Address) aligned) & ~(pz-1)); } else if (a % pz == 0) { aligned = a; } else { - sp_debug("PAGE SIZE LARGER - pagesize %lx, address %lx", + sp_debug_patchapi("PAGE SIZE LARGER - pagesize %lx, address %lx", (long)pz, (long)a); // assert(0 && "LARGE PAGE SIZE?"); return false; @@ -113,14 +113,14 @@ namespace sp { } size_t len = length + (a - aligned); - sp_debug("TRY mprotect - for [%lx ~ %lx] of %ld bytes", + sp_debug_patchapi("TRY mprotect - for [%lx ~ %lx] of %ld bytes", (long)aligned, (long)(aligned + len - 1), (long)len); if (mprotect((void*)aligned, len, perm) < 0) { - sp_debug("MPROTECT - Failed to change memory access permission"); + sp_debug_patchapi("MPROTECT - Failed to change memory access permission"); // perror("mprotect"); return false; } else { - sp_debug("MPROTECT - SUCCEED TO change memory access" + sp_debug_patchapi("MPROTECT - SUCCEED TO change memory access" " perm for %lx in [%lx, %lx]", a, aligned, aligned+len-1); ret = true; } diff --git a/src/agent/patchapi/addr_space_unittest.cc b/src/agent/patchapi/addr_space_unittest.cc index 2a0f7cc39..f0a3b0336 100644 --- a/src/agent/patchapi/addr_space_unittest.cc +++ b/src/agent/patchapi/addr_space_unittest.cc @@ -51,20 +51,20 @@ TEST_F(AddrSpaceTest, simple_malloc_free) { SpObject* exe = agent_->parser()->exe(); dt::Address buf = as_->malloc(exe, 100, 0); EXPECT_TRUE(IsDisp32(buf - exe->load_addr())); - sp_debug("SMALL BUF - %lx", buf); + sp_debug_patchapi("SMALL BUF - %lx", buf); buf = as_->malloc(exe, 500, 0); EXPECT_TRUE(IsDisp32(buf - exe->load_addr())); - sp_debug("MID BUF - %lx", buf); + sp_debug_patchapi("MID BUF - %lx", buf); buf = as_->malloc(exe, 4000, 0); EXPECT_TRUE(IsDisp32(buf - exe->load_addr())); - sp_debug("LARGE BUF - %lx", buf); + sp_debug_patchapi("LARGE BUF - %lx", buf); // Should use mmap to allocate buf = as_->malloc(exe, 40000, 0); EXPECT_TRUE(buf != 0); - sp_debug("MMAPED - %lx", buf); + sp_debug_patchapi("MMAPED - %lx", buf); } } diff --git a/src/agent/patchapi/cfg.cc b/src/agent/patchapi/cfg.cc index e98e6ab31..feec9e31f 100644 --- a/src/agent/patchapi/cfg.cc +++ b/src/agent/patchapi/cfg.cc @@ -54,7 +54,7 @@ namespace sp { } } if (symbols.size() == 0) { - //sp_debug("GetMangledName: found no symbol, returning empty string"); + //sp_debug_patchapi("GetMangledName: found no symbol, returning empty string"); return ""; } return (symbols)[0]->getMangledName(); diff --git a/src/agent/patchapi/instrumenter.cc b/src/agent/patchapi/instrumenter.cc index 55b4dcf23..60c1a444e 100644 --- a/src/agent/patchapi/instrumenter.cc +++ b/src/agent/patchapi/instrumenter.cc @@ -59,29 +59,29 @@ namespace sp { SpInstrumenter::SpInstrumenter(ph::AddrSpace* as) : ph::Instrumenter(as) { - sp_debug("INSTRUMENTER - created"); + sp_debug_patchapi("INSTRUMENTER - created"); // Relocate insn if (getenv("SP_TEST_RELOCINSN")) { - sp_debug("ONLY TEST RELOCINSN WORKER"); + sp_debug_patchapi("ONLY TEST RELOCINSN WORKER"); workers_.push_back(new RelocCallInsnWorker); } // Relocate call block if (getenv("SP_TEST_RELOCBLK")) { - sp_debug("ONLY TEST RELOCBLK WORKER"); + sp_debug_patchapi("ONLY TEST RELOCBLK WORKER"); workers_.push_back(new RelocCallBlockWorker); } // Only use springboard if (getenv("SP_TEST_SPRING")) { - sp_debug("ONLY TEST SPRING BOARD WORKER"); + sp_debug_patchapi("ONLY TEST SPRING BOARD WORKER"); workers_.push_back(new SpringboardWorker); } // Only use trap if (getenv("SP_TEST_TRAP")) { - sp_debug("ONLY TEST TRAP WORKER"); + sp_debug_patchapi("ONLY TEST TRAP WORKER"); workers_.push_back(new TrapWorker); } @@ -89,7 +89,7 @@ namespace sp { getenv("SP_TEST_RELOCBLK") || getenv("SP_TEST_SPRING") || getenv("SP_TEST_TRAP")) { - sp_debug("DEBUGGING MODE - test a subset of workers"); + sp_debug_patchapi("DEBUGGING MODE - test a subset of workers"); return; } @@ -119,7 +119,7 @@ namespace sp { static_cast(*c); if (!command) { - sp_debug("BAD COMMAND - skip"); + sp_debug_patchapi("BAD COMMAND - skip"); continue; } @@ -127,14 +127,14 @@ namespace sp { assert(spt); SpBlock* blk = spt->GetBlock(); assert(blk); - sp_debug("INSTRUMENTING POINT - for call insn %lx", blk->last()); + sp_debug_patchapi("INSTRUMENTING POINT - for call insn %lx", blk->last()); // If we only want to instrument direct call, and this point is a // indirect call point, then skip it if (spt && !spt->getCallee() && g_context->IsDirectcallOnlyEnabled()) { - sp_debug("INDIRECT CALL - skip"); + sp_debug_patchapi("INDIRECT CALL - skip"); continue; } @@ -147,7 +147,7 @@ namespace sp { assert(callinsn.ptr()); if (callinsn.getCategory() == in::c_BranchInsn) { - sp_debug("TAIL CALL - for call insn %lx", blk->last()); + sp_debug_patchapi("TAIL CALL - for call insn %lx", blk->last()); if (getenv("SP_NO_TAILCALL")) { continue; } @@ -166,23 +166,23 @@ namespace sp { // very dangous when we want to restore in the future. // If this worker succeeds, then we are done for current point if (worker->save(spt)) { - sp_debug("SAVE SUCCESSFULLY"); + sp_debug_patchapi("SAVE SUCCESSFULLY"); if (worker->run(spt)) { blk->SetInstrumented(true); spt->SetInstallMethod(worker->install_method()); ++success_count; break; // escape the worker loop } else { - sp_debug("FAILED TO INSTALL - for call insn %lx", + sp_debug_patchapi("FAILED TO INSTALL - for call insn %lx", blk->last()); } // install } else { - sp_debug("FAILED TO SAVE - for call insn %lx", blk->last()); + sp_debug_patchapi("FAILED TO SAVE - for call insn %lx", blk->last()); } // save } // workers } // commands - sp_debug("BATCH DONE - %d / %lu succeeded", success_count, + sp_debug_patchapi("BATCH DONE - %d / %lu succeeded", success_count, (unsigned long)user_commands_.size()); user_commands_.clear(); diff --git a/src/agent/patchapi/object-i386.cc b/src/agent/patchapi/object-i386.cc index a4837e44d..863d53735 100644 --- a/src/agent/patchapi/object-i386.cc +++ b/src/agent/patchapi/object-i386.cc @@ -45,7 +45,7 @@ namespace sp { SpObject::AllocateBuffer(size_t size) { dt::Address ret = 0; if (::posix_memalign((void**)&ret, getpagesize(), size) == 0) { - sp_debug("FAILED TO GET A CLOSE BUFFER - %lx malloced", ret); + sp_debug_patchapi("FAILED TO GET A CLOSE BUFFER - %lx malloced", ret); } return ret; } diff --git a/src/agent/patchapi/object-x86_64.cc b/src/agent/patchapi/object-x86_64.cc index fe50224f8..721e936d9 100644 --- a/src/agent/patchapi/object-x86_64.cc +++ b/src/agent/patchapi/object-x86_64.cc @@ -39,7 +39,7 @@ namespace sp { void SpObject::InitMemoryAlloc(dt::Address base, size_t size) { - sp_debug("INIT MEMORY ALLOC - base %lx, size %ld", + sp_debug_patchapi("INIT MEMORY ALLOC - base %lx, size %ld", (long)base, (long)size); // MMap this big buffer @@ -64,11 +64,11 @@ namespace sp { } if (m == MAP_FAILED) { - sp_debug("%s: FAILED TO MAP TO %lx (size %ld)", + sp_debug_patchapi("%s: FAILED TO MAP TO %lx (size %ld)", name().c_str(), (long)base, (long)size); return; } else { - sp_debug("%s: SUCCEED TO MAP TO %lx (size %ld)", + sp_debug_patchapi("%s: SUCCEED TO MAP TO %lx (size %ld)", name().c_str(), (long)m, (long)size); } @@ -93,21 +93,21 @@ namespace sp { if (small_freebufs_.buf_size >= size) { ret = small_freebufs_.base; - //sp_debug("Number of free buffers: %d", small_freebufs_.list.size()); - sp_debug("%s: Returning %lu buffer at %lx", name().c_str(), size, ret); + //sp_debug_patchapi("Number of free buffers: %d", small_freebufs_.list.size()); + sp_debug_patchapi("%s: Returning size %lu buffer at %lx from interval [%lx, %lx]", name().c_str(), size, ret, small_freebufs_.base, (small_freebufs_.base + small_freebufs_.buf_size)); small_freebufs_.base += (size+1); small_freebufs_.buf_size -= (size+1); - sp_debug("%s: %lu bytes left", name().c_str(), small_freebufs_.buf_size); + sp_debug_patchapi("%s: %lu bytes left in interval [%lx, %lx]", name().c_str(), small_freebufs_.buf_size, small_freebufs_.base, (small_freebufs_.base + small_freebufs_.buf_size)); return ret; } size_t ps = getpagesize(); size = ((size + ps -1) & ~(ps - 1)); if (::posix_memalign((void**)&ret, ps, size) == 0) { // sp_print("FAILED TO GET A CLOSE BUFFER - %lx malloced", ret); - sp_debug("FAILED TO GET A CLOSE BUFFER - %lx malloced", ret); + sp_debug_patchapi("FAILED TO GET A CLOSE BUFFER - %lu at %lx malloced", size, ret); return ret; } - sp_debug("FAILED TO GET A CLOSE BUFFER - 0 is malloced"); + sp_debug_patchapi("FAILED TO GET A CLOSE BUFFER - 0 is malloced"); return 0; } @@ -116,7 +116,7 @@ namespace sp { if (!buf) return false; if (alloc_bufs_.find(buf) == alloc_bufs_.end()) { - sp_debug("FREE FROM MALLOC-ed - %lx is allocated by malloc", buf); + sp_debug_patchapi("FREE FROM MALLOC-ed - %lx is allocated by malloc", buf); ::free((void*)buf); buf = (dt::Address)NULL; return true; @@ -127,12 +127,6 @@ namespace sp { case SMALL_BUF: small_freebufs_.list.push_back(buf); break; - case MID_BUF: - mid_freebufs_.list.push_back(buf); - break; - case BIG_BUF: - big_freebufs_.list.push_back(buf); - break; default: sp_perror("UNKNOWN FREE - %lx", buf); assert(0); diff --git a/src/agent/patchapi/object.h b/src/agent/patchapi/object.h index c2742abf1..ce7cb596a 100644 --- a/src/agent/patchapi/object.h +++ b/src/agent/patchapi/object.h @@ -44,9 +44,7 @@ namespace sp { typedef std::list FreeList; typedef enum { - SMALL_BUF, - MID_BUF, - BIG_BUF + SMALL_BUF } BufType; typedef std::map BufTypeMap; @@ -72,6 +70,7 @@ namespace sp { load_addr_(la), symtab_(symtab) {} + dt::Address load_addr() const { return load_addr_; } // Get this object's name @@ -88,9 +87,8 @@ namespace sp { std::string name_; sb::Symtab* symtab_; - FreeBufs small_freebufs_; // Small buffers - FreeBufs mid_freebufs_; // Midium buffers - FreeBufs big_freebufs_; // Big buffers + FreeBufs small_freebufs_ {}; // Small buffers + BufTypeMap alloc_bufs_; // To facilitate future deallocation typedef std::map BufSizeMap; // For the mmap-ed BufSizeMap buf_size_map_; diff --git a/src/agent/payload.cc b/src/agent/payload.cc index 652d402e8..989af93a2 100644 --- a/src/agent/payload.cc +++ b/src/agent/payload.cc @@ -44,6 +44,7 @@ using std::string; // do instrumentation, the purpose of this is to stop // instrumentation when we hit exit function std::atomic IN_INSTRUMENTATION {1}; +bool inTramp = false; namespace sp { extern SpContext* g_context; @@ -90,6 +91,21 @@ void PointCallHandle::SetReturnValue(long ret_val) { } } +class TrampGuard { + public: + TrampGuard(bool &b): guard(b) { + if (!guard) + guard = true; + else { + sp_perror("Tramp guard error"); + assert(false); + } + } + ~TrampGuard() {guard = false;} + private: + bool &guard; +}; + ////////////////////////////////////////////////////////////////////// /** @@ -102,38 +118,43 @@ void PointCallHandle::SetReturnValue(long ret_val) { */ void wrapper_entry(sp::SpPoint* pt, - sp::PayloadFuncEntry entry) { - sp_debug("In wrapper entry function for point %p", pt); - if (sp::g_context == NULL) { - sp_perror("Global context is NULL, return"); - return; - } + sp::PayloadFuncEntry sp_entry) { - void* user_info = NULL; - sp::SpFunction* callee = sp::Callee(pt); + if (inTramp) return; + TrampGuard trampGuard(inTramp); + sp_debug_agent("In wrapper entry function for point %p", pt); + + if (sp::g_context == NULL) { + sp_perror("Global context is NULL, return"); + return; + } - sp::PointCallHandle* call_handle = - new sp::PointCallHandle(pt, callee); + void* user_info = NULL; + sp::SpFunction* callee = sp::Callee(pt); - if (callee != NULL) { - // Handle IPC stuffs - if (sp::g_context->IsIpcEnabled()) { - sp::SpIpcMgr::BeforeEntry(pt); - } + sp::PointCallHandle* call_handle = + new sp::PointCallHandle(pt, callee); - // Handle multihread stuffs - if (sp::g_context->IsMultithreadEnabled()) { - sp::SpThreadMgr::BeforeEntry(pt); - } + if (callee != nullptr) { + // Handle IPC stuffs + if (sp::g_context->IsIpcEnabled()) { + sp::SpIpcMgr::BeforeEntry(pt); + } - if (entry) { - user_info = entry(call_handle); - } + // Handle multihread stuffs + if (sp::g_context->IsMultithreadEnabled()) { + sp::SpThreadMgr::BeforeEntry(pt); + } - call_handle->SetUserInfo(user_info); - } + if (sp_entry) { + user_info = sp_entry(call_handle); + } + + call_handle->SetUserInfo(user_info); + } - sp::g_context->PushPointCallHandle(call_handle); + sp::g_context->PushPointCallHandle(call_handle); + } /////////////////////////////////////////////////////////////////////////////// @@ -153,63 +174,67 @@ wrapper_entry(sp::SpPoint* pt, */ void wrapper_exit(sp::SpPoint* pt, - sp::PayloadFuncExit exit) { - sp_debug("In wrapper exit function for point %p", pt); - - sp::PointCallHandle* call_handle; - long ret_val; + sp::PayloadFuncExit sp_exit) { + + if (inTramp) return; + TrampGuard trampGuard(inTramp); + sp_debug_agent("In wrapper exit function for point %p", pt); + + sp::PointCallHandle* call_handle; + long ret_val; - // 1. Retrieving point information and the return value. - // Due to the property of tailcalls, the return value is the same for all - // of the previous tailcalls - call_handle = sp::g_context->PopPointCallHandle(); - ret_val = ReturnValue(pt); + // 1. Retrieving point information and the return value. + // Due to the property of tailcalls, the return value is the same for all + // of the previous tailcalls + call_handle = sp::g_context->PopPointCallHandle(); + ret_val = ReturnValue(pt); - call_handle->SetReturnValue(ret_val); + call_handle->SetReturnValue(ret_val); - // 2. Iterate through all the missed tailcall information and call the exit - // payload function for all of them - while (pt != call_handle->GetPoint()) { - sp_debug("Got info from previous tail call %p", call_handle->GetPoint()); + // 2. Iterate through all the missed tailcall information and call the exit + // payload function for all of them + while (pt != call_handle->GetPoint()) { + sp_debug_agent("Got info from previous tail call %p", call_handle->GetPoint()); - if (!call_handle->GetPoint()->tailcall()) { - sp_debug("ERROR: this point is not tailcall"); - } + if (!call_handle->GetPoint()->tailcall()) { + sp_debug_agent("ERROR: this point is not tailcall"); + } - // Handle IPC stuffs + // Handle IPC stuffs + if (sp::g_context->IsIpcEnabled()) { + sp::SpIpcMgr::BeforeExit(call_handle); + } + + // Handle dlopen + if (sp::g_context->IsHandleDlopenEnabled()) { + sp::SpParser::ParseDlExit(call_handle->GetPoint()); + } + + if (sp_exit) { + sp_exit(call_handle); + } + + delete call_handle; + call_handle = sp::g_context->PopPointCallHandle(); + call_handle->SetReturnValue(ret_val); + } + + // 3. Now, deal with the current call handler if (sp::g_context->IsIpcEnabled()) { sp::SpIpcMgr::BeforeExit(call_handle); } // Handle dlopen if (sp::g_context->IsHandleDlopenEnabled()) { - sp::SpParser::ParseDlExit(call_handle->GetPoint()); + sp::SpParser::ParseDlExit(pt); } - if (exit) { - exit(call_handle); + if (sp_exit) { + sp_exit(call_handle); } - - delete call_handle; - call_handle = sp::g_context->PopPointCallHandle(); - call_handle->SetReturnValue(ret_val); - } - - // 3. Now, deal with the current call handler - if (sp::g_context->IsIpcEnabled()) { - sp::SpIpcMgr::BeforeExit(call_handle); - } - // Handle dlopen - if (sp::g_context->IsHandleDlopenEnabled()) { - sp::SpParser::ParseDlExit(pt); - } - - if (exit) { - exit(call_handle); - } + delete call_handle; - delete call_handle; } @@ -247,7 +272,7 @@ default_exit(sp::PointCallHandle*) { */ void toggle_off_instrumentation_entry(sp::SpPoint* pt) { - sp_debug("PROCESS[%d] toggle off instrumentation", getpid()); + sp_debug_agent("PROCESS[%d] toggle off instrumentation", getpid()); IN_INSTRUMENTATION = 0; } @@ -319,10 +344,10 @@ Propel(SpPoint* pt) { // we stop instrumentation since the exit handlers call destructors for // all the global variables, and we can not rely on them any more if (!IN_INSTRUMENTATION) { - sp_debug("PROCESS[%d] Already hit exit function, skip instrumentation", getpid()); + sp_debug_agent("PROCESS[%d] Already hit exit function, skip instrumentation", getpid()); return; } else { - sp_debug("PROCESS[%d] still in instrumentation", getpid()); + sp_debug_agent("PROCESS[%d] still in instrumentation", getpid()); } sp::SpPropeller::ptr p = sp::SpPropeller::ptr(); @@ -331,19 +356,19 @@ Propel(SpPoint* pt) { SP_LOCK(PROPEL); f = CalleeNolock(pt); if (!f) { - sp_debug("NOT VALID FUNC - stop propagation"); + sp_debug_agent("NOT VALID FUNC - stop propagation"); goto PROPEL_EXIT; } // Skip if we have already propagated from this point if (f->propagated()) { - sp_debug("Already propagated, goto exit"); + sp_debug_agent("Already propagated, goto exit"); goto PROPEL_EXIT; } p = g_context->init_propeller(); if (!p) { - sp_debug("asserting propeller"); + sp_debug_agent("asserting propeller"); assert(p); } @@ -409,7 +434,7 @@ IsIpcRead(SpPoint* pt) { // if (c && c->rw == SP_READ) { ret = true; if (CalleeNolock(pt)->name().compare("accept") == 0) { - sp_debug("Accept skip"); + sp_debug_agent("Accept skip"); ret = false; } } diff --git a/src/agent/propeller.cc b/src/agent/propeller.cc index cc53a1155..074d3022a 100644 --- a/src/agent/propeller.cc +++ b/src/agent/propeller.cc @@ -41,6 +41,9 @@ #include "Command.h" #include "PatchMgr.h" +#include "PatchObject.h" +#include "agent/patchapi/object.h" + #include namespace sp { @@ -67,23 +70,23 @@ namespace sp { SpPoint* point, StringSet* inst_calls) { if (func == NULL) { - sp_debug("FATAL: func is NULL"); + sp_debug_agent("FATAL: func is NULL"); return false; } - sp_debug("START PROPELLING - propel to callees of function %s", + sp_debug_agent("START PROPELLING - propel to callees of function %s", func->name().c_str()); - if (func->name().find("std::")!=std::string::npos || func->name().find("cxx")!=std::string::npos) { - sp_debug("TODO: libstdc++ functions: stop propelling"); + /*if (func->name().find("std::")!=std::string::npos || func->name().find("cxx")!=std::string::npos) { + sp_debug_agent("TODO: libstdc++ functions: stop propelling"); return true; - } + }*/ // Skip propelling into functions that we do not want to instrument // We need this check if we are doing initial instrumentation for // all functions on the stack trace when agentlib is injected if (!g_parser->CanInstrumentFunc(func->name())) { - sp_debug("SKIP propel into - %s", func->name().c_str()); + sp_debug_agent("SKIP propel into - %s", func->name().c_str()); return false; } @@ -116,7 +119,7 @@ namespace sp { if (callee) { if (!g_parser->CanInstrumentFunc(callee->name())) { - sp_debug("SKIP NOT-INST FUNC - %s", callee->name().c_str()); + sp_debug_agent("SKIP NOT-INST FUNC - %s", callee->name().c_str()); continue; } @@ -124,23 +127,23 @@ namespace sp { if (inst_calls && (inst_calls->find(callee->name()) == inst_calls->end())) { // sp_print("SKIP NOT-INST CALL - %s", callee->name().c_str()); - sp_debug("SKIP NOT-INST CALL - %s", callee->name().c_str()); + sp_debug_agent("SKIP NOT-INST CALL - %s", callee->name().c_str()); continue; } - sp_debug("POINT - instrumenting direct call at %lx to " + sp_debug_agent("POINT - instrumenting direct call at %lx to " "function %s (%lx) for point %lx", blk->last(), callee->name().c_str(), (dt::Address)callee, (dt::Address)p); } else { if (inst_calls) { - sp_debug("SKIP INDIRECT CALL - at %lx", blk->last()); + sp_debug_agent("SKIP INDIRECT CALL - at %lx", blk->last()); continue; } - sp_debug("POINT - instrumenting indirect call at %lx for point %lx", + sp_debug_agent("POINT - instrumenting indirect call at %lx for point %lx", blk->last(), (dt::Address)p); } - sp_debug("PAYLOAD ENTRY - %lx", (long)entry); + sp_debug_agent("PAYLOAD ENTRY - %lx", (long)entry); p->SetCallerPt(point); SpSnippet::ptr sp_snip = SpSnippet::create(callee, p, @@ -160,10 +163,10 @@ namespace sp { bool ret = patcher.commit(); if (ret) { - sp_debug("FINISH PROPELLING - callees of function %s are" + sp_debug_agent("FINISH PROPELLING - callees of function %s are" " instrumented", func->name().c_str()); } else { - sp_debug("FINISH PROPELLING - instrumentation failed for" + sp_debug_agent("FINISH PROPELLING - instrumentation failed for" " callees of %s", func->name().c_str()); } return ret; @@ -176,18 +179,25 @@ namespace sp { SpPropeller::ModifyPC(SpFunction* func, PayloadFunc exit) { assert(func); - sp_debug("Modify PC for the function %s",func->name().c_str()); + sp_debug_agent("Modify PC for the function %s",func->name().c_str()); Points pts; ph::PatchMgrPtr mgr = g_parser->mgr(); assert(mgr); ph::PatchFunction* cur_func = NULL; - cur_func = g_parser->FindFunction(func->GetMangledName()); + FuncSet found_funcs; + //cur_func = g_parser->FindFunction(func->GetMangledName()); + found_funcs = g_parser->FindFunctionByMangledName(func->GetMangledName()); + + for (auto i: found_funcs) { + if (FUNC_CAST(i)->GetObject()->name() == func->GetObject()->name()) + cur_func = func; + } if (!cur_func) return false; //1. Find all return points next_ret_points(cur_func, mgr, pts); - sp_debug("No of return points for the function %s is %lu", func->name().c_str(),pts.size()); + sp_debug_agent("No of return points for the function %s is %lu", func->name().c_str(),pts.size()); //2.. Replace all the return points associated with the function with a trap instruction for(unsigned i=0; igetCategory() == in::c_CallInsn && a != last) { - sp_debug("THUNK CALL - at insn %lx", src_insn); + sp_debug_agent("THUNK CALL - at insn %lx", src_insn); // Case 2: handle thunk call // What thunk does, is to move current pc value to ebx. // mov orig_pc, ebx @@ -323,7 +323,7 @@ SpSnippet::GetSavedReg(Dyninst::MachRegister reg) { /* for (int i = 0; i < 32; i+=4) { - sp_debug("i: %d, EDI: %lx", i, reg_val(i)); + sp_debug_agent("i: %d, EDI: %lx", i, reg_val(i)); } */ namespace d32 = Dyninst::x86; @@ -331,11 +331,11 @@ SpSnippet::GetSavedReg(Dyninst::MachRegister reg) { dt::Address out = 0; if (GetRegInternal(reg, &out)) { - sp_debug("GOT REG - %s = %lx", reg.name().c_str(), out); + sp_debug_agent("GOT REG - %s = %lx", reg.name().c_str(), out); return out; } - sp_debug("NOT FOUND - %s", reg.name().c_str()); + sp_debug_agent("NOT FOUND - %s", reg.name().c_str()); return 0; } diff --git a/src/agent/snippet-x86_64.cc b/src/agent/snippet-x86_64.cc index 6c58289fc..d20df328e 100644 --- a/src/agent/snippet-x86_64.cc +++ b/src/agent/snippet-x86_64.cc @@ -595,12 +595,12 @@ dt::Address SpSnippet::GetSavedReg(dt::MachRegister reg) { /* for (int i = -64; i < 48; i++) { - sp_debug("DUMP SAVED REGS: %lx", reg_val((i*8))); + sp_debug_agent("DUMP SAVED REGS: %lx", reg_val((i*8))); } */ dt::Address out = 0; if (GetRegInternal(reg, &out)) { - sp_debug("GOT REG - %s = %lx", reg.name().c_str(), out); + sp_debug_agent("GOT REG - %s = %lx", reg.name().c_str(), out); return out; } @@ -609,15 +609,15 @@ dt::Address SpSnippet::GetSavedReg(dt::MachRegister reg) { namespace d64 = Dyninst::x86_64; if (reg == d64::rsp || reg == d64::esp || reg == d64::sp || reg == d64::spl) { - sp_debug("GOT SP - %s = %lx = %lx + %x", reg.name().c_str(), + sp_debug_agent("GOT SP - %s = %lx = %lx + %x", reg.name().c_str(), saved_context_loc_ + RSP, saved_context_loc_, RSP); if (func()) { - sp_debug("Before %s", func()->name().c_str()); + sp_debug_agent("Before %s", func()->name().c_str()); } return (saved_context_loc_ + RSP); } - sp_debug("NOT FOUND - %s", reg.name().c_str()); + sp_debug_agent("NOT FOUND - %s", reg.name().c_str()); return 0; } @@ -728,7 +728,7 @@ class EmuVisitor : public in::Visitor { // if (r->getID().isPC()) { imm_ = a_; stack_.push(imm_); - sp_debug("EMU VISITOR - pc %lx", a_); + sp_debug_agent("EMU VISITOR - pc %lx", a_); } } virtual void visit(in::BinaryFunction* b) { @@ -740,10 +740,10 @@ class EmuVisitor : public in::Visitor { if (b->isAdd()) { imm_ = i1 + i2; - sp_debug("EMU VISITOR - %lx + %lx = %lx", i1, i2, imm_); + sp_debug_agent("EMU VISITOR - %lx + %lx = %lx", i1, i2, imm_); } else if (b->isMultiply()) { imm_ = i1 * i2; - sp_debug("EMU VISITOR - %lx * %lx = %lx", i1, i2, imm_); + sp_debug_agent("EMU VISITOR - %lx * %lx = %lx", i1, i2, imm_); } else { assert(0); } @@ -770,7 +770,7 @@ class EmuVisitor : public in::Visitor { break; } } - sp_debug("EMU VISITOR - IMM %lx", imm_); + sp_debug_agent("EMU VISITOR - IMM %lx", imm_); stack_.push(imm_); } virtual void visit(in::Dereference* d) { @@ -868,7 +868,7 @@ class EmuVisitor : public in::Visitor { if ((char)insn_buf[1] == (char)0x8d) { int* dis = get_disp(insn, insn_buf); - sp_debug("LEA - orig-disp(%d), orig-insn-addr(%lx)," + sp_debug_agent("LEA - orig-disp(%d), orig-insn-addr(%lx)," " orig-insn-size(%ld), abs-trg(%lx)", *dis, a, insn->size(), *dis+a+insn->size()); @@ -881,7 +881,7 @@ class EmuVisitor : public in::Visitor { e->apply(&visitor); *l = visitor.imm(); - sp_debug("OTHER PC-INSN - orig-insn-size(%ld), abs-trg(%lx)", + sp_debug_agent("OTHER PC-INSN - orig-insn-size(%ld), abs-trg(%lx)", insn->size(), *l); } @@ -956,7 +956,7 @@ bool SpSnippet::getTargetAddr(dt::Address a, in::Instruction insn, // Bind succeeded, eval to get targetAddr address in::Result res = exp->eval(); if (!res.defined) { - sp_debug("ERROR: failed bind/eval at %lx", a); + sp_debug_agent("ERROR: failed bind/eval at %lx", a); continue; } assert(res.defined); @@ -996,11 +996,11 @@ size_t SpSnippet::reloc_insn_internal(dt::Address a, in::Instruction insn, // Deal with PC-sensitive instruction // first get the target address associated with this instruction dt::Address targetAddr = 0; - sp_debug("READ USE PC: %s", + sp_debug_agent("READ USE PC: %s", g_parser->DumpInsns((void*)insn.ptr(), insn.size()).c_str()); if (!getTargetAddr(a, insn, targetAddr)) - sp_debug("Cannot obtan target address"); - sp_debug("Target address is %lx", targetAddr); + sp_debug_agent("Cannot obtan target address"); + sp_debug_agent("Target address is %lx", targetAddr); // Copied and modified from dynisntAPT/src/codegen-x86.C instruction ins(insn.ptr(), true); const unsigned char* origInsn = ins.ptr(); @@ -1076,7 +1076,7 @@ size_t SpSnippet::reloc_insn_internal(dt::Address a, in::Instruction insn, *((int*)newInsn) = (int)(newDisp - insnSz); newInsn += 4; } else if (is_addr32(targetAddr)) { - sp_debug("Target address is 32 bit"); + sp_debug_agent("Target address is 32 bit"); assert(!is_disp32(newDisp + insnSz)); unsigned char mod_rm = *origInsn++; @@ -1092,7 +1092,7 @@ size_t SpSnippet::reloc_insn_internal(dt::Address a, in::Instruction insn, newInsn += 4; } else { // Should never be reached... - sp_debug("Reaching what should not be reached"); + sp_debug_agent("Reaching what should not be reached"); assert(0); } @@ -1193,11 +1193,11 @@ size_t SpSnippet::reloc_insn(dt::Address src_insn, in::Instruction insn, if (use_pc) { assert(opSet.size() == 1); - sp_debug("USE PC: %s", + sp_debug_agent("USE PC: %s", g_parser->DumpInsns((void*)insn.ptr(), insn.size()).c_str()); - sp_debug("USE_PC - at %lx", src_insn); + sp_debug_agent("USE_PC - at %lx", src_insn); } else { - sp_debug("NOT_USE PC - at %lx", src_insn); + sp_debug_agent("NOT_USE PC - at %lx", src_insn); } // Here we go! @@ -1234,12 +1234,12 @@ size_t SpSnippet::emit_call_orig(char* buf, size_t offset) { opSet.insert(trg); } - sp_debug("EMIT_CALL_ORIG - for call insn at %lx", src); - sp_debug("BEFORE RELOC - %s", + sp_debug_agent("EMIT_CALL_ORIG - for call insn at %lx", src); + sp_debug_agent("BEFORE RELOC - %s", g_parser->DumpInsns((void*)insn.ptr(), insn.size()).c_str()); - if (use_pc) sp_debug("PC-REL CALL"); + if (use_pc) sp_debug_agent("PC-REL CALL"); size_t insn_size = reloc_insn_internal(src, insn, opSet, use_pc, p); - sp_debug("AFTER RELOC %s", g_parser->DumpInsns((void*)p, insn_size).c_str()); + sp_debug_agent("AFTER RELOC %s", g_parser->DumpInsns((void*)p, insn_size).c_str()); return insn_size; } @@ -1375,7 +1375,7 @@ dt::Address SpSnippet::GetFs(void* context) { assert(ctx); // REG_CSGSFS int index = REG_CSGSFS; - sp_debug("REG_CSGSFS=%llx", ctx->uc_mcontext.gregs[index]); + sp_debug_agent("REG_CSGSFS=%llx", ctx->uc_mcontext.gregs[index]); return ((ctx->uc_mcontext.gregs[index] >> 32) & 0xffff); } @@ -1412,7 +1412,7 @@ bool SpSnippet::UsePC(in::Instruction insn) { (*i)->apply(&visitor); read_use_pc = visitor.use_pc(); if (read_use_pc) { - sp_debug("READ USE PC: %s", + sp_debug_agent("READ USE PC: %s", g_parser->DumpInsns((void*)insn.ptr(), insn.size()).c_str()); return true; } @@ -1426,7 +1426,7 @@ bool SpSnippet::UsePC(in::Instruction insn) { (*i)->apply(&visitor); write_use_pc = visitor.use_pc(); if (write_use_pc) { - sp_debug("WRITE USE PC: %s", + sp_debug_agent("WRITE USE PC: %s", g_parser->DumpInsns((void*)insn.ptr(), insn.size()).c_str()); return true; } diff --git a/src/agent/snippet.cc b/src/agent/snippet.cc index f4cc1ce96..81c81e4a0 100644 --- a/src/agent/snippet.cc +++ b/src/agent/snippet.cc @@ -70,7 +70,7 @@ namespace sp { // should have a smarter memory allocator. assert(g_as); assert(pt); - sp_debug("SNIPPET CONSTRUCTOR - payload entry %lx", (long)entry_); + sp_debug_agent("SNIPPET CONSTRUCTOR - payload entry %lx", (long)entry_); InitSavedRegMap(); } @@ -96,7 +96,7 @@ namespace sp { assert(point_); if (!blob_) { - sp_debug("ALLOC BLOB - for size %ld", (long)est_size); + sp_debug_agent("ALLOC BLOB - for size %ld", (long)est_size); blob_ = (char*)GetBlob(est_size); if (!blob_) return NULL; } @@ -105,7 +105,7 @@ namespace sp { // If this blob is already generated? If so, just return it. if (blob_size_ > 0 && blob_) { - sp_debug("BLOB EXIST - avoid regenerating it"); + sp_debug_agent("BLOB EXIST - avoid regenerating it"); return blob_; } @@ -113,15 +113,15 @@ namespace sp { assert(b); - sp_debug("RET_ADDR - is %lx for point %lx ", ret_addr, + sp_debug_agent("RET_ADDR - is %lx for point %lx ", ret_addr, (dt::Address)b->last()); // 1. Relocate call block, if it's indirect call if (reloc) { - sp_debug("RELOC BLOCK"); + sp_debug_agent("RELOC BLOCK"); /* if (b->size() >= BLK_LIMIT) { - sp_debug("NO SUFFICIENT SPACE - for BLOB (%lu >= %lu)", + sp_debug_agent("NO SUFFICIENT SPACE - for BLOB (%lu >= %lu)", b->size(), (unsigned long)BLK_LIMIT); return NULL; } @@ -136,7 +136,7 @@ namespace sp { // 3. Call payload wrapper before function call long param_func = (long)entry_; long called_func = (long)g_context->wrapper_entry(); - sp_debug("PAYLOAD ENTRY - at %lx", called_func); + sp_debug_agent("PAYLOAD ENTRY - at %lx", called_func); assert(g_context); blob_size_ += emit_pass_param((long)point_, param_func, blob_, @@ -152,15 +152,17 @@ namespace sp { // Case 2: non tail call and direct call // Case 3: indirect call (tail call or non tail call) + SpFunction* callee; + if (point_->tailcall() && func_) { - sp_debug("TAIL_CALL_DIRECT_CALL "); + sp_debug_agent("TAIL_CALL_DIRECT_CALL "); assert(!ret_addr); // 5.1. tail call and direct call blob_size_ += emit_jump_abs((long)func_->addr(), blob_, blob_size_); goto EXIT; } else if (!point_->tailcall() && func_) { assert(ret_addr); - sp_debug("SIMPLE_DIRECT_CALL "); + sp_debug_agent("SIMPLE_DIRECT_CALL "); // 5.2. non tail call and Direct call blob_size_ += emit_call_abs((long)func_->addr(), blob_, @@ -168,24 +170,19 @@ namespace sp { false); } else { - sp_debug("For point %lx", point_); + sp_debug_agent("For point %lx", point_); if (!point_->tailcall()) - sp_debug("INDIRECT_CALL "); + sp_debug_agent("INDIRECT_CALL "); else - sp_debug("TAIL_CALL_INDIRECT_CALL"); + sp_debug_agent("TAIL_CALL_INDIRECT_CALL"); // 5.3. indirect call //assert(b->orig_call_insn()); blob_size_ += emit_call_orig(blob_, blob_size_); } - if (g_context->IsIpcEnabled() || - g_context->IsHandleDlopenEnabled() || - exit_) { - - - SpFunction* callee = point_->callee(); + callee = point_->callee(); if (callee) { char* ret_blob_address = blob_; @@ -194,21 +191,21 @@ namespace sp { g_context->ra_csp_map_[ret_addr] = point_; } - // 6. save context - blob_size_ += emit_save(blob_, blob_size_); + // 6. save context + blob_size_ += emit_save(blob_, blob_size_); + + // 7. Pass parameters + param_func = (long)exit_; + called_func = (long)g_context->wrapper_exit(); + blob_size_ += emit_pass_param((long)point_, + param_func, + blob_, + blob_size_); + blob_size_ += emit_call_abs(called_func, blob_, blob_size_, true); - // 7. Pass parameters - param_func = (long)exit_; - called_func = (long)g_context->wrapper_exit(); - blob_size_ += emit_pass_param((long)point_, - param_func, - blob_, - blob_size_); - blob_size_ += emit_call_abs(called_func, blob_, blob_size_, true); + // 8. Restore context + blob_size_ += emit_restore(blob_, blob_size_); - // 8. Restore context - blob_size_ += emit_restore(blob_, blob_size_); - } // 9. Jump back to ORIG_INSN_ADDR blob_size_ += emit_jump_abs(ret_addr, blob_, blob_size_); @@ -216,17 +213,17 @@ namespace sp { EXIT: if (func_) { - sp_debug("DUMP PATCH AREA %lx (%lu bytes) for point %lx for %s - {", + sp_debug_agent("DUMP PATCH AREA %lx (%lu bytes) for point %lx for %s - {", (unsigned long)blob_, (unsigned long)blob_size_, b->last(), func_->name().c_str()); } else { - sp_debug("DUMP PATCH AREA %lx (%lu bytes) for point %lx - {", + sp_debug_agent("DUMP PATCH AREA %lx (%lu bytes) for point %lx - {", (unsigned long)blob_, (unsigned long)blob_size_, b->last()); } - sp_debug("%s", g_parser->DumpInsns((void*)blob_, + sp_debug_agent("%s", g_parser->DumpInsns((void*)blob_, blob_size_).c_str()); - sp_debug("}"); + sp_debug_agent("}"); return blob_; } @@ -274,7 +271,7 @@ namespace sp { long after_jmp = callblk->start() + 2; bool done = false; - sp_debug("LOOKING FOR SPRING BOARD - springboard size should >= %ld", + sp_debug_agent("LOOKING FOR SPRING BOARD - springboard size should >= %ld", (long)min_springblk_size); // Find a nearby block @@ -293,14 +290,14 @@ namespace sp { upper -= obj->load_addr(); lower -= obj->load_addr(); } - sp_debug("SAME OBJ - codebase-%lx, load_addr-%lx, range-[%lx, %lx) ", + sp_debug_agent("SAME OBJ - codebase-%lx, load_addr-%lx, range-[%lx, %lx) ", obj->codeBase(), obj->load_addr(), lower, upper); for (unsigned i = 0; i < regions.size(); i++) { pe::CodeRegion* cr = regions[i]; size_t cr_low = cr->low(); size_t cr_high = cr->high(); - sp_debug("REGION [%lx, %lx] - (%lx, %lx)", (unsigned long)cr_low, + sp_debug_agent("REGION [%lx, %lx] - (%lx, %lx)", (unsigned long)cr_low, (unsigned long)cr_high, lower, upper); if ((lower <= (long)cr_low && (long)cr_low < upper) || ((long)cr_low <= lower && upper < (long)cr_high) || @@ -320,7 +317,7 @@ namespace sp { bi != blks.end(); bi++) { b = *bi; } - sp_debug("POTENTIAL SPRING BOARD - %ld found, [%lx, %lx]", + sp_debug_agent("POTENTIAL SPRING BOARD - %ld found, [%lx, %lx]", (unsigned long)blks.size(), b->start(), b->size() + b->start()); @@ -330,13 +327,13 @@ namespace sp { } if (!sp::IsDisp8(rel)) { - sp_debug("TOO BIG DISP, SKIPPED - disp=%ld", (long)rel); + sp_debug_agent("TOO BIG DISP, SKIPPED - disp=%ld", (long)rel); span_addr = b->end(); continue; } size_t s = b->lastInsnAddr() - b->start(); if (s < min_springblk_size) { - sp_debug("TOO SMALL, SKIPPED - size=%ld", (long)s); + sp_debug_agent("TOO SMALL, SKIPPED - size=%ld", (long)s); span_addr = b->end(); continue; } @@ -345,19 +342,19 @@ namespace sp { // For simplicity, we don't want call block if (pb->containsCall()) { - sp_debug("CALL BLK, SKIPPED - we don't relocate call block"); + sp_debug_agent("CALL BLK, SKIPPED - we don't relocate call block"); span_addr = b->end(); continue; } // For simplicity, we don't relocate used spring block if (pb->IsSpring()) { - sp_debug("SPRING BOARD, SKIPPED - we don't relocate second-hand" + sp_debug_agent("SPRING BOARD, SKIPPED - we don't relocate second-hand" " spring board"); span_addr = b->end(); continue; } - sp_debug("GOT SPRING BOARD"); + sp_debug_agent("GOT SPRING BOARD"); spring_blk_ = pb; pb->SetIsSpring(true); done = true; @@ -390,10 +387,10 @@ namespace sp { spring_size_ += emit_jump_abs(ret_addr, spring_, spring_size_); assert(point_->block()); - sp_debug("DUMP RELOC SPRING INSNS (%lu bytes) for point %lx- {", + sp_debug_agent("DUMP RELOC SPRING INSNS (%lu bytes) for point %lx- {", (unsigned long)spring_size_, point_->block()->last()); - sp_debug("%s", g_parser->DumpInsns((void*)spring_, spring_size_).c_str()); - sp_debug("}"); + sp_debug_agent("%s", g_parser->DumpInsns((void*)spring_, spring_size_).c_str()); + sp_debug_agent("}"); return spring_; } @@ -411,7 +408,7 @@ namespace sp { // We may want to reallocate it, so free existing buffer first if (blob_) { - sp_debug("REALLOC - for %lx", point_->block()->last()); + sp_debug_agent("REALLOC - for %lx", point_->block()->last()); // g_as->free(obj, (dt::Address)blob_); } @@ -432,9 +429,9 @@ namespace sp { int offset = saved_reg_map_[reg]; *out = RegVal(offset); - sp_debug("Looing for register [%s] with offset [%d]", reg.name().c_str(), offset); + sp_debug_agent("Looing for register [%s] with offset [%d]", reg.name().c_str(), offset); - sp_debug("ORIG VAL - %s = %lx, size: %ld", + sp_debug_agent("ORIG VAL - %s = %lx, size: %ld", reg.name().c_str(), *out, (long)reg.size()); switch(reg.size()) { case 8: @@ -457,7 +454,7 @@ namespace sp { return false; } - sp_debug("NEW VAL - %s = %lx", + sp_debug_agent("NEW VAL - %s = %lx", reg.name().c_str(), *out); return true; diff --git a/src/agent/thread_mgr.cc b/src/agent/thread_mgr.cc index 3581a0ca5..f91e7de3c 100644 --- a/src/agent/thread_mgr.cc +++ b/src/agent/thread_mgr.cc @@ -52,10 +52,10 @@ SpThreadMgr::BeforeEntry(SpPoint* pt) { bool ret = true; SP_LOCK(THREADMGR_BEFOREENTRY); - sp_debug("THREAD MGR BeforeEntry"); + sp_debug_agent("THREAD MGR BeforeEntry"); func = pt->callee(); if (!func) { - sp_debug("CANNOT FIND CALLEE FOR %lx", pt->block()->last()); + sp_debug_agent("CANNOT FIND CALLEE FOR %lx", pt->block()->last()); ret = false; goto THREADMGR_BEFOREENTRY_EXIT; } @@ -73,17 +73,17 @@ SpThreadMgr::BeforeEntry(SpPoint* pt) { SpFunction* tfunc = g_parser->FindFunction((dt::Address)*thread_func); if (!tfunc) { - sp_debug("CANNOT FIND FUNCTION FOR %lx", (dt::Address)*thread_func); + sp_debug_agent("CANNOT FIND FUNCTION FOR %lx", (dt::Address)*thread_func); ret = false; goto THREADMGR_BEFOREENTRY_EXIT; } - sp_debug("GOT CALLBACK - %s at %lx", tfunc->name().c_str(), + sp_debug_agent("GOT CALLBACK - %s at %lx", tfunc->name().c_str(), (long)*thread_func); // Start propagating instrumentation to thread routine sp::SpPropeller::ptr p = g_context->init_propeller(); assert(p); - sp_debug("GET PROPELLER"); + sp_debug_agent("GET PROPELLER"); p->go(tfunc, g_context->init_entry(), g_context->init_exit(), diff --git a/src/common/common.h b/src/common/common.h index 237b814ec..7c057ecd6 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -33,6 +33,7 @@ #define SP_COMMON_H_ #include +#include // Some macros for code readability #define OVERRIDE @@ -50,6 +51,13 @@ extern FILE* g_output_fp; extern FILE* g_debug_fp; extern FILE* g_error_fp; +extern bool sp_debug; +extern bool sp_fdebug; +const int numDebugTypes = 8; +enum DebugType {injectorDebug, commonDebug, patchapiDebug, ipcDebug, workerDebug, sigtrapDebug, agentDebug, unknownDebugType}; +extern bool debugTypeEnabled [numDebugTypes]; +// = {getenv("SP_DEBUG_INJECTOR"), getenv("SP_DEBUG_COMMON"), getenv("SP_DEBUG_PATCHAPI"), getenv("SP_DEBUG_IPC"), getenv("SP_DEBUG_WORKER"), getenv("SP_DEBUG_SIGTRAP"), getenv("SP_DEBUG_AGENT"), true}; + // Print facility #define sp_perror(...) do {\ if (getenv("SP_DEBUG")) { \ @@ -84,23 +92,35 @@ extern FILE* g_error_fp; } \ } while(0) -#define sp_debug(...) do { \ - if (getenv("SP_DEBUG")) { \ - char* nodir = basename((char*)__FILE__); \ - fprintf(stderr, "%s [%d]: ", nodir, __LINE__); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - fflush(stderr); \ - } \ - else if (getenv("SP_FDEBUG")) { \ - char* nodir = basename((char*)__FILE__); \ - fprintf(g_debug_fp, "%s [%d]: ", nodir, __LINE__); \ - fprintf(g_debug_fp, __VA_ARGS__); \ - fprintf(g_debug_fp, "\n"); \ - fflush(g_debug_fp); \ - }\ +#define sp_debug(debug_type, ...) do { \ + DebugType debugType = debug_type; \ + if (debugType >= numDebugTypes) { \ + debugType = unknownDebugType; \ + } \ + if (debugTypeEnabled[debugType]) { \ + FILE* debug_fp; \ + if (sp_fdebug) \ + debug_fp = g_debug_fp; \ + else \ + debug_fp = stderr; \ + if (sp_debug || sp_fdebug) { \ + char* nodir = basename((char*)__FILE__); \ + fprintf(debug_fp, "%s [%d]: ", nodir, __LINE__); \ + fprintf(debug_fp, __VA_ARGS__); \ + fprintf(debug_fp, "\n"); \ + fflush(debug_fp); \ + } \ + } \ } while(0) +#define sp_debug_injector(...) sp_debug(injectorDebug, __VA_ARGS__) +#define sp_debug_common(...) sp_debug(commonDebug, __VA_ARGS__) +#define sp_debug_patchapi(...) sp_debug(patchapiDebug, __VA_ARGS__) +#define sp_debug_ipc(...) sp_debug(ipcDebug, __VA_ARGS__) +#define sp_debug_worker(...) sp_debug(workerDebug, __VA_ARGS__) +#define sp_debug_sigtrap(...) sp_debug(sigtrapDebug, __VA_ARGS__) +#define sp_debug_agent(...) sp_debug(agentDebug, __VA_ARGS__) + // Gets file name from a full path name #define sp_filename(path) basename((char*)path) diff --git a/src/common/utils.cc b/src/common/utils.cc index 3496373ad..e255e7dda 100644 --- a/src/common/utils.cc +++ b/src/common/utils.cc @@ -41,7 +41,8 @@ #include #include #include - +#include +#include #include #include @@ -70,7 +71,7 @@ CPerfCounter a[kNumTimers]; void SetupTimer(const int i) { if (i < 0 || i > (kNumTimers - 1)) { - sp_debug("OUT OF BOUND TIMER - timer id should be in [0, 9]"); + sp_debug_common("OUT OF BOUND TIMER - timer id should be in [0, 9]"); return; } a[i]._clocks = 0; @@ -84,7 +85,7 @@ SetupTimer(const int i) { void StartTimer(const int i) { if (i < 0 || i > (kNumTimers - 1)) { - sp_debug("OUT OF BOUND TIMER - timer id should be in [0, 9]"); + sp_debug_common("OUT OF BOUND TIMER - timer id should be in [0, 9]"); return; } struct timeval s; @@ -97,7 +98,7 @@ StartTimer(const int i) { void StopTimer(const int i) { if (i < 0 || i > (kNumTimers - 1)) { - sp_debug("OUT OF BOUND TIMER - timer id should be in [0, 9]"); + sp_debug_common("OUT OF BOUND TIMER - timer id should be in [0, 9]"); return; } @@ -115,7 +116,7 @@ StopTimer(const int i) { void ResetTimer(const int i) { if (i < 0 || i > (kNumTimers - 1)) { - sp_debug("OUT OF BOUND TIMER - timer id should be in [0, 9]"); + sp_debug_common("OUT OF BOUND TIMER - timer id should be in [0, 9]"); return; } @@ -127,7 +128,7 @@ ResetTimer(const int i) { double GetTimer(const int i) { if (i < 0 || i > (kNumTimers - 1)) { - sp_debug("OUT OF BOUND TIMER - timer id should be in [0, 9]"); + sp_debug_common("OUT OF BOUND TIMER - timer id should be in [0, 9]"); return 0.0; } @@ -140,7 +141,7 @@ void PrintTime(const char *msg, const int i) { if (i < 0 || i > (kNumTimers - 1)) { - sp_debug("OUT OF BOUND TIMER - timer id should be in [0, 9]"); + sp_debug_common("OUT OF BOUND TIMER - timer id should be in [0, 9]"); return; } @@ -269,7 +270,7 @@ GetPidsFromFileDesc(const int fd, } if (pid != getpid() && PidUsesInode(pid, GetInodeFromFileDesc(fd))) { - sp_debug("GET PID FOR PIPE: pid - %d", pid); + sp_debug_common("GET PID FOR PIPE: pid - %d", pid); pid_set.insert(pid); } } @@ -296,14 +297,14 @@ void GetSocketDescFromPid(int pid, SocketSet& socket_set) snprintf(name, kLenStringBuffer, "/proc/%u/fd/%s", pid, de->d_name); int size = -1; if ((size = readlink(name, buffer, kLenStringBuffer)) < 0) { - sp_debug("GetSocketDescFromPid: readlink error"); + sp_debug_common("GetSocketDescFromPid: readlink error"); } else { buffer[size] = '\0'; if (sscanf(buffer, "socket:[%lu]", &temp_node) == 1){ // Tcp socket_set.insert(dir); - sp_debug("%d uses Socket %d",pid,dir); + sp_debug_common("%d uses Socket %d",pid,dir); } } } @@ -513,7 +514,7 @@ GetLocalAddress(const int fd, assert(out); socklen_t sock_len = sizeof(sockaddr_storage); if (getsockname(fd, reinterpret_cast(out), &sock_len) == -1) { - sp_debug("FAILED GET LOCAL ADDR - getsockname @ pid = %d", getpid()); + sp_debug_common("FAILED GET LOCAL ADDR - getsockname @ pid = %d", getpid()); return false; } return true; @@ -527,7 +528,7 @@ GetRemoteAddress(const int fd, assert(out); socklen_t sock_len = sizeof(sockaddr_storage); if (getpeername(fd, reinterpret_cast(out), &sock_len) == -1) { - sp_debug("FAILED GET REMOTE ADDR - getpeername @ pid = %d", getpid()); + sp_debug_common("FAILED GET REMOTE ADDR - getpeername @ pid = %d", getpid()); return false; } return true; @@ -640,12 +641,12 @@ IsIllegalProgram() { std::string content = GetFileText(proc_path.c_str()); char* exe_name = sp_filename(content.c_str()); - sp_debug("exe: %s", exe_name); */ + sp_debug_common("exe: %s", exe_name); */ std::string exe_name = GetExeName(); for (StringSet::iterator si = illegal_exes.begin(); si != illegal_exes.end(); si++) { - // sp_debug("comparing: %s", (*si).c_str()); + // sp_debug_common("comparing: %s", (*si).c_str()); if ((*si).compare(exe_name.c_str()) == 0) return true; } return false; @@ -665,7 +666,7 @@ GetExeName() { } exe[size] ='\0'; - sp_debug("Exename is %s",exe); + sp_debug_common("Exename is %s",exe); std::string content(exe); return content; @@ -673,6 +674,15 @@ GetExeName() { ////////////////////////////////////////////////////////////////////// +// Gets current process's executable name without full path +std::string +GetExeObjName() { + std::string path = GetExeName(); + return path.substr(path.find_last_of("/") + 1); +} + +////////////////////////////////////////////////////////////////////// + // Gets text content from a file. If file doesn't exist, return "". std::string GetFileText(const char* filename) { @@ -704,7 +714,7 @@ ProcessHasLibrary(int pid, std::string lib) { if(line.find(lib) != std::string::npos) { - sp_debug("Agent shared library is already injected into the process"); + sp_debug_common("Agent shared library is already injected into the process"); return true; } } @@ -719,13 +729,13 @@ void sig_urg_handler(int signo) int n; char buff[100]; int connfd; - sp_debug("SIGURG received!!"); + sp_debug_common("SIGURG received!!"); SocketSet socket_set; GetSocketDescFromPid(getpid(),socket_set); if(socket_set.size() > 0) { for(SocketSet::iterator s=socket_set.begin(); s!=socket_set.end(); s++) { connfd=*s; - sp_debug("Socket: %d, trying to receive OOB", connfd); + sp_debug_common("Socket: %d, trying to receive OOB", connfd); if ((n = recv(connfd, buff, sizeof(buff)-1, MSG_OOB)) > 0) { buff[n] ='\0'; sp_print("read OOB data %s",buff); @@ -777,7 +787,7 @@ GetThreadId() { int InitLock(SpLock* const lock) { assert(lock); - sp_debug("INIT LOCK - mutex %d", lock->mutex); + sp_debug_common("INIT LOCK - mutex %d", lock->mutex); lock->mutex = 0; return 0; } @@ -801,7 +811,7 @@ int Lock(SpLock* const lock) { int Unlock(SpLock* const lock) { assert(lock); - // sp_debug("UNLOCK - mutex %d", lock->mutex); + // sp_debug_common("UNLOCK - mutex %d", lock->mutex); __sync_synchronize(); lock->mutex = 0; return 0; @@ -836,9 +846,9 @@ int shmid; } int ret = shmctl(shmid, IPC_RMID, NULL); if (ret < 0) { - sp_debug("free shared memory failed"); + sp_debug_common("free shared memory failed"); } else { - sp_debug("free shared memory successful"); + sp_debug_common("free shared memory successful"); } return; } diff --git a/src/common/utils.h b/src/common/utils.h index 787da38ff..73ab33344 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -102,7 +102,10 @@ namespace sp { // Gets full path of the executable file COMMON_EXPORT std::string GetExeName(); - + + // Gets executable object name + COMMON_EXPORT std::string GetExeObjName(); + //check if a library is already present in the process COMMON_EXPORT bool ProcessHasLibrary(int pid, std::string lib); diff --git a/src/injector/injector-x86_64.cc b/src/injector/injector-x86_64.cc index 0a3bde332..479d31f36 100644 --- a/src/injector/injector-x86_64.cc +++ b/src/injector/injector-x86_64.cc @@ -32,7 +32,7 @@ #include "injector/injector.h" namespace sp { - +/* // The code snippet to invoke do_dlopen static unsigned char kDlopenCode[] = { //0 , 1 @@ -80,7 +80,8 @@ static unsigned char kIjagentCode[] = { 0xff, 0xd0, // call %rax 0xCC }; - +*/ +/* enum { OFF_ARGS = 4, OFF_DODLOPEN = 14, @@ -98,7 +99,8 @@ SpInjector::GetCodeTemplateSize() { unsigned char* SpInjector::GetCodeTemplate(Dyninst::Address args_addr, Dyninst::Address do_dlopen, - Dyninst::Address /*code_addr*/) { + Dyninst::Address //code_addr + ) { long* p = (long*)&kDlopenCode[OFF_DODLOPEN]; *p = (long)do_dlopen; p = (long*)&kDlopenCode[OFF_ARGS]; @@ -115,7 +117,8 @@ unsigned char* SpInjector::GetDlmodeTemplate(Dyninst::Address libname, Dyninst::Address mode, Dyninst::Address dlopen, - Dyninst::Address /*code_addr*/) { + Dyninst::Address //code_addr + ) { long* p = (long*)&kLibcDlopenModeCode[OFF_DODLOPEN+10]; *p = (long)dlopen; p = (long*)&kLibcDlopenModeCode[OFF_ARGS]; @@ -130,12 +133,13 @@ size_t SpInjector::GetIjTemplateSize() { } unsigned char* SpInjector::GetIjTemplate(Dyninst::Address ij_addr, - Dyninst::Address /*code_addr*/) { + Dyninst::Address //code_addr + ) { long* p = (long*)&kIjagentCode[OFF_IJ]; *p = (long)ij_addr; return kIjagentCode; } - +*/ Dyninst::Address SpInjector::pc() { Dyninst::MachRegisterVal rip; thr_->getRegister(Dyninst::x86_64::rip, rip); diff --git a/src/injector/injector.cc b/src/injector/injector.cc index 635f5bf29..9f9d6f088 100644 --- a/src/injector/injector.cc +++ b/src/injector/injector.cc @@ -62,18 +62,18 @@ SpInjector::ptr SpInjector::Create(dt::PID pid) { SpInjector::SpInjector(dt::PID pid) : pid_(pid) { proc_ = Process::attachProcess(pid); if (proc_ == Process::ptr()) { - sp_debug("Injector [pid = %5d] - Failed to attach to process %d.", getpid(), + sp_debug_injector("Injector [pid = %5d] - Failed to attach to process %d.", getpid(), pid); exit(0); } else - sp_debug("Attached the process %d successfully", pid); + sp_debug_injector("Attached the process %d successfully", pid); ThreadPool &thrs = proc_->threads(); thr_ = thrs.getInitialThread(); } ////////////////////////////////////////////////////////////////////// SpInjector::~SpInjector() { - sp_debug("Detaching the process"); + sp_debug_injector("Detaching the process"); proc_->detach(); } @@ -86,7 +86,7 @@ Address SpInjector::FindFunction(const char *func) { std::string name = (*li)->getName(); if (name.size() <= 0) continue; - sp_debug("IN LIB - %s", name.c_str()); + sp_debug_injector("IN LIB - %s", name.c_str()); sb::Symtab *obj = NULL; bool ret = sb::Symtab::openFile(obj, name); std::vector funcs; @@ -108,10 +108,10 @@ Address SpInjector::FindDlopen() { if (func_addr) return func_addr; - sp_debug("Injector [pid = %5d]: Cannot find do_dlopen", getpid()); + sp_debug_injector("Injector [pid = %5d]: Cannot find do_dlopen", getpid()); func_addr = FindFunction("__libc_dlopen_mode"); - sp_debug("Injector [pid = %5d]: Got _dl_open at %lx", getpid(), func_addr); + sp_debug_injector("Injector [pid = %5d]: Got _dl_open at %lx", getpid(), func_addr); return func_addr; } @@ -128,7 +128,7 @@ Process::cb_ret_t on_event_lib(Event::const_ptr ev) { for (std::set::iterator i = libs.begin(); i != libs.end(); i++) { Address loaded_addr = (*i)->getLoadAddress(); - sp_debug("LOADED - Library %s at %lx", sp_filename((*i)->getName().c_str()), + sp_debug_injector("LOADED - Library %s at %lx", sp_filename((*i)->getName().c_str()), loaded_addr); } return Process::cbThreadContinue; @@ -148,7 +148,7 @@ Process::cb_ret_t on_event_signal(Event::const_ptr ev) { // Check whether a library is loaded bool SpInjector::IsLibraryLoaded(const char *libname) { char *name_only = sp_filename(libname); - sp_debug("CHECKING - checking whether %s is loaded ...", name_only); + sp_debug_injector("CHECKING - checking whether %s is loaded ...", name_only); std::string proc_maps = ""; proc_maps += "/proc/"; @@ -156,10 +156,10 @@ bool SpInjector::IsLibraryLoaded(const char *libname) { proc_maps += "/maps"; const char *content = sp::GetFileText(proc_maps.c_str()).c_str(); if (strstr(content, name_only)) { - sp_debug("LOADED - %s is already loaded", name_only); + sp_debug_injector("LOADED - %s is already loaded", name_only); return true; } - sp_debug("NO LOADED - %s is not yet loaded", name_only); + sp_debug_injector("NO LOADED - %s is not yet loaded", name_only); return false; } @@ -290,11 +290,11 @@ bool SpInjector::Inject(const char *lib_name) { // proc_->detach(); return true; }*/ - +/* ////////////////////////////////////////////////////////////////////// // Invoke ijagent function in libijagent.so, which in turn invokes dlopen void SpInjector::LoadUserLibrary() { - sp_debug("PAUSED - Process %d is paused by injector.", pid_); + sp_debug_injector("PAUSED - Process %d is paused by injector.", pid_); if (!proc_->stopProc()) { sp_perror("Injector [pid = %5d] - Failed to stop process %d", getpid(), pid_); @@ -302,19 +302,19 @@ void SpInjector::LoadUserLibrary() { UpdateFrameInfo(); Address ij_agent_addr = FindFunction("ij_agent"); if (ij_agent_addr > 0) { - sp_debug("FOUND - Address of ij_agent function at %lx", ij_agent_addr); + sp_debug_injector("FOUND - Address of ij_agent function at %lx", ij_agent_addr); } else { sp_perror("Injector [pid = %5d] - Failed to find ij_agent", getpid()); } size_t size = GetIjTemplateSize(); Address code_addr = proc_->mallocMemory(size); unsigned char *code = GetIjTemplate(ij_agent_addr, code_addr); - sp_debug("ALLOCATED - Buffer for load-library code in mutatee's heap" + sp_debug_injector("ALLOCATED - Buffer for load-library code in mutatee's heap" " at %lx of %lu bytes", code_addr, (unsigned long)size); IRPC::ptr irpc = IRPC::createIRPC(code, size, code_addr); irpc->setStartOffset(2); - sp_debug("POSTING - IRPC is on the way ..."); + sp_debug_injector("POSTING - IRPC is on the way ..."); if (!proc_->postIRPC(irpc)) { sp_perror("Injector [pid = %5d] - Failed to execute load-library code" " in mutatee's address space", @@ -334,7 +334,7 @@ void SpInjector::LoadIjagent(const char *lib_name) { sp_perror("Injector [pid = %5d] - %s cannot be found", getpid(), sp_filename(lib_name)); } - sp_debug("PAUSED - Process %d is paused by injector.", pid_); + sp_debug_injector("PAUSED - Process %d is paused by injector.", pid_); if (!proc_->stopProc()) { sp_perror("Injector [pid = %5d] - Failed to stop process %d", getpid(), pid_); @@ -352,12 +352,12 @@ void SpInjector::LoadIjagent(const char *lib_name) { // Find do_dlopen function Address do_dlopen_addr = FindFunction("do_dlopen"); if (do_dlopen_addr > 0) { - sp_debug("FOUND - Address of do_dlopen function at %lx", do_dlopen_addr); + sp_debug_injector("FOUND - Address of do_dlopen function at %lx", do_dlopen_addr); size_t lib_name_len = strlen(libname) + 1; lib_name_addr = proc_->mallocMemory(lib_name_len); proc_->writeMemory(lib_name_addr, (void *)libname, lib_name_len); - sp_debug("STORED - Library name \"%s\" in mutatee's heap at %lx", + sp_debug_injector("STORED - Library name \"%s\" in mutatee's heap at %lx", sp_filename(libname), lib_name_addr); DlopenArg args; @@ -366,32 +366,32 @@ void SpInjector::LoadIjagent(const char *lib_name) { args.mode = RTLD_NOW | RTLD_GLOBAL; args.link_map = 0; proc_->writeMemory(args_addr, &args, sizeof(args)); - sp_debug("STORED - do_dlopen's argument in mutatee's heap at %lx", + sp_debug_injector("STORED - do_dlopen's argument in mutatee's heap at %lx", args_addr); size = GetCodeTemplateSize(); code_addr = proc_->mallocMemory(size); code = GetCodeTemplate(args_addr, do_dlopen_addr, code_addr); - sp_debug("ALLOCATED - Buffer for load-library code in mutatee's heap" + sp_debug_injector("ALLOCATED - Buffer for load-library code in mutatee's heap" " at %lx of %lu bytes", code_addr, (unsigned long)size); } // Cannot do_dlopen, then we try __libc_dl_open_mode else { - sp_debug("Injector [pid = %5d] - Failed to find do_dlopen, " + sp_debug_injector("Injector [pid = %5d] - Failed to find do_dlopen, " "try __libc_dlopen_mode", getpid()); Address libc_dlopen_addr = FindFunction("__libc_dlopen_mode"); if (libc_dlopen_addr > 0) { - sp_debug("FOUND - Address of __libc_dlopen_mode function at %lx", + sp_debug_injector("FOUND - Address of __libc_dlopen_mode function at %lx", libc_dlopen_addr); // Argument 1 size_t lib_name_len = strlen(libname) + 1; lib_name_addr = proc_->mallocMemory(lib_name_len); proc_->writeMemory(lib_name_addr, (void *)libname, lib_name_len); - sp_debug("STORED - 1st argument libname \"%s\" in mutatee's heap at %lx", + sp_debug_injector("STORED - 1st argument libname \"%s\" in mutatee's heap at %lx", sp_filename(libname), lib_name_addr); // Argument 2 @@ -401,7 +401,7 @@ void SpInjector::LoadIjagent(const char *lib_name) { code_addr = proc_->mallocMemory(size); code = GetDlmodeTemplate(lib_name_addr, mode, libc_dlopen_addr, code_addr); - sp_debug("ALLOCATED - Buffer for load-library code in mutatee's heap" + sp_debug_injector("ALLOCATED - Buffer for load-library code in mutatee's heap" " at %lx of %lu bytes", code_addr, (unsigned long)size); } else { @@ -431,11 +431,11 @@ void SpInjector::LoadIjagent(const char *lib_name) { proc_->freeMemory(code_addr); free(libname); } - /* - char dump_maps[1024]; - snprintf(dump_maps, 1024, "cat /proc/%d/maps", pid_); - system(dump_maps); -*/ + + //char dump_maps[1024]; + //snprintf(dump_maps, 1024, "cat /proc/%d/maps", pid_); + //system(dump_maps); + } ////////////////////////////////////////////////////////////////////// @@ -555,15 +555,15 @@ bool SpInjector::GetResolvedLibPath(const std::string &filename, return (0 < paths.size()); } - +*/ ////////////////////////////////////////////////////////////////////// void SpInjector::UpdateFrameInfo() { - sp_debug("Shared memory key: %ui", IJMSG_ID+proc_->getPid()); + sp_debug_injector("Shared memory key: %ui", IJMSG_ID+proc_->getPid()); IjMsg *shm = (IjMsg *)GetSharedMemory(IJMSG_ID+proc_->getPid(), sizeof(IjMsg)); shm->pc = pc(); shm->sp = sp(); shm->bp = bp(); - sp_debug("Updated frame info pc [%ld] sp [%ld] bp [%ld]", shm->pc, shm->sp, + sp_debug_injector("Updated frame info pc [%ld] sp [%ld] bp [%ld]", shm->pc, shm->sp, shm->bp); } diff --git a/src/injector/injector_main.cc b/src/injector/injector_main.cc index 392afeefc..47787f990 100644 --- a/src/injector/injector_main.cc +++ b/src/injector/injector_main.cc @@ -10,6 +10,9 @@ using namespace sp; FILE* g_debug_fp = stderr; FILE* g_error_fp = stderr; FILE* g_output_fp = stdout; +bool debugTypeEnabled [numDebugTypes] = {getenv("SP_DEBUG_INJECTOR"), getenv("SP_DEBUG_COMMON"), getenv("SP_DEBUG_PATCHAPI"), getenv("SP_DEBUG_IPC"), getenv("SP_DEBUG_WORKER"), getenv("SP_DEBUG_SIGTRAP"), getenv("SP_DEBUG_AGENT"), true}; +bool sp_debug = getenv("SP_DEBUG"); +bool sp_fdebug = getenv("SP_FDEBUG"); // Here we go! int main(int argc, char *argv[]) { @@ -31,7 +34,7 @@ int main(int argc, char *argv[]) { const char* lib_name = argv[3]; sp_print("Injector [pid = %5d]: INJECTING - %s to pid=%d...", getpid(), lib_name, pid); - sp_debug("========== Injector =========="); + sp_debug_injector("========== Injector =========="); SpInjector::ptr injector = SpInjector::Create(pid); injector->Inject(lib_name); } diff --git a/src/injector/injector_unittest.cc b/src/injector/injector_unittest.cc index 84a07bb8c..32f46fe07 100644 --- a/src/injector/injector_unittest.cc +++ b/src/injector/injector_unittest.cc @@ -87,7 +87,7 @@ TEST_F(InjectorTest, pid_inject) { cmd += getenv("PLATFORM"); cmd += "/test_agent/inject_test_agent.so"; //cmd += " 2>&1"; - sp_debug(cmd.c_str()); + sp_debug_injector(cmd.c_str()); // system(cmd.c_str()); @@ -98,9 +98,9 @@ TEST_F(InjectorTest, pid_inject) { // Skip the first line ASSERT_TRUE(fgets(buf, 1024, fp) != NULL); - sp_debug("first line: %s", buf); + sp_debug_injector("first line: %s", buf); ASSERT_TRUE(fgets(buf, 1024, fp) != NULL); - sp_debug("second line: %s", buf); + sp_debug_injector("second line: %s", buf); // Check "INJECTED" for the second line ASSERT_TRUE(strstr(buf, "INJECTION SUCCESS") != NULL); diff --git a/test.target.mk b/test.target.mk index 1b2cd0f48..8371ed79e 100644 --- a/test.target.mk +++ b/test.target.mk @@ -68,7 +68,8 @@ google-mock: $(GMOCK_MAIN) #========================================================== # SPI UNIT TESTS #========================================================== -UT_FLAGS = $(AG_IFLAGS) $(CPPFLAGS) -no-pie -fno-PIE +UT_FLAGS = $(AG_IFLAGS) $(CPPFLAGS) -no-pie -fno-PIE -fPIC -D_GLIBCXX_USE_CXX11_ABI=1 + UT_LDFLAGS = -lpthread -ldl ifeq ($(DYNLINK), true) @@ -250,5 +251,22 @@ $(TG_SO): $(TAGENT_EXES_DIR)/%.so : $(TAGENT_OBJS_DIR)/%.o $(AGENT) @echo "Linking $*.so" @$(GCC) -o $@ $< $(TG_LDFLAGS) +FPVA_DIR = $(SP_DIR)/user_agent/fpva + +fpva: + @echo "Compiling fpva" + @$(MKDIR) $(TAGENT_OBJS_DIR) + @$(GCC) -I/usr/include/libxml2 -o $(TAGENT_OBJS_DIR)/MyAgent.o $(FPVA_DIR)/MyAgent.C $(TG_FLAGS) -c + @$(GCC) -I/usr/include/libxml2 -o $(TAGENT_OBJS_DIR)/fpva.o $(FPVA_DIR)/fpva.C $(TG_FLAGS) -c + @$(GCC) -I/usr/include/libxml2 -o $(TAGENT_OBJS_DIR)/fpva_checker.o $(FPVA_DIR)/fpva_checker.C $(TG_FLAGS) -c + @$(GCC) -I/usr/include/libxml2 -o $(TAGENT_OBJS_DIR)/fpva_utils.o $(FPVA_DIR)/fpva_utils.C $(TG_FLAGS) -c +# @$(GCC) -I/usr/include/libxml2 -o $(TAGENT_OBJS_DIR)/tcp_client.o $(FPVA_DIR)/tcp_client.c $(TG_FLAGS) -c +# @$(GCC) -I/usr/include/libxml2 -o $(TAGENT_OBJS_DIR)/tcp_server4.o $(FPVA_DIR)/tcp_server4.c $(TG_FLAGS) -c + @$(GCC) -I/usr/include/libxml2 -o $(TAGENT_OBJS_DIR)/trace_mgr.o $(FPVA_DIR)/trace_mgr.C $(TG_FLAGS) -c + @echo "Linking fpva" + @echo $(TAGENT_OBJS_DIR) + @$(GCC) -o $(TAGENT_EXES_DIR)/MyAgent.so $(TAGENT_OBJS_DIR)/MyAgent.o $(TAGENT_OBJS_DIR)/fpva.o $(TAGENT_OBJS_DIR)/fpva_checker.o $(TAGENT_OBJS_DIR)/fpva_utils.o $(TAGENT_OBJS_DIR)/trace_mgr.o $(AGENT) $(TG_LDFLAGS) -I/usr/include/libxml2 -L/usr/lib/x86_64-linux-gnu -lxml2 /usr/lib/x86_64-linux-gnu/libxml2.so +# @$(GCC) -o $(TAGENT_EXES_DIR)/MyAgent.so $(TG_LDFLAGS) $(TAGENT_OBJS_DIR)/trace_mgr.o + debug: echo $(UT_LDFLAGS) diff --git a/user_agent/fpva/MyAgent.C b/user_agent/fpva/MyAgent.C index 5cdb9775a..25f2bb505 100644 --- a/user_agent/fpva/MyAgent.C +++ b/user_agent/fpva/MyAgent.C @@ -32,7 +32,8 @@ void MyAgent() { "librt.so", "libcrypto.so", "libstdc++.so", "libm.so", "libgomp.so", "libpthread.so", "libc.so", "ld-linux-x86-64.so", "libparseAPI.so", - "libpcontrol.so", "libstackwalk.so", "libpatchAPI.so"}; + "libpcontrol.so", "libstackwalk.so", "libpatchAPI.so"//, "libclassad.so" + }; agent->SetLibrariesNotToInstrument(libs_not_to_inst); sp::StringSet funcs_not_to_inst; diff --git a/user_agent/fpva/SecSTAR/SecSTAR/structures/__init__.pyc b/user_agent/fpva/SecSTAR/SecSTAR/structures/__init__.pyc index a8ade8c2e..737c7fa95 100644 Binary files a/user_agent/fpva/SecSTAR/SecSTAR/structures/__init__.pyc and b/user_agent/fpva/SecSTAR/SecSTAR/structures/__init__.pyc differ diff --git a/user_agent/fpva/SecSTAR/SecSTAR/structures/event.pyc b/user_agent/fpva/SecSTAR/SecSTAR/structures/event.pyc index f54a90b6e..99b8c681b 100644 Binary files a/user_agent/fpva/SecSTAR/SecSTAR/structures/event.pyc and b/user_agent/fpva/SecSTAR/SecSTAR/structures/event.pyc differ diff --git a/user_agent/fpva/SecSTAR/SecSTAR/structures/graph_artist.pyc b/user_agent/fpva/SecSTAR/SecSTAR/structures/graph_artist.pyc index f0b9445e9..86e90c4ad 100644 Binary files a/user_agent/fpva/SecSTAR/SecSTAR/structures/graph_artist.pyc and b/user_agent/fpva/SecSTAR/SecSTAR/structures/graph_artist.pyc differ diff --git a/user_agent/fpva/SecSTAR/SecSTAR/structures/lookup_table.pyc b/user_agent/fpva/SecSTAR/SecSTAR/structures/lookup_table.pyc index cc669d412..0011d4c72 100644 Binary files a/user_agent/fpva/SecSTAR/SecSTAR/structures/lookup_table.pyc and b/user_agent/fpva/SecSTAR/SecSTAR/structures/lookup_table.pyc differ diff --git a/user_agent/fpva/SecSTAR/SecSTAR/structures/trace.py b/user_agent/fpva/SecSTAR/SecSTAR/structures/trace.py index f113bbe67..ca7e218cc 100644 --- a/user_agent/fpva/SecSTAR/SecSTAR/structures/trace.py +++ b/user_agent/fpva/SecSTAR/SecSTAR/structures/trace.py @@ -121,9 +121,12 @@ def parse(self): self.init_euid = self.__get_node_value2(head_nodes, 'effective_user', 'name') self.cur_euid = self.init_euid self.ppid = self.__get_node_value2(head_nodes, 'parent', 'pid') - self.parent_exe = os.path.basename(self.__get_node_value2(head_nodes, + try: + self.parent_exe = os.path.basename(self.__get_node_value2(head_nodes, 'parent', 'exe_name')) + except: + print("Skipping parent exe name") traces_nodes = dom.getElementsByTagName('traces')[0].childNodes for eve in traces_nodes: @@ -134,7 +137,7 @@ def parse(self): # XXX: abnormal forked pid? skip it for now if eve.firstChild.nodeValue == '4294967295': continue the_eve = event.ForkEvent(eve_type, eve_time, self.hostname, - self.pid, eve.firstChild.nodeValue) + self.pid, self.__get_node_value1(eve.childNodes, 'pid')) elif eve_type == 'clone': the_eve = event.CloneEvent(eve_type, eve_time, self.hostname, self.pid, eve.firstChild.nodeValue) diff --git a/user_agent/fpva/SecSTAR/SecSTAR/structures/trace.pyc b/user_agent/fpva/SecSTAR/SecSTAR/structures/trace.pyc index 0a923443c..b82bf1adc 100644 Binary files a/user_agent/fpva/SecSTAR/SecSTAR/structures/trace.pyc and b/user_agent/fpva/SecSTAR/SecSTAR/structures/trace.pyc differ diff --git a/user_agent/fpva/SecSTAR/SecSTAR/workers/__init__.pyc b/user_agent/fpva/SecSTAR/SecSTAR/workers/__init__.pyc index 589c649ab..7213a0439 100644 Binary files a/user_agent/fpva/SecSTAR/SecSTAR/workers/__init__.pyc and b/user_agent/fpva/SecSTAR/SecSTAR/workers/__init__.pyc differ diff --git a/user_agent/fpva/SecSTAR/SecSTAR/workers/animation_worker.pyc b/user_agent/fpva/SecSTAR/SecSTAR/workers/animation_worker.pyc index 0de602d13..c96dd46fa 100644 Binary files a/user_agent/fpva/SecSTAR/SecSTAR/workers/animation_worker.pyc and b/user_agent/fpva/SecSTAR/SecSTAR/workers/animation_worker.pyc differ diff --git a/user_agent/fpva/SecSTAR/SecSTAR/workers/combine_worker.pyc b/user_agent/fpva/SecSTAR/SecSTAR/workers/combine_worker.pyc index 107494dd2..f147c3dcd 100644 Binary files a/user_agent/fpva/SecSTAR/SecSTAR/workers/combine_worker.pyc and b/user_agent/fpva/SecSTAR/SecSTAR/workers/combine_worker.pyc differ diff --git a/user_agent/fpva/SecSTAR/SecSTAR/workers/lookup_table_worker.pyc b/user_agent/fpva/SecSTAR/SecSTAR/workers/lookup_table_worker.pyc index 09b30aba3..f079eafa1 100644 Binary files a/user_agent/fpva/SecSTAR/SecSTAR/workers/lookup_table_worker.pyc and b/user_agent/fpva/SecSTAR/SecSTAR/workers/lookup_table_worker.pyc differ diff --git a/user_agent/fpva/SecSTAR/SecSTAR/workers/static_graph_worker.pyc b/user_agent/fpva/SecSTAR/SecSTAR/workers/static_graph_worker.pyc index aaa2fe219..e352718d0 100644 Binary files a/user_agent/fpva/SecSTAR/SecSTAR/workers/static_graph_worker.pyc and b/user_agent/fpva/SecSTAR/SecSTAR/workers/static_graph_worker.pyc differ