Commit 09e8e71f authored by gejun's avatar gejun

minor changes

Change-Id: Icf7e87ee4b169887c56ff463a94d9b31eede0520
parent a19ff045
Initialize repo
The opensource version of baidu-rpc
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/debug/profiler.h"
#include <string>
#include "base/process/process_handle.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#if defined(OS_WIN)
#include "base/win/pe_image.h"
#endif // defined(OS_WIN)
// TODO(peria): Enable profiling on Windows.
#if defined(ENABLE_PROFILING) && !defined(NO_TCMALLOC) && !defined(OS_WIN)
#include "third_party/tcmalloc/chromium/src/gperftools/profiler.h"
#endif
namespace base {
namespace debug {
// TODO(peria): Enable profiling on Windows.
#if defined(ENABLE_PROFILING) && !defined(NO_TCMALLOC) && !defined(OS_WIN)
static int profile_count = 0;
void StartProfiling(const std::string& name) {
++profile_count;
std::string full_name(name);
std::string pid = StringPrintf("%d", GetCurrentProcId());
std::string count = StringPrintf("%d", profile_count);
ReplaceSubstringsAfterOffset(&full_name, 0, "{pid}", pid);
ReplaceSubstringsAfterOffset(&full_name, 0, "{count}", count);
ProfilerStart(full_name.c_str());
}
void StopProfiling() {
ProfilerFlush();
ProfilerStop();
}
void FlushProfiling() {
ProfilerFlush();
}
bool BeingProfiled() {
return ProfilingIsEnabledForAllThreads();
}
void RestartProfilingAfterFork() {
ProfilerRegisterThread();
}
#else
void StartProfiling(const std::string& name) {
}
void StopProfiling() {
}
void FlushProfiling() {
}
bool BeingProfiled() {
return false;
}
void RestartProfilingAfterFork() {
}
#endif
#if !defined(OS_WIN)
bool IsBinaryInstrumented() {
return false;
}
ReturnAddressLocationResolver GetProfilerReturnAddrResolutionFunc() {
return NULL;
}
DynamicFunctionEntryHook GetProfilerDynamicFunctionEntryHookFunc() {
return NULL;
}
AddDynamicSymbol GetProfilerAddDynamicSymbolFunc() {
return NULL;
}
MoveDynamicSymbol GetProfilerMoveDynamicSymbolFunc() {
return NULL;
}
#else // defined(OS_WIN)
// http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx
extern "C" IMAGE_DOS_HEADER __ImageBase;
bool IsBinaryInstrumented() {
enum InstrumentationCheckState {
UNINITIALIZED,
INSTRUMENTED_IMAGE,
NON_INSTRUMENTED_IMAGE,
};
static InstrumentationCheckState state = UNINITIALIZED;
if (state == UNINITIALIZED) {
HMODULE this_module = reinterpret_cast<HMODULE>(&__ImageBase);
base::win::PEImage image(this_module);
// Check to be sure our image is structured as we'd expect.
DCHECK(image.VerifyMagic());
// Syzygy-instrumented binaries contain a PE image section named ".thunks",
// and all Syzygy-modified binaries contain the ".syzygy" image section.
// This is a very fast check, as it only looks at the image header.
if ((image.GetImageSectionHeaderByName(".thunks") != NULL) &&
(image.GetImageSectionHeaderByName(".syzygy") != NULL)) {
state = INSTRUMENTED_IMAGE;
} else {
state = NON_INSTRUMENTED_IMAGE;
}
}
DCHECK(state != UNINITIALIZED);
return state == INSTRUMENTED_IMAGE;
}
namespace {
struct FunctionSearchContext {
const char* name;
FARPROC function;
};
// Callback function to PEImage::EnumImportChunks.
bool FindResolutionFunctionInImports(
const base::win::PEImage &image, const char* module_name,
PIMAGE_THUNK_DATA unused_name_table, PIMAGE_THUNK_DATA import_address_table,
PVOID cookie) {
FunctionSearchContext* context =
reinterpret_cast<FunctionSearchContext*>(cookie);
DCHECK_NE(static_cast<FunctionSearchContext*>(NULL), context);
DCHECK_EQ(static_cast<FARPROC>(NULL), context->function);
// Our import address table contains pointers to the functions we import
// at this point. Let's retrieve the first such function and use it to
// find the module this import was resolved to by the loader.
const wchar_t* function_in_module =
reinterpret_cast<const wchar_t*>(import_address_table->u1.Function);
// Retrieve the module by a function in the module.
const DWORD kFlags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT;
HMODULE module = NULL;
if (!::GetModuleHandleEx(kFlags, function_in_module, &module)) {
// This can happen if someone IAT patches us to a thunk.
return true;
}
// See whether this module exports the function we're looking for.
FARPROC exported_func = ::GetProcAddress(module, context->name);
if (exported_func != NULL) {
// We found it, return the function and terminate the enumeration.
context->function = exported_func;
return false;
}
// Keep going.
return true;
}
template <typename FunctionType>
FunctionType FindFunctionInImports(const char* function_name) {
if (!IsBinaryInstrumented())
return NULL;
HMODULE this_module = reinterpret_cast<HMODULE>(&__ImageBase);
base::win::PEImage image(this_module);
FunctionSearchContext ctx = { function_name, NULL };
image.EnumImportChunks(FindResolutionFunctionInImports, &ctx);
return reinterpret_cast<FunctionType>(ctx.function);
}
} // namespace
ReturnAddressLocationResolver GetProfilerReturnAddrResolutionFunc() {
return FindFunctionInImports<ReturnAddressLocationResolver>(
"ResolveReturnAddressLocation");
}
DynamicFunctionEntryHook GetProfilerDynamicFunctionEntryHookFunc() {
return FindFunctionInImports<DynamicFunctionEntryHook>(
"OnDynamicFunctionEntry");
}
AddDynamicSymbol GetProfilerAddDynamicSymbolFunc() {
return FindFunctionInImports<AddDynamicSymbol>(
"AddDynamicSymbol");
}
MoveDynamicSymbol GetProfilerMoveDynamicSymbolFunc() {
return FindFunctionInImports<MoveDynamicSymbol>(
"MoveDynamicSymbol");
}
#endif // defined(OS_WIN)
} // namespace debug
} // namespace base
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_DEBUG_PROFILER_H
#define BASE_DEBUG_PROFILER_H
#include <string>
#include "base/base_export.h"
#include "base/basictypes.h"
// The Profiler functions allow usage of the underlying sampling based
// profiler. If the application has not been built with the necessary
// flags (-DENABLE_PROFILING and not -DNO_TCMALLOC) then these functions
// are noops.
namespace base {
namespace debug {
// Start profiling with the supplied name.
// {pid} will be replaced by the process' pid and {count} will be replaced
// by the count of the profile run (starts at 1 with each process).
BASE_EXPORT void StartProfiling(const std::string& name);
// Stop profiling and write out data.
BASE_EXPORT void StopProfiling();
// Force data to be written to file.
BASE_EXPORT void FlushProfiling();
// Returns true if process is being profiled.
BASE_EXPORT bool BeingProfiled();
// Reset profiling after a fork, which disables timers.
BASE_EXPORT void RestartProfilingAfterFork();
// Returns true iff this executable is instrumented with the Syzygy profiler.
BASE_EXPORT bool IsBinaryInstrumented();
// There's a class of profilers that use "return address swizzling" to get a
// hook on function exits. This class of profilers uses some form of entry hook,
// like e.g. binary instrumentation, or a compiler flag, that calls a hook each
// time a function is invoked. The hook then switches the return address on the
// stack for the address of an exit hook function, and pushes the original
// return address to a shadow stack of some type. When in due course the CPU
// executes a return to the exit hook, the exit hook will do whatever work it
// does on function exit, then arrange to return to the original return address.
// This class of profiler does not play well with programs that look at the
// return address, as does e.g. V8. V8 uses the return address to certain
// runtime functions to find the JIT code that called it, and from there finds
// the V8 data structures associated to the JS function involved.
// A return address resolution function is used to fix this. It allows such
// programs to resolve a location on stack where a return address originally
// resided, to the shadow stack location where the profiler stashed it.
typedef uintptr_t (*ReturnAddressLocationResolver)(
uintptr_t return_addr_location);
// This type declaration must match V8's FunctionEntryHook.
typedef void (*DynamicFunctionEntryHook)(uintptr_t function,
uintptr_t return_addr_location);
// The functions below here are to support profiling V8-generated code.
// V8 has provisions for generating a call to an entry hook for newly generated
// JIT code, and it can push symbol information on code generation and advise
// when the garbage collector moves code. The functions declarations below here
// make glue between V8's facilities and a profiler.
// This type declaration must match V8's FunctionEntryHook.
typedef void (*DynamicFunctionEntryHook)(uintptr_t function,
uintptr_t return_addr_location);
typedef void (*AddDynamicSymbol)(const void* address,
size_t length,
const char* name,
size_t name_len);
typedef void (*MoveDynamicSymbol)(const void* address, const void* new_address);
// If this binary is instrumented and the instrumentation supplies a function
// for each of those purposes, find and return the function in question.
// Otherwise returns NULL.
BASE_EXPORT ReturnAddressLocationResolver GetProfilerReturnAddrResolutionFunc();
BASE_EXPORT DynamicFunctionEntryHook GetProfilerDynamicFunctionEntryHookFunc();
BASE_EXPORT AddDynamicSymbol GetProfilerAddDynamicSymbolFunc();
BASE_EXPORT MoveDynamicSymbol GetProfilerMoveDynamicSymbolFunc();
} // namespace debug
} // namespace base
#endif // BASE_DEBUG_DEBUGGER_H
......@@ -79,7 +79,7 @@
// };
//
//
// Example: Class that has to be contructed/destroyed on same thread, it has
// Example: Class that has to be constructed/destroyed on same thread, it has
// a "shareable" method (with external synchronization) and a not
// shareable method (even with external synchronization).
//
......
......@@ -7,12 +7,9 @@
#ifndef BRPC_DATA_FACTORY_H
#define BRPC_DATA_FACTORY_H
#include <pthread.h>
// To baidu-rpc developers: This is a header included by user, don't depend
// on internal structures, use opaque pointers instead.
namespace brpc {
class DataFactory {
......@@ -32,5 +29,4 @@ public:
} // namespace brpc
#endif // BRPC_DATA_FACTORY_H
......@@ -111,7 +111,7 @@ struct Butex {
base::Mutex waiter_lock;
};
// Confirm that Butex is consistent with constants in bthread_types.h
// Confirm that Butex is consistent with constants in bthread/types.h
BAIDU_CASSERT(sizeof(Butex) == BUTEX_MEMORY_SIZE,
sizeof_Butex_must_match);
// Confirm that layout of Butex is consistent with impl. of butex_locate()
......
......@@ -28,7 +28,7 @@ struct TimerThreadOptions {
// Default: ""
std::string bvar_prefix;
// Contruct with default options.
// Constructed with default options.
TimerThreadOptions();
};
......
......@@ -42,7 +42,7 @@ public:
// Options for Variable::dump_exposed().
struct DumpOptions {
// Contructed with default options.
// Constructed with default options.
DumpOptions();
// If this is true, string-type values will be quoted.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment