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

Commit 2317287d authored by Christopher Ferris's avatar Christopher Ferris Committed by Gerrit Code Review
Browse files

Merge "Remove libcorkscrew."

parents da7409da 688a8a72
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