Skip to content

runtime: expose the layout of SwiftError to LLDB #4204

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 11, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions stdlib/public/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ set(swift_runtime_sources
CygwinPort.cpp
Demangle.cpp
Enum.cpp
ErrorObjectConstants.cpp
ErrorObjectNative.cpp
Errors.cpp
Heap.cpp
Expand Down
12 changes: 12 additions & 0 deletions stdlib/public/runtime/ErrorObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ struct SwiftError : SwiftErrorHeader {
/// This member is only available for native Swift errors.
const WitnessTable *errorConformance;

#if SWIFT_OBJC_INTEROP
/// The base type that introduces the `Hashable` conformance.
/// This member is only available for native Swift errors.
/// This member is lazily-initialized.
Expand All @@ -89,6 +90,7 @@ struct SwiftError : SwiftErrorHeader {
/// This member is lazily-initialized.
/// Instead of using it directly, call `getHashableConformance()`.
mutable std::atomic<const hashable_support::HashableWitnessTable *> hashableConformance;
#endif

/// Get a pointer to the value contained inside the indirectly-referenced
/// box reference.
Expand Down Expand Up @@ -143,13 +145,15 @@ struct SwiftError : SwiftErrorHeader {
const WitnessTable *getErrorConformance() const { return errorConformance; }
#endif

#if SWIFT_OBJC_INTEROP
/// Get the base type that conforms to `Hashable`.
/// Returns NULL if the type does not conform.
const Metadata *getHashableBaseType() const;

/// Get the `Hashable` protocol witness table for the contained type.
/// Returns NULL if the type does not conform.
const hashable_support::HashableWitnessTable *getHashableConformance() const;
#endif

// Don't copy or move, please.
SwiftError(const SwiftError &) = delete;
Expand Down Expand Up @@ -229,6 +233,14 @@ const Metadata *getNSErrorMetadata();

#endif

SWIFT_RUNTIME_EXPORT
extern "C"
const size_t _swift_lldb_offsetof_SwiftError_typeMetadata;

SWIFT_RUNTIME_EXPORT
extern "C"
const size_t _swift_lldb_sizeof_SwiftError;

} // namespace swift

#endif
24 changes: 24 additions & 0 deletions stdlib/public/runtime/ErrorObjectConstants.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "ErrorObject.h"

using namespace swift;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winvalid-offsetof"
const size_t swift::_swift_lldb_offsetof_SwiftError_typeMetadata =
offsetof(SwiftError, type);
#pragma clang diagnostic pop

const size_t swift::_swift_lldb_sizeof_SwiftError = sizeof(SwiftError);

34 changes: 34 additions & 0 deletions test/1_stdlib/Runtime.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import Swift
import StdlibUnittest
import SwiftShims

#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
import Darwin
#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
import Glibc
#endif

@_silgen_name("swift_demangle")
public
Expand Down Expand Up @@ -496,6 +501,35 @@ Runtime.test("Struct layout with reference storage types") {
print(malkovich)
}

Runtime.test("SwiftError layout constants for LLDB") {
#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: -2)
#elseif os(Linux)
let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: 0)
#else
_UnimplementedError()
#endif

let offsetof_SwiftError_typeMetadata =
dlsym(RTLD_DEFAULT, "_swift_lldb_offsetof_SwiftError_typeMetadata")!
let sizeof_SwiftError =
dlsym(RTLD_DEFAULT, "_swift_lldb_sizeof_SwiftError")!
#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
#if arch(i386) || arch(arm)
expectEqual(20, offsetof_SwiftError_typeMetadata.load(as: UInt.self))
expectEqual(36, sizeof_SwiftError.load(as: UInt.self))
#else
expectEqual(40, offsetof_SwiftError_typeMetadata.load(as: UInt.self))
expectEqual(72, sizeof_SwiftError.load(as: UInt.self))
#endif
#elseif os(Linux)
expectEqual(16, offsetof_SwiftError_typeMetadata.load(as: UInt.self))
expectEqual(32, sizeof_SwiftError.load(as: UInt.self))
#else
_UnimplementedError()
#endif
}

var Reflection = TestSuite("Reflection")

func wrap1 (_ x: Any) -> Any { return x }
Expand Down