void PProfService::symbol( ::google::protobuf::RpcController* controller_base, const ::brpc::ProfileRequest* /*request*/, ::brpc::ProfileResponse* /*response*/, ::google::protobuf::Closure* done) { ClosureGuard done_guard(done); Controller* cntl = static_cast<Controller*>(controller_base); cntl->http_response().set_content_type("text/plain"); // Load /proc/self/maps pthread_once(&s_load_symbolmap_once, LoadSymbols); if (cntl->http_request().method() != HTTP_METHOD_POST) { char buf[64]; snprintf(buf, sizeof(buf), "num_symbols: %lu\n", symbol_map.size()); cntl->response_attachment().append(buf); } else { // addr_str is addressed separated by + std::string addr_str = cntl->request_attachment().to_string(); // May be quoted const char* addr_cstr = addr_str.c_str(); if (*addr_cstr == '\'' || *addr_cstr == '"') { ++addr_cstr; } std::vector<uintptr_t> addr_list; addr_list.reserve(32); butil::StringSplitter sp(addr_cstr, '+'); for ( ; sp != NULL; ++sp) { char* endptr; uintptr_t addr = strtoull(sp.field(), &endptr, 16); addr_list.push_back(addr); } FindSymbols(&cntl->response_attachment(), addr_list); } }
void DumpEnumEntry(SYMBOL *Sym) { SYMBOL *theSym; if (!Sym) { printf("Null Symbol\n"); return; } #if 0 if (Sym < SymTab) return; if ((int) Sym >= (int)((int) SymTab + sizeof(SYMBOL) * SYMMAX) ) return; #endif if ((Sym->Section == section_Enum) && (Sym->LocalScope != 0)) { if ((Sym->Flags & SymFlag_Ref) == 0) printf("*Unref* "); theSym = FindSymbols(Sym->Name,section_Enum,section_Enum, 0); if (theSym) printf("Global %2d: ",Sym->LocalScope); else printf("Local %2d: ",Sym->LocalScope); printf("%2s ", Sect_Strings[Sym->Type]); printf("0x%s ",Hex32(Sym->Value)); printf("- 0x%s ",Hex32(Sym->EndIP)); printf("'%s'",Sym->Name); switch(Sym->LabelType) { case label_Local: printf(" (Local)"); break; case label_Function: printf(" (Function)(%d)", Sym->Params); break; case label_Virtual: printf(" (Virtual Function 0x%x)(%d)", Sym->VirtualIndex, Sym->Params); break; } printf("\n"); } }
int SymbolExists(char *ThisName, int sect, int scope) { SYMBOL *theSym; if (scope != -1) theSym = FindSymbols(ThisName, sect, sect, scope); else theSym = FindSymbolsOld(ThisName, sect, sect); if (theSym) return 1; return 0; }
SYMBOL * GetGlobalSym(char *ThisName) { SYMBOL *theSym; int scope; // Variable wasnt found is local scope, so check global scope theSym = FindSymbols(ThisName,section_Enum,section_Enum, 0); if (theSym) { // Found a global, so extract the scope of this global scope = theSym->Value; theSym = FindSymbols(ThisName,section_Enum,section_Enum, scope); if (theSym) return theSym; } return 0; }
void StepOneThreadSuite::RunDebuggee( Step* steps, int stepsCount ) { Exec exec; TEST_ASSERT_RETURN( SUCCEEDED( exec.Init( mCallback ) ) ); LaunchInfo info = { 0 }; wchar_t cmdLine[ MAX_PATH ] = L""; IProcess* proc = NULL; const wchar_t* Debuggee = StepOneThreadDebuggee; Symbol funcs[] = { { NULL, 0 }, { L"Scenario1Func0", 0 }, { L"Scenario1Func1", 0 }, { L"Scenario1Func2", 0 }, { L"Scenario1Func3", 0 }, }; TEST_ASSERT_RETURN( SUCCEEDED( FindSymbols( Debuggee, funcs, _countof( funcs ) ) ) ); swprintf_s( cmdLine, L"\"%s\" 1", Debuggee ); info.CommandLine = cmdLine; info.Exe = Debuggee; TEST_ASSERT_RETURN( SUCCEEDED( exec.Launch( &info, proc ) ) ); uint32_t pid = proc->GetId(); int nextStep = 0; char msg[1024] = ""; RefPtr<IProcess> process; process = proc; proc->Release(); mCallback->SetTrackLastEvent( true ); for ( int i = 0; !mCallback->GetProcessExited(); i++ ) { bool continued = false; HRESULT hr = exec.WaitForEvent( DefaultTimeoutMillis ); // this should happen after process exit if ( hr == E_TIMEOUT ) break; TEST_ASSERT_RETURN( SUCCEEDED( hr ) ); TEST_ASSERT_RETURN( SUCCEEDED( hr = exec.DispatchEvent() ) ); if ( !process->IsStopped() ) continue; if ( (mCallback->GetLastEvent()->Code != ExecEvent_ModuleLoad) && (mCallback->GetLastEvent()->Code != ExecEvent_ModuleUnload) && (mCallback->GetLastEvent()->Code != ExecEvent_ThreadStart) && (mCallback->GetLastEvent()->Code != ExecEvent_ThreadExit) && (mCallback->GetLastEvent()->Code != ExecEvent_LoadComplete) ) { Step* curStep = &steps[nextStep]; nextStep++; RefPtr<Thread> thread; CONTEXT_X86 context = { 0 }; if ( mCallback->GetLastThreadId() != 0 ) { TEST_ASSERT_RETURN( process->FindThread( mCallback->GetLastThreadId(), thread.Ref() ) ); TEST_ASSERT_RETURN( exec.GetThreadContext( process, thread->GetId(), CONTEXT_X86_FULL, 0, &context, sizeof context ) == S_OK ); } uintptr_t baseAddr = 0; RefPtr<IModule> procMod = mCallback->GetProcessModule(); if ( procMod.Get() != NULL ) baseAddr = (uintptr_t) procMod->GetImageBase(); // TODO: test threadId if ( mCallback->GetLastEvent()->Code != curStep->Event.Code ) { sprintf_s( msg, "Expected event '%s', got '%s'.", GetEventName( curStep->Event.Code ), GetEventName( mCallback->GetLastEvent()->Code ) ); TEST_FAIL_MSG( msg ); break; } else if ( (curStep->Event.Code == ExecEvent_Exception) && (curStep->Event.ExceptionCode != ((ExceptionEventNode*) mCallback->GetLastEvent().get())->Exception.ExceptionCode) ) { sprintf_s( msg, "Expected exception %08x, got %08x.", curStep->Event.ExceptionCode, ((ExceptionEventNode*) mCallback->GetLastEvent().get())->Exception.ExceptionCode ); TEST_FAIL_MSG( msg ); break; } else if ( (curStep->Event.Code == ExecEvent_Exception) || (curStep->Event.Code == ExecEvent_StepComplete) || (curStep->Event.Code == ExecEvent_Breakpoint) ) { uintptr_t funcRva = funcs[curStep->Event.FunctionIndex].RelativeAddress; uintptr_t addr = (funcRva + curStep->Event.AddressOffset + baseAddr); if ( context.Eip != addr ) { sprintf_s( msg, "Expected instruction pointer at %08x, got %08x.", addr, context.Eip ); TEST_FAIL_MSG( msg ); break; } } mCallback->SetCanStepInFunctionReturnValue( curStep->Action.CanStepInFunction ); if ( curStep->Action.BPAddressOffset != 0 ) { uintptr_t funcRva = funcs[curStep->Action.FunctionIndex].RelativeAddress; uintptr_t addr = (funcRva + curStep->Action.BPAddressOffset + baseAddr); TEST_ASSERT_RETURN( SUCCEEDED( exec.SetBreakpoint( process.Get(), addr ) ) ); } if ( curStep->Action.Action == Action_StepInstruction ) { TEST_ASSERT_RETURN( SUCCEEDED( exec.StepInstruction( process.Get(), curStep->Action.StepIn, true ) ) ); continued = true; } else if ( curStep->Action.Action == Action_StepRange ) { AddressRange range = { context.Eip, context.Eip }; TEST_ASSERT_RETURN( SUCCEEDED( exec.StepRange( process.Get(), curStep->Action.StepIn, range, true ) ) ); continued = true; } } if ( !continued ) TEST_ASSERT_RETURN( SUCCEEDED( exec.Continue( process, true ) ) ); } TEST_ASSERT( mCallback->GetLoadCompleted() ); TEST_ASSERT( mCallback->GetProcessExited() ); }
int GetEnumValue(char *ThisName) { SYMBOL *theSym; int scope; ClearLastSymbolRef(); // Test to see if this symbol is a thunk alias if (ThisName[0] == '%') { int v; PushTokenPtr(ThisName, 0); if (!Token("%")) Error(Error_Fatal, "Missing Thunk Delimiter"); v = GetDecNum(5); if (GetDecNumDigitCount() == 0) Error(Error_Fatal, "Missing Thunk Number"); PopTokenPtr(); theSym = GetThunk(v); if (!theSym) { if (Pass == 1) return 0; printf("Bad thunk!!\n"); doCannotEvaluate(ThisName+1); return 0; } SetLastSymbolRef(theSym); return theSym->Value; } // Now deal with all other symbols theSym = FindSymbols(ThisName,section_Enum,section_Enum, LocalScope); if (theSym) // Variable was found in local scope { // Add one more reference to this symbol //theSym->Ref++; SetLastSymbolRef(theSym); // Save the symbols label type //EnumFunction = theSym->LabelType; return theSym->Value; } else { // Variable wasnt found is local scope, so check global scope theSym = FindSymbols(ThisName,section_Enum,section_Enum, 0); if (theSym) { // Found a global, so extract the scope of this global scope = theSym->Value; theSym = FindSymbols(ThisName,section_Enum,section_Enum, scope); if (theSym) { // Add one more reference to this symbol //theSym->Ref++; SetLastSymbolRef(theSym); // Save the symbols label type //EnumFunction = theSym->LabelType; return theSym->Value; } } } // Dont worry if a global doesnt exist in pass 1 if (Pass == 1) return 0; // Do worry in other passes doCannotEvaluate(ThisName); return 0; }