Unwind: prevent unw_get_proc_info from returning stale data
authorSaleem Abdulrasool <compnerd@compnerd.org>
Fri, 20 Sep 2019 15:53:42 +0000 (15:53 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Fri, 20 Sep 2019 15:53:42 +0000 (15:53 +0000)
If unwind info is not available at the current IP, unw_get_proc_info should
return a zero-filled structure rather than the info of the previous IP.

This change also makes unw_get_proc_info return UNW_ENOINFO instead of
UNW_ESUCCESS.

Patch by Amanieu d'Antras!

llvm-svn: 372407

libunwind/src/UnwindCursor.hpp
libunwind/test/libunwind_01.pass.cpp

index a96c9f3..488c317 100644 (file)
@@ -1991,7 +1991,10 @@ int UnwindCursor<A, R>::step() {
 
 template <typename A, typename R>
 void UnwindCursor<A, R>::getInfo(unw_proc_info_t *info) {
-  *info = _info;
+  if (_unwindInfoMissing)
+    memset(info, 0, sizeof(*info));
+  else
+    *info = _info;
 }
 
 template <typename A, typename R>
index 6957d98..830dcdd 100644 (file)
@@ -35,8 +35,29 @@ void test3(int i, int j, int k) {
   test2(j, k);
 }
 
+void test_no_info() {
+  unw_context_t context;
+  unw_getcontext(&context);
+
+  unw_cursor_t cursor;
+  unw_init_local(&cursor, &context);
+
+  unw_proc_info_t info;
+  int ret = unw_get_proc_info(&cursor, &info);
+  if (ret != UNW_ESUCCESS)
+    abort();
+
+  // Set the IP to an address clearly outside any function.
+  unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)&context);
+
+  ret = unw_get_proc_info(&cursor, &info);
+  if (ret != UNW_ENOINFO)
+    abort();
+}
+
 int main() {
   test1(1);
   test2(1, 2);
   test3(1, 2, 3);
+  test_no_info();
 }