Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 688a8a72 authored by Christopher Ferris's avatar Christopher Ferris
Browse files

Remove libcorkscrew.

All unwinding is now done through libunwind.

Change-Id: I93ba6f5bd5ad41eeb5f6a93113b7894f842cc8e0
parent 4a5966b9
Loading
Loading
Loading
Loading
+0 −22
Original line number Diff line number Diff line
@@ -46,10 +46,6 @@ libbacktrace_shared_libraries_target := \
	libcutils \
	libgccdemangle \

# To enable using libunwind on each arch, add it to this list.
libunwind_architectures := arm arm64 mips x86 x86_64

ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),$(libunwind_architectures)))
libbacktrace_src_files += \
	UnwindCurrent.cpp \
	UnwindMap.cpp \
@@ -68,24 +64,6 @@ libbacktrace_shared_libraries_host := \
libbacktrace_static_libraries_host := \
	libcutils \

else
libbacktrace_src_files += \
	Corkscrew.cpp \

libbacktrace_c_includes := \
	system/core/libcorkscrew \

libbacktrace_shared_libraries := \
	libcorkscrew \

libbacktrace_shared_libraries_target += \
	libdl \

libbacktrace_ldlibs_host := \
	-ldl \

endif

module := libbacktrace
module_tag := optional
build_type := target

libbacktrace/Corkscrew.cpp

deleted100644 → 0
+0 −250
Original line number Diff line number Diff line
/*
 * 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.
 */

#include <backtrace/Backtrace.h>

#include <string.h>

#include <backtrace-arch.h>
#include <corkscrew/backtrace.h>

#ifndef __USE_GNU
#define __USE_GNU
#endif
#include <dlfcn.h>

#include "BacktraceLog.h"
#include "Corkscrew.h"

//-------------------------------------------------------------------------
// CorkscrewMap functions.
//-------------------------------------------------------------------------
CorkscrewMap::CorkscrewMap(pid_t pid) : BacktraceMap(pid), map_info_(NULL) {
}

CorkscrewMap::~CorkscrewMap() {
  if (map_info_) {
    free_map_info_list(map_info_);
    map_info_ = NULL;
  }
}

bool CorkscrewMap::Build() {
  map_info_ = load_map_info_list(pid_);

  // Use the information in map_info_ to construct the BacktraceMap data
  // rather than reparsing /proc/self/maps.
  map_info_t* cur_map = map_info_;
  while (cur_map) {
    backtrace_map_t map;
    map.start = cur_map->start;
    map.end = cur_map->end;
    map.flags = 0;
    if (cur_map->is_readable) {
      map.flags |= PROT_READ;
    }
    if (cur_map->is_writable) {
      map.flags |= PROT_WRITE;
    }
    if (cur_map->is_executable) {
      map.flags |= PROT_EXEC;
    }
    map.name = cur_map->name;

    // The maps are in descending order, but we want them in ascending order.
    maps_.push_front(map);

    cur_map = cur_map->next;
  }
  return map_info_ != NULL;
}

//-------------------------------------------------------------------------
// CorkscrewCommon functions.
//-------------------------------------------------------------------------
bool CorkscrewCommon::GenerateFrameData(
    backtrace_frame_t* cork_frames, ssize_t num_frames) {
  if (num_frames < 0) {
    BACK_LOGW("libcorkscrew unwind failed.");
    return false;
  }

  std::vector<backtrace_frame_data_t>* frames = GetFrames();
  frames->resize(num_frames);
  size_t i = 0;
  for (std::vector<backtrace_frame_data_t>::iterator it = frames->begin();
       it != frames->end(); ++it, ++i) {
    it->num = i;
    it->pc = cork_frames[i].absolute_pc;
    it->sp = cork_frames[i].stack_top;
    it->stack_size = cork_frames[i].stack_size;
    it->func_offset = 0;

    it->map = FindMap(it->pc);
    it->func_name = GetFunctionName(it->pc, &it->func_offset);
  }
  return true;
}

//-------------------------------------------------------------------------
// CorkscrewCurrent functions.
//-------------------------------------------------------------------------
CorkscrewCurrent::CorkscrewCurrent() {
}

CorkscrewCurrent::~CorkscrewCurrent() {
}

bool CorkscrewCurrent::Unwind(size_t num_ignore_frames) {
  backtrace_frame_t frames[MAX_BACKTRACE_FRAMES];
  ssize_t num_frames = unwind_backtrace(frames, num_ignore_frames, MAX_BACKTRACE_FRAMES);

  return GenerateFrameData(frames, num_frames);
}

