diff options
author | Christopher Ferris <cferris@google.com> | 2013-10-21 13:30:52 -0700 |
---|---|---|
committer | Christopher Ferris <cferris@google.com> | 2013-10-28 17:55:25 -0700 |
commit | 17e91d44edf5e6476a477a200bcd89d4327358a3 (patch) | |
tree | 947783229077133a7f467402607a72fe2047a7a7 /include/backtrace | |
parent | f1296b9e92cb04f9bba8c622560d37dfc53c7aa4 (diff) | |
download | system_core-17e91d44edf5e6476a477a200bcd89d4327358a3.zip system_core-17e91d44edf5e6476a477a200bcd89d4327358a3.tar.gz system_core-17e91d44edf5e6476a477a200bcd89d4327358a3.tar.bz2 |
Rewrite libbacktrace using C++.
The old code was essentially trying to be C++ in C and was awkward. This
change makes it all objects with a thin layer that C code can use.
There is a C++ backtrace object that is not very useful, this code will
replace it.
This change also includes moving the backtrace test to a gtest, and adding
coverage of all major functionality.
Bug: 8410085
Change-Id: Iae0f1b09b3dd60395f71ed66010c1ea5cdd37841
Diffstat (limited to 'include/backtrace')
-rw-r--r-- | include/backtrace/Backtrace.h | 85 | ||||
-rw-r--r-- | include/backtrace/backtrace.h | 60 |
2 files changed, 120 insertions, 25 deletions
diff --git a/include/backtrace/Backtrace.h b/include/backtrace/Backtrace.h new file mode 100644 index 0000000..0b75e83 --- /dev/null +++ b/include/backtrace/Backtrace.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _BACKTRACE_BACKTRACE_H +#define _BACKTRACE_BACKTRACE_H + +#include <backtrace/backtrace.h> + +#include <string> + +class BacktraceImpl; + +class Backtrace { +public: + Backtrace(BacktraceImpl* impl); + virtual ~Backtrace(); + + // Get the current stack trace and store in the backtrace_ structure. + virtual bool Unwind(size_t num_ignore_frames); + + // Get the function name and offset into the function given the pc. + // If the string is empty, then no valid function name was found. + virtual std::string GetFunctionName(uintptr_t pc, uintptr_t* offset); + + // Get the name of the map associated with the given pc. If NULL is returned, + // then map_start is not set. Otherwise, map_start is the beginning of this + // map. + virtual const char* GetMapName(uintptr_t pc, uintptr_t* map_start); + + // Finds the memory map associated with the given ptr. + virtual const backtrace_map_info_t* FindMapInfo(uintptr_t ptr); + + // Read the data at a specific address. + virtual bool ReadWord(uintptr_t ptr, uint32_t* out_value) = 0; + + // Create a string representing the formatted line of backtrace information + // for a single frame. + virtual std::string FormatFrameData(size_t frame_num); + + pid_t Pid() { return backtrace_.pid; } + pid_t Tid() { return backtrace_.tid; } + size_t NumFrames() { return backtrace_.num_frames; } + + const backtrace_t* GetBacktrace() { return &backtrace_; } + + const backtrace_frame_data_t* GetFrame(size_t frame_num) { + return &backtrace_.frames[frame_num]; + } + + // Create the correct Backtrace object based on what is to be unwound. + // If pid < 0 or equals the current pid, then the Backtrace object + // corresponds to the current process. + // If pid < 0 or equals the current pid and tid >= 0, then the Backtrace + // object corresponds to a thread in the current process. + // If pid >= 0 and tid < 0, then the Backtrace object corresponds to a + // different process. + // Tracing a thread in a different process is not supported. + static Backtrace* Create(pid_t pid, pid_t tid); + +protected: + virtual bool VerifyReadWordArgs(uintptr_t ptr, uint32_t* out_value); + + BacktraceImpl* impl_; + + backtrace_map_info_t* map_info_; + + backtrace_t backtrace_; + + friend class BacktraceImpl; +}; + +#endif // _BACKTRACE_BACKTRACE_H diff --git a/include/backtrace/backtrace.h b/include/backtrace/backtrace.h index b6bff38..b35a6d5 100644 --- a/include/backtrace/backtrace.h +++ b/include/backtrace/backtrace.h @@ -21,9 +21,7 @@ #include <stdbool.h> #include <inttypes.h> -#ifdef __cplusplus -extern "C" { -#endif +__BEGIN_DECLS #define MAX_BACKTRACE_FRAMES 64 @@ -43,48 +41,58 @@ typedef struct { size_t stack_size; /* The size of the stack, zero indicate an unknown stack size. */ const char* map_name; /* The name of the map to which this pc belongs, NULL indicates the pc doesn't belong to a known map. */ uintptr_t map_offset; /* pc relative to the start of the map, only valid if map_name is not NULL. */ - char* proc_name; /* The function name associated with this pc, NULL if not found. */ - uintptr_t proc_offset; /* pc relative to the start of the procedure, only valid if proc_name is not NULL. */ + char* func_name; /* The function name associated with this pc, NULL if not found. */ + uintptr_t func_offset; /* pc relative to the start of the function, only valid if func_name is not NULL. */ } backtrace_frame_data_t; typedef struct { backtrace_frame_data_t frames[MAX_BACKTRACE_FRAMES]; size_t num_frames; + pid_t pid; pid_t tid; backtrace_map_info_t* map_info_list; - void* private_data; } backtrace_t; -/* Gather the backtrace data for tid and fill in the backtrace structure. - * If tid < 0, then gather the backtrace for the current thread. +typedef struct { + void* data; + const backtrace_t* backtrace; +} backtrace_context_t; + +/* Create a context for the backtrace data and gather the backtrace. + * If pid < 0, then gather the backtrace for the current process. */ -bool backtrace_get_data(backtrace_t* backtrace, pid_t tid); +bool backtrace_create_context( + backtrace_context_t* context, pid_t pid, pid_t tid, size_t num_ignore_frames); -/* Free any memory associated with the backtrace structure. */ -void backtrace_free_data(backtrace_t* backtrace); +/* Gather the backtrace data for a pthread instead of a process. */ +bool backtrace_create_thread_context( + backtrace_context_t* context, pid_t tid, size_t num_ignore_frames); + +/* Free any memory allocated during the context create. */ +void backtrace_destroy_context(backtrace_context_t* context); /* Read data at a specific address for a process. */ bool backtrace_read_word( - const backtrace_t* backtrace, uintptr_t ptr, uint32_t* value); + const backtrace_context_t* context, uintptr_t ptr, uint32_t* value); -/* Get information about the map associated with a pc. If NULL is +/* Get information about the map name associated with a pc. If NULL is * returned, then map_start is not set. */ -const char* backtrace_get_map_info( - const backtrace_t* backtrace, uintptr_t pc, uintptr_t* map_start); +const char* backtrace_get_map_name( + const backtrace_context_t* context, uintptr_t pc, uintptr_t* map_start); -/* Get the procedure name and offest given the pc. If NULL is returned, - * then proc_offset is not set. The returned string is allocated using +/* Get the function name and offset given the pc. If NULL is returned, + * then func_offset is not set. The returned string is allocated using * malloc and must be freed by the caller. */ -char* backtrace_get_proc_name( - const backtrace_t* backtrace, uintptr_t pc, uintptr_t* proc_offset); +char* backtrace_get_func_name( + const backtrace_context_t* context, uintptr_t pc, uintptr_t* func_offset); -/* Loads memory map from /proc/<tid>/maps. If tid < 0, then load the memory +/* Loads memory map from /proc/<pid>/maps. If pid < 0, then load the memory * map for the current process. */ -backtrace_map_info_t* backtrace_create_map_info_list(pid_t tid); +backtrace_map_info_t* backtrace_create_map_info_list(pid_t pid); /* Frees memory associated with the map list. */ void backtrace_destroy_map_info_list(backtrace_map_info_t* map_info_list); @@ -95,10 +103,12 @@ const backtrace_map_info_t* backtrace_find_map_info( /* Create a formatted line of backtrace information for a single frame. */ void backtrace_format_frame_data( - const backtrace_frame_data_t* frame, size_t frame_num, char *buf, size_t buf_size); + const backtrace_context_t* context, size_t frame_num, char* buf, + size_t buf_size); + +/* Get the backtrace data structure associated with the context. */ +const backtrace_t* backtrace_get_data(backtrace_context_t* context); -#ifdef __cplusplus -} -#endif +__END_DECLS #endif /* _BACKTRACE_H */ |