llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.h
jimingham 85d94e1714
Make StopInfoMachException return the right data. (#180088)
When I changed lldb so that the StopInfo's compute their own stop reason
data (before it was oddly done in SBThread::GetStopReasonData...) I
didn't notice that StopInfoMachException was relying on that routine's
default of returning the Value as the 0th exception data, and didn't
actually return its own data.
This fixes that, and makes us report the exception type, and the code
and subcode if the exception has them. I also added a test for this.

rdar://169755672
2026-02-06 11:27:33 -08:00

110 lines
3.7 KiB
C++

//===-- StopInfoMachException.h ---------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_STOPINFOMACHEXCEPTION_H
#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_STOPINFOMACHEXCEPTION_H
#include <algorithm>
#include <optional>
#include <string>
#include "lldb/Target/StopInfo.h"
#if defined(__APPLE__)
// Needed for the EXC_* defines
#include <mach/exception.h>
#endif
namespace lldb_private {
class StopInfoMachException : public StopInfo {
/// Determine the pointer-authentication related failure that caused this
/// exception. Returns true and fills out the failure description if there
/// is auth-related failure, and returns false otherwise.
bool DeterminePtrauthFailure(ExecutionContext &exe_ctx);
bool DetermineTagMismatch();
public:
// Constructors and Destructors
StopInfoMachException(Thread &thread, uint32_t exc_type,
uint32_t exc_data_count, uint64_t exc_code,
uint64_t exc_subcode,
bool not_stepping_but_got_singlestep_exception)
: StopInfo(thread, exc_type), m_exc_data_count(exc_data_count),
m_exc_code(exc_code), m_exc_subcode(exc_subcode),
m_not_stepping_but_got_singlestep_exception(
not_stepping_but_got_singlestep_exception) {}
~StopInfoMachException() override = default;
lldb::StopReason GetStopReason() const override {
return lldb::eStopReasonException;
}
const char *GetDescription() override;
uint32_t GetStopReasonDataCount() const override {
// We return the Exception Type as the first element, then the code and
// subcode. But we don't store any further exception data, so we can't
// return more than these three elements regardless of the data count.
// Not many exceptions we deal with have more than code & subcode, however
// so fixing that isn't urgent.
return std::min((uint32_t)3, m_exc_data_count + 1);
}
uint64_t GetStopReasonDataAtIndex(uint32_t idx) override {
// FIXME: We really should return all the exception data, but for now we
// just cheese out and return only the exception type.
if (idx >= GetStopReasonDataCount())
return 0;
switch (idx) {
case 0:
return GetValue();
case 1:
return m_exc_code;
case 2:
return m_exc_subcode;
default:
return 0;
}
}
// Returns the fault address, iff this is a EXC_ARM_MTE_TAG_FAULT.
std::optional<lldb::addr_t> GetTagFaultAddress() const;
#if defined(__APPLE__)
struct MachException {
static const char *Name(exception_type_t exc_type);
static std::optional<exception_type_t> ExceptionCode(const char *name);
};
#endif
// Since some mach exceptions will be reported as breakpoints, signals,
// or trace, we use this static accessor which will translate the mach
// exception into the correct StopInfo.
static lldb::StopInfoSP CreateStopReasonWithMachException(
Thread &thread, uint32_t exc_type, uint32_t exc_data_count,
uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code,
bool pc_already_adjusted = true, bool adjust_pc_if_needed = false);
bool WasContinueInterrupted(Thread &thread) override;
protected:
uint32_t m_exc_data_count;
uint64_t m_exc_code;
uint64_t m_exc_subcode;
bool m_not_stepping_but_got_singlestep_exception;
};
} // namespace lldb_private
#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_STOPINFOMACHEXCEPTION_H