std::string CorkscrewCurrent::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) {
  *offset = 0;

  Dl_info info;
  const backtrace_map_t* map = FindMap(pc);
  if (map) {
    if (dladdr((const void*)pc, &info)) {
      if (info.dli_sname) {
        *offset = pc - map->start - (uintptr_t)info.dli_saddr + (uintptr_t)info.dli_fbase;
        return info.dli_sname;
      }
    } else {
      // dladdr(3) didn't find a symbol; maybe it's static? Look in the ELF file...
      symbol_table_t* symbol_table = load_symbol_table(map->name.c_str());
      if (symbol_table) {
        // First check if we can find the symbol using a relative pc.
        std::string name;
        const symbol_t* elf_symbol = find_symbol(symbol_table, pc - map->start);
        if (elf_symbol) {
          name = elf_symbol->name;
          *offset = pc - map->start - elf_symbol->start;
        } else if ((elf_symbol = find_symbol(symbol_table, pc)) != NULL) {
          // Found the symbol using the absolute pc.
          name = elf_symbol->name;
          *offset = pc - elf_symbol->start;
        }
        free_symbol_table(symbol_table);
        return name;
      }
    }
  }
  return "";
}

//-------------------------------------------------------------------------
// CorkscrewThread functions.
//-------------------------------------------------------------------------
CorkscrewThread::CorkscrewThread() {
}

CorkscrewThread::~CorkscrewThread() {
}

void CorkscrewThread::ThreadUnwind(
    siginfo_t* siginfo, void* sigcontext, size_t num_ignore_frames) {
  backtrace_frame_t cork_frames[MAX_BACKTRACE_FRAMES];
  CorkscrewMap* map = static_cast<CorkscrewMap*>(GetMap());
  ssize_t num_frames = unwind_backtrace_signal_arch(
      siginfo, sigcontext, map->GetMapInfo(), cork_frames,
      num_ignore_frames, MAX_BACKTRACE_FRAMES);
  if (num_frames > 0) {
    std::vector<backtrace_frame_data_t>* frames = GetFrames();
    frames->resize(num_frames);
    size_t i = 0;
    for (std::vector<backtrace_frame_data_t>::iterator it = frames->begin();
         it != frames->end(); ++it, ++i) {
      it->num = i;
      it->pc = cork_frames[i].absolute_pc;
      it->sp = cork_frames[i].stack_top;
      it->stack_size = cork_frames[i].stack_size;
      it->map = NULL;
      it->func_offset = 0;
    }
  }
}

//-------------------------------------------------------------------------
// CorkscrewPtrace functions.
//-------------------------------------------------------------------------
CorkscrewPtrace::CorkscrewPtrace() : ptrace_context_(NULL) {
}

CorkscrewPtrace::~CorkscrewPtrace() {
  if (ptrace_context_) {
    free_ptrace_context(ptrace_context_);
    ptrace_context_ = NULL;
  }
}

bool CorkscrewPtrace::Unwind(size_t num_ignore_frames) {
  ptrace_context_ = load_ptrace_context(Tid());

  backtrace_frame_t frames[MAX_BACKTRACE_FRAMES];
  ssize_t num_frames = unwind_backtrace_ptrace(
      Tid(), ptrace_context_, frames, num_ignore_frames, MAX_BACKTRACE_FRAMES);

  return GenerateFrameData(frames, num_frames);
}

std::string CorkscrewPtrace::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) {
  // Get information about a different process.
  const map_info_t* map_info;
  const symbol_t* symbol;
  find_symbol_ptrace(ptrace_context_, pc, &map_info, &symbol);
  char* symbol_name = NULL;
  if (symbol) {
    if (map_info) {
      *offset = pc - map_info->start - symbol->start;
    }
    symbol_name = symbol->name;
    return symbol_name;
  }

  return "";
}

//-------------------------------------------------------------------------
// C++ object creation functions.
//-------------------------------------------------------------------------
Backtrace* CreateCurrentObj(BacktraceMap* map) {
  return new BacktraceCurrent(new CorkscrewCurrent(), map);
}

Backtrace* CreatePtraceObj(pid_t pid, pid_t tid, BacktraceMap* map) {
  return new BacktracePtrace(new CorkscrewPtrace(), pid, tid, map);
}

Backtrace* CreateThreadObj(pid_t tid, BacktraceMap* map) {
  CorkscrewThread* thread_obj = new CorkscrewThread();
  return new BacktraceThread(thread_obj, thread_obj, tid, map);
}

//-------------------------------------------------------------------------
// BacktraceMap create function.
//-------------------------------------------------------------------------
BacktraceMap* BacktraceMap::Create(pid_t pid) {
  BacktraceMap* map = new CorkscrewMap(pid);
  if (!map->Build()) {
    delete map;
    return NULL;
  }
  return map;
}

libbacktrace/Corkscrew.h

deleted100644 → 0
+0 −82
Original line number Diff line number Diff line
/*
 * 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 _LIBBACKTRACE_CORKSCREW_H
#define _LIBBACKTRACE_CORKSCREW_H

#include <inttypes.h>

#include <string>

#include <backtrace/Backtrace.h>
#include <backtrace/BacktraceMap.h>

#include <corkscrew/backtrace.h>

#include "BacktraceImpl.h"
#include "BacktraceThread.h"

class CorkscrewMap : public BacktraceMap {
public:
  CorkscrewMap(pid_t pid);
  virtual ~CorkscrewMap();

  virtual bool Build();

  map_info_t* GetMapInfo() { return map_info_; }

private:
  map_info_t* map_info_;
};

class CorkscrewCommon : public BacktraceImpl {
public:
  bool GenerateFrameData(backtrace_frame_t* cork_frames, ssize_t num_frames);
};

class CorkscrewCurrent : public CorkscrewCommon {
public:
  CorkscrewCurrent();
  virtual ~CorkscrewCurrent();

  virtual bool Unwind(size_t num_ignore_threads);

  virtual std::string GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset);
};

class CorkscrewThread : public CorkscrewCurrent, public BacktraceThreadInterface {
public:
  CorkscrewThread();
  virtual ~CorkscrewThread();

  virtual void ThreadUnwind(
      siginfo_t* siginfo, void* sigcontext, size_t num_ignore_frames);
};

class CorkscrewPtrace : public CorkscrewCommon {
public:
  CorkscrewPtrace();
  virtual ~CorkscrewPtrace();

  virtual std::string GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset);

  virtual bool Unwind(size_t num_ignore_threads);

private:
  ptrace_context_t* ptrace_context_;
};

#endif // _LIBBACKTRACE_CORKSCREW_H

libcorkscrew/Android.mk

deleted100644 → 0
+0 −100
Original line number Diff line number Diff line
# Copyright (C) 2011 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.

LOCAL_PATH:= $(call my-dir)

generic_src_files := \
	backtrace.c \
	backtrace-helper.c \
	demangle.c \
	map_info.c \
	ptrace.c \
	symbol_table.c

arm_src_files := \
	arch-arm/backtrace-arm.c \
	arch-arm/ptrace-arm.c

x86_src_files := \
	arch-x86/backtrace-x86.c \
	arch-x86/ptrace-x86.c

ifneq ($(TARGET_IS_64_BIT),true)

include $(CLEAR_VARS)

LOCAL_SRC_FILES := $(generic_src_files)

ifeq ($(TARGET_ARCH),arm)
LOCAL_SRC_FILES += $(arm_src_files)
LOCAL_CFLAGS += -DCORKSCREW_HAVE_ARCH
endif
ifeq ($(TARGET_ARCH),x86)
LOCAL_SRC_FILES += $(x86_src_files)
LOCAL_CFLAGS += -DCORKSCREW_HAVE_ARCH
endif
ifeq ($(TARGET_ARCH),mips)
LOCAL_SRC_FILES += \
	arch-mips/backtrace-mips.c \
	arch-mips/ptrace-mips.c
LOCAL_CFLAGS += -DCORKSCREW_HAVE_ARCH
endif

LOCAL_SHARED_LIBRARIES += libdl libcutils liblog libgccdemangle

LOCAL_CFLAGS += -std=gnu99 -Werror -Wno-unused-parameter
LOCAL_MODULE := libcorkscrew
LOCAL_MODULE_TAGS := optional

include $(BUILD_SHARED_LIBRARY)

# Build test.
include $(CLEAR_VARS)
LOCAL_SRC_FILES := test.cpp
LOCAL_CFLAGS += -Werror -fno-inline-small-functions
LOCAL_SHARED_LIBRARIES := libcorkscrew
LOCAL_MODULE := libcorkscrew_test
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)

endif # TARGET_IS_64_BIT == false


ifeq ($(HOST_OS)-$(HOST_ARCH),linux-x86)

# Build libcorkscrew.
include $(CLEAR_VARS)
LOCAL_SRC_FILES += $(generic_src_files) $(x86_src_files)
LOCAL_CFLAGS += -DCORKSCREW_HAVE_ARCH
LOCAL_STATIC_LIBRARIES += libcutils liblog
LOCAL_LDLIBS += -ldl
ifeq ($(HOST_OS),linux)
  LOCAL_SHARED_LIBRARIES += libgccdemangle # TODO: is this even needed on Linux?
  LOCAL_LDLIBS += -lrt
endif
LOCAL_CFLAGS += -std=gnu99 -Werror -Wno-unused-parameter
LOCAL_MODULE := libcorkscrew
LOCAL_MODULE_TAGS := optional
include $(BUILD_HOST_SHARED_LIBRARY)

# Build test.
include $(CLEAR_VARS)
LOCAL_SRC_FILES := test.cpp
LOCAL_CFLAGS += -Werror
LOCAL_SHARED_LIBRARIES := libcorkscrew
LOCAL_MODULE := libcorkscrew_test
LOCAL_MODULE_TAGS := optional
include $(BUILD_HOST_EXECUTABLE)

endif # $(HOST_OS)-$(HOST_ARCH) == linux-x86
+0 −0

Empty file deleted.

Loading