summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libbacktrace/BacktraceCurrent.cpp11
-rw-r--r--libbacktrace/BacktraceCurrent.h3
-rw-r--r--libbacktrace/UnwindCurrent.cpp39
-rw-r--r--libbacktrace/backtrace_test.cpp18
-rw-r--r--libcutils/Android.mk2
-rw-r--r--libcutils/tests/Android.mk32
-rw-r--r--sdcard/sdcard.c3
7 files changed, 72 insertions, 36 deletions
diff --git a/libbacktrace/BacktraceCurrent.cpp b/libbacktrace/BacktraceCurrent.cpp
index b7190e256..fd1f4da7b 100644
--- a/libbacktrace/BacktraceCurrent.cpp
+++ b/libbacktrace/BacktraceCurrent.cpp
@@ -14,6 +14,7 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#define _GNU_SOURCE 1
17#include <errno.h> 18#include <errno.h>
18#include <stdint.h> 19#include <stdint.h>
19#include <string.h> 20#include <string.h>
@@ -73,6 +74,16 @@ bool BacktraceCurrent::Unwind(size_t num_ignore_frames, ucontext_t* ucontext) {
73 return UnwindFromContext(num_ignore_frames, nullptr); 74 return UnwindFromContext(num_ignore_frames, nullptr);
74} 75}
75 76
77bool BacktraceCurrent::DiscardFrame(const backtrace_frame_data_t& frame) {
78 if (BacktraceMap::IsValid(frame.map)) {
79 const std::string library = basename(frame.map.name.c_str());
80 if (library == "libunwind.so" || library == "libbacktrace.so") {
81 return true;
82 }
83 }
84 return false;
85}
86
76static pthread_mutex_t g_sigaction_mutex = PTHREAD_MUTEX_INITIALIZER; 87static pthread_mutex_t g_sigaction_mutex = PTHREAD_MUTEX_INITIALIZER;
77 88
78static void SignalHandler(int, siginfo_t*, void* sigcontext) { 89static void SignalHandler(int, siginfo_t*, void* sigcontext) {
diff --git a/libbacktrace/BacktraceCurrent.h b/libbacktrace/BacktraceCurrent.h
index 81ea81d5a..8aad36d00 100644
--- a/libbacktrace/BacktraceCurrent.h
+++ b/libbacktrace/BacktraceCurrent.h
@@ -46,6 +46,9 @@ public:
46 46
47 bool Unwind(size_t num_ignore_frames, ucontext_t* ucontext) override; 47 bool Unwind(size_t num_ignore_frames, ucontext_t* ucontext) override;
48 48
49protected:
50 bool DiscardFrame(const backtrace_frame_data_t& frame);
51
49private: 52private:
50 bool UnwindThread(size_t num_ignore_frames); 53 bool UnwindThread(size_t num_ignore_frames);
51 54
diff --git a/libbacktrace/UnwindCurrent.cpp b/libbacktrace/UnwindCurrent.cpp
index 12e289095..67e583f08 100644
--- a/libbacktrace/UnwindCurrent.cpp
+++ b/libbacktrace/UnwindCurrent.cpp
@@ -99,25 +99,30 @@ bool UnwindCurrent::UnwindFromContext(size_t num_ignore_frames, ucontext_t* ucon
99 break; 99 break;
100 } 100 }
101 101
102 if (num_ignore_frames == 0) { 102 frames_.resize(num_frames+1);
103 frames_.resize(num_frames+1); 103 backtrace_frame_data_t* frame = &frames_.at(num_frames);
104 backtrace_frame_data_t* frame = &frames_.at(num_frames); 104 frame->num = num_frames;
105 frame->num = num_frames; 105 frame->pc = static_cast<uintptr_t>(pc);
106 frame->pc = static_cast<uintptr_t>(pc); 106 frame->sp = static_cast<uintptr_t>(sp);
107 frame->sp = static_cast<uintptr_t>(sp); 107 frame->stack_size = 0;
108 frame->stack_size = 0;
109 108
110 if (num_frames > 0) { 109 FillInMap(frame->pc, &frame->map);
111 // Set the stack size for the previous frame. 110 // Check to see if we should skip this frame because it's coming
112 backtrace_frame_data_t* prev = &frames_.at(num_frames-1); 111 // from within the library, and we are doing a local unwind.
113 prev->stack_size = frame->sp - prev->sp; 112 if (ucontext != nullptr || num_frames != 0 || !DiscardFrame(*frame)) {
113 if (num_ignore_frames == 0) {
114 // GetFunctionName is an expensive call, only do it if we are
115 // keeping the frame.
116 frame->func_name = GetFunctionName(frame->pc, &frame->func_offset);
117 if (num_frames > 0) {
118 // Set the stack size for the previous frame.
119 backtrace_frame_data_t* prev = &frames_.at(num_frames-1);
120 prev->stack_size = frame->sp - prev->sp;
121 }
122 num_frames++;
123 } else {
124 num_ignore_frames--;
114 } 125 }
115
116 frame->func_name = GetFunctionName(frame->pc, &frame->func_offset);
117 FillInMap(frame->pc, &frame->map);
118 num_frames++;
119 } else {
120 num_ignore_frames--;
121 } 126 }
122 ret = unw_step (cursor.get()); 127 ret = unw_step (cursor.get());
123 } while (ret > 0 && num_frames < MAX_BACKTRACE_FRAMES); 128 } while (ret > 0 && num_frames < MAX_BACKTRACE_FRAMES);
diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp
index d40885647..5de80b1ac 100644
--- a/libbacktrace/backtrace_test.cpp
+++ b/libbacktrace/backtrace_test.cpp
@@ -14,6 +14,7 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#define _GNU_SOURCE 1
17#include <dirent.h> 18#include <dirent.h>
18#include <errno.h> 19#include <errno.h>
19#include <inttypes.h> 20#include <inttypes.h>
@@ -200,6 +201,23 @@ bool WaitForNonZero(int32_t* value, uint64_t seconds) {
200 return false; 201 return false;
201} 202}
202 203
204TEST(libbacktrace, local_no_unwind_frames) {
205 // Verify that a local unwind does not include any frames within
206 // libunwind or libbacktrace.
207 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), getpid()));
208 ASSERT_TRUE(backtrace->Unwind(0));
209
210 ASSERT_TRUE(backtrace->NumFrames() != 0);
211 for (const auto& frame : *backtrace ) {
212 if (BacktraceMap::IsValid(frame.map)) {
213 const std::string name = basename(frame.map.name.c_str());
214 ASSERT_TRUE(name != "libunwind.so" && name != "libbacktrace.so")
215 << DumpFrames(backtrace.get());
216 }
217 break;
218 }
219}
220
203TEST(libbacktrace, local_trace) { 221TEST(libbacktrace, local_trace) {
204 ASSERT_NE(test_level_one(1, 2, 3, 4, VerifyLevelBacktrace, nullptr), 0); 222 ASSERT_NE(test_level_one(1, 2, 3, 4, VerifyLevelBacktrace, nullptr), 0);
205} 223}
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index 9f3230714..0cd560d11 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -22,6 +22,7 @@ commonSources := \
22 native_handle.c \ 22 native_handle.c \
23 config_utils.c \ 23 config_utils.c \
24 load_file.c \ 24 load_file.c \
25 memory.c \
25 open_memstream.c \ 26 open_memstream.c \
26 strdup16to8.c \ 27 strdup16to8.c \
27 strdup8to16.c \ 28 strdup8to16.c \
@@ -113,7 +114,6 @@ LOCAL_SRC_FILES := $(commonSources) \
113 ashmem-dev.c \ 114 ashmem-dev.c \
114 debugger.c \ 115 debugger.c \
115 klog.c \ 116 klog.c \
116 memory.c \
117 partition_utils.c \ 117 partition_utils.c \
118 properties.c \ 118 properties.c \
119 qtaguid.c \ 119 qtaguid.c \
diff --git a/libcutils/tests/Android.mk b/libcutils/tests/Android.mk
index 5a5469868..d532dfbf5 100644
--- a/libcutils/tests/Android.mk
+++ b/libcutils/tests/Android.mk
@@ -32,21 +32,19 @@ LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
32LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64 32LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
33include $(BUILD_NATIVE_TEST) 33include $(BUILD_NATIVE_TEST)
34 34
35# The static libcutils tests cannot be built when using libc++ because there are 35include $(CLEAR_VARS)
36# multiple symbol definition errors between libc++ and libgcc. b/18389856 36LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
37#include $(CLEAR_VARS) 37LOCAL_MODULE := libcutils_test_static
38#LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk 38LOCAL_FORCE_STATIC_EXECUTABLE := true
39#LOCAL_MODULE := libcutils_test_static 39LOCAL_SRC_FILES := $(test_src_files)
40#LOCAL_FORCE_STATIC_EXECUTABLE := true 40LOCAL_STATIC_LIBRARIES := \
41#LOCAL_SRC_FILES := $(test_src_files) 41 libc \
42#LOCAL_STATIC_LIBRARIES := \ 42 libcutils \
43# libc \ 43 liblog \
44# libcutils \ 44 libutils \
45# liblog \
46# libutils \
47 45
48#LOCAL_CXX_STL := stlport_static 46LOCAL_CXX_STL := libc++_static
49#LOCAL_MULTILIB := both 47LOCAL_MULTILIB := both
50#LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32 48LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
51#LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64 49LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
52#include $(BUILD_NATIVE_TEST) 50include $(BUILD_NATIVE_TEST)
diff --git a/sdcard/sdcard.c b/sdcard/sdcard.c
index 4d50bf0d6..39ce0eb3e 100644
--- a/sdcard/sdcard.c
+++ b/sdcard/sdcard.c
@@ -1869,7 +1869,8 @@ static int run(const char* source_path, const char* dest_path, uid_t uid,
1869 "fd=%i,rootmode=40000,default_permissions,allow_other,user_id=%d,group_id=%d", 1869 "fd=%i,rootmode=40000,default_permissions,allow_other,user_id=%d,group_id=%d",
1870 fd, uid, gid); 1870 fd, uid, gid);
1871 1871
1872 res = mount("/dev/fuse", dest_path, "fuse", MS_NOSUID | MS_NODEV | MS_NOEXEC, opts); 1872 res = mount("/dev/fuse", dest_path, "fuse", MS_NOSUID | MS_NODEV | MS_NOEXEC |
1873 MS_NOATIME, opts);
1873 if (res < 0) { 1874 if (res < 0) {
1874 ERROR("cannot mount fuse filesystem: %s\n", strerror(errno)); 1875 ERROR("cannot mount fuse filesystem: %s\n", strerror(errno));
1875 goto error; 1876 goto error;