Skip to content

Commit

Permalink
Merge pull request #30 from cwakamo/prevent-recursive-logging-4.2
Browse files Browse the repository at this point in the history
[4.2] [PlaygroundLogger] Add checks in the logger entrypoints to prevent recursive logging.
  • Loading branch information
cwakamo authored Sep 9, 2018
2 parents 590bb63 + b357798 commit 7da6532
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 6 deletions.
34 changes: 33 additions & 1 deletion PlaygroundLogger/PlaygroundLogger.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@
5E5D77842040F5E900EBC3A9 /* LoggingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E5D77832040F5E900EBC3A9 /* LoggingError.swift */; };
5E5F600B20409D4E007EF0A8 /* LogPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E5F600A20409D4E007EF0A8 /* LogPolicy.swift */; };
5E5FE50B202D13C800E28C3C /* PGLConcurrentMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E5FE50A202D13C800E28C3C /* PGLConcurrentMap.swift */; };
5EB651C0213A01D0001CC984 /* LegacyEntrypointTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EB651BF213A01D0001CC984 /* LegacyEntrypointTests.swift */; };
5EB651C1213A01D0001CC984 /* LegacyEntrypointTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EB651BF213A01D0001CC984 /* LegacyEntrypointTests.swift */; };
5EB651C2213A01D0001CC984 /* LegacyEntrypointTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EB651BF213A01D0001CC984 /* LegacyEntrypointTests.swift */; };
5EB651C4213A081A001CC984 /* LoggerEntrypointTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EB651C3213A081A001CC984 /* LoggerEntrypointTests.swift */; };
5EB651C5213A081A001CC984 /* LoggerEntrypointTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EB651C3213A081A001CC984 /* LoggerEntrypointTests.swift */; };
5EB651C6213A081A001CC984 /* LoggerEntrypointTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EB651C3213A081A001CC984 /* LoggerEntrypointTests.swift */; };
5ECE8F911FFCD2A70034D9BC /* LegacyPlaygroundLoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5ECE8F901FFCD2A70034D9BC /* LegacyPlaygroundLoggerTests.swift */; };
5EE3867420352F3200D625F0 /* CGFloat+CustomOpaqueLoggable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EE3867320352F3200D625F0 /* CGFloat+CustomOpaqueLoggable.swift */; };
5EF581532041387C00AC14FE /* CustomPlaygroundDisplayConvertibleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EF581512041384700AC14FE /* CustomPlaygroundDisplayConvertibleTests.swift */; };
Expand All @@ -93,6 +99,8 @@
5EF6403E204148B80007BDD2 /* NSBezierPath+PGLKeyedArchivingUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EF6403C204148B80007BDD2 /* NSBezierPath+PGLKeyedArchivingUtilities.m */; settings = {COMPILER_FLAGS = "-fobjc-arc-exceptions"; }; };
5EF64041204149DE0007BDD2 /* UIBezierPath+PGLKeyedArchivingUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 5EF6403F204149DE0007BDD2 /* UIBezierPath+PGLKeyedArchivingUtilities.h */; settings = {ATTRIBUTES = (Public, ); }; };
5EF64042204149DE0007BDD2 /* UIBezierPath+PGLKeyedArchivingUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EF64040204149DE0007BDD2 /* UIBezierPath+PGLKeyedArchivingUtilities.m */; settings = {COMPILER_FLAGS = "-fobjc-arc-exceptions"; }; };
5EFB2A5321211BC300BA43D3 /* PGLThreadIsLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = 5EFB2A5121211BC300BA43D3 /* PGLThreadIsLogging.h */; settings = {ATTRIBUTES = (Public, ); }; };
5EFB2A5421211BC300BA43D3 /* PGLThreadIsLogging.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EFB2A5221211BC300BA43D3 /* PGLThreadIsLogging.m */; };
5EFE9193203F6CF900E21BAA /* LegacyPlaygroundLoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5ECE8F901FFCD2A70034D9BC /* LegacyPlaygroundLoggerTests.swift */; };
5EFE919B203F6DD700E21BAA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EFE919A203F6DD700E21BAA /* AppDelegate.swift */; };
5EFE919D203F6DD700E21BAA /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EFE919C203F6DD700E21BAA /* ViewController.swift */; };
Expand Down Expand Up @@ -260,6 +268,8 @@
5E5D77832040F5E900EBC3A9 /* LoggingError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggingError.swift; sourceTree = "<group>"; };
5E5F600A20409D4E007EF0A8 /* LogPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogPolicy.swift; sourceTree = "<group>"; };
5E5FE50A202D13C800E28C3C /* PGLConcurrentMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PGLConcurrentMap.swift; sourceTree = "<group>"; };
5EB651BF213A01D0001CC984 /* LegacyEntrypointTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyEntrypointTests.swift; sourceTree = "<group>"; };
5EB651C3213A081A001CC984 /* LoggerEntrypointTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggerEntrypointTests.swift; sourceTree = "<group>"; };
5ECE8F901FFCD2A70034D9BC /* LegacyPlaygroundLoggerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyPlaygroundLoggerTests.swift; sourceTree = "<group>"; };
5EE3867320352F3200D625F0 /* CGFloat+CustomOpaqueLoggable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGFloat+CustomOpaqueLoggable.swift"; sourceTree = "<group>"; };
5EF581512041384700AC14FE /* CustomPlaygroundDisplayConvertibleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomPlaygroundDisplayConvertibleTests.swift; sourceTree = "<group>"; };
Expand All @@ -269,6 +279,8 @@
5EF6403C204148B80007BDD2 /* NSBezierPath+PGLKeyedArchivingUtilities.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSBezierPath+PGLKeyedArchivingUtilities.m"; sourceTree = "<group>"; };
5EF6403F204149DE0007BDD2 /* UIBezierPath+PGLKeyedArchivingUtilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIBezierPath+PGLKeyedArchivingUtilities.h"; sourceTree = "<group>"; };
5EF64040204149DE0007BDD2 /* UIBezierPath+PGLKeyedArchivingUtilities.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIBezierPath+PGLKeyedArchivingUtilities.m"; sourceTree = "<group>"; };
5EFB2A5121211BC300BA43D3 /* PGLThreadIsLogging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PGLThreadIsLogging.h; sourceTree = "<group>"; };
5EFB2A5221211BC300BA43D3 /* PGLThreadIsLogging.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PGLThreadIsLogging.m; sourceTree = "<group>"; };
5EFE9189203F6CC400E21BAA /* PlaygroundLoggerTests_iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PlaygroundLoggerTests_iOS.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
5EFE918D203F6CC400E21BAA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
5EFE9198203F6DD700E21BAA /* PlaygroundLoggerTestHost_iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PlaygroundLoggerTestHost_iOS.app; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -354,6 +366,7 @@
5EFE91B1203F6E8D00E21BAA /* PlaygroundLoggerTestHost_tvOS */,
5E11805820414E0C00B73EE9 /* Config Files */,
5E2646281FB64876002DC6B6 /* Products */,
5EFB2A352121145E00BA43D3 /* Frameworks */,
);
sourceTree = "<group>";
};
Expand Down Expand Up @@ -400,6 +413,8 @@
5EF581512041384700AC14FE /* CustomPlaygroundDisplayConvertibleTests.swift */,
5E48E0A92042925B00C7712D /* LogEntryTests.swift */,
5E5D777F2040BD7D00EBC3A9 /* LogPolicyTests.swift */,
5EB651C3213A081A001CC984 /* LoggerEntrypointTests.swift */,
5EB651BF213A01D0001CC984 /* LegacyEntrypointTests.swift */,
5ECE8F901FFCD2A70034D9BC /* LegacyPlaygroundLoggerTests.swift */,
);
path = PlaygroundLoggerTests;
Expand Down Expand Up @@ -599,10 +614,19 @@
5E184716202BB80200F01AD1 /* PGLConcurrentMap.h */,
5E184717202BB80200F01AD1 /* PGLConcurrentMap_MRR.m */,
5E5FE50A202D13C800E28C3C /* PGLConcurrentMap.swift */,
5EFB2A5121211BC300BA43D3 /* PGLThreadIsLogging.h */,
5EFB2A5221211BC300BA43D3 /* PGLThreadIsLogging.m */,
);
path = Utilities;
sourceTree = "<group>";
};
5EFB2A352121145E00BA43D3 /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
5EFE918A203F6CC400E21BAA /* PlaygroundLoggerTests_iOS */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -651,6 +675,7 @@
files = (
5E184718202BB80200F01AD1 /* PGLConcurrentMap.h in Headers */,
5EF64041204149DE0007BDD2 /* UIBezierPath+PGLKeyedArchivingUtilities.h in Headers */,
5EFB2A5321211BC300BA43D3 /* PGLThreadIsLogging.h in Headers */,
5EF6403D204148B80007BDD2 /* NSBezierPath+PGLKeyedArchivingUtilities.h in Headers */,
5EF64039204145A80007BDD2 /* NSAttributedString+PGLKeyedArchivingUtilities.h in Headers */,
5E2646381FB64876002DC6B6 /* PlaygroundLogger.h in Headers */,
Expand Down Expand Up @@ -778,7 +803,7 @@
5E26461E1FB64876002DC6B6 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0930;
LastSwiftUpdateCheck = 1000;
LastUpgradeCheck = 0910;
ORGANIZATIONNAME = "Apple Inc. and the Swift project authors";
TargetAttributes = {
Expand Down Expand Up @@ -952,6 +977,7 @@
5E2755CF1FB657F200B69C83 /* LogEntry.swift in Sources */,
5E2756221FC4873000B69C83 /* UInt64+TaggedOpaqueRepresentation.swift in Sources */,
5E2756281FC4895100B69C83 /* Double+TaggedOpaqueRepresentation.swift in Sources */,
5EFB2A5421211BC300BA43D3 /* PGLThreadIsLogging.m in Sources */,
5E2756481FC4DE1500B69C83 /* NSView+OpaqueImageRepresentable.swift in Sources */,
5E2755D31FB672DC00B69C83 /* SendData.swift in Sources */,
5E27567E1FCF429900B69C83 /* NSCursor+CustomOpaqueLoggable.swift in Sources */,
Expand All @@ -964,6 +990,8 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
5EB651C0213A01D0001CC984 /* LegacyEntrypointTests.swift in Sources */,
5EB651C4213A081A001CC984 /* LoggerEntrypointTests.swift in Sources */,
5E5D77802040BD7D00EBC3A9 /* LogPolicyTests.swift in Sources */,
5E48E0AA2042925B00C7712D /* LogEntryTests.swift in Sources */,
5EF581532041387C00AC14FE /* CustomPlaygroundDisplayConvertibleTests.swift in Sources */,
Expand All @@ -975,6 +1003,8 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
5EB651C1213A01D0001CC984 /* LegacyEntrypointTests.swift in Sources */,
5EB651C5213A081A001CC984 /* LoggerEntrypointTests.swift in Sources */,
5E5D77812040BD7D00EBC3A9 /* LogPolicyTests.swift in Sources */,
5E48E0AB2042925B00C7712D /* LogEntryTests.swift in Sources */,
5EF581542041387C00AC14FE /* CustomPlaygroundDisplayConvertibleTests.swift in Sources */,
Expand Down Expand Up @@ -1004,6 +1034,8 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
5EB651C2213A01D0001CC984 /* LegacyEntrypointTests.swift in Sources */,
5EB651C6213A081A001CC984 /* LoggerEntrypointTests.swift in Sources */,
5E5D77822040BD7D00EBC3A9 /* LogPolicyTests.swift in Sources */,
5E48E0AC2042925B00C7712D /* LogEntryTests.swift in Sources */,
5EF581552041387C00AC14FE /* CustomPlaygroundDisplayConvertibleTests.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ fileprivate func legacySendDataStub(_: NSData) -> Void {
}

@_silgen_name("playground_log_hidden")
public func legacyLog<T>(instance: T, name: String, id: Int, startLine: Int, endLine: Int, startColumn: Int, endColumn: Int) -> AnyObject {
public func legacyLog<T>(instance: T, name: String, id: Int, startLine: Int, endLine: Int, startColumn: Int, endColumn: Int) -> AnyObject? {
guard !PGLGetThreadIsLogging() else { return nil }
PGLSetThreadIsLogging(true)
defer { PGLSetThreadIsLogging(false) }

let packet = LogPacket(describingResult: instance, named: name, withPolicy: .default, startLine: startLine, endLine: endLine, startColumn: startColumn, endColumn: endColumn)

let data: Data
Expand Down Expand Up @@ -68,7 +72,11 @@ public func legacyLog<T>(instance: T, name: String, id: Int, startLine: Int, end
}

@_silgen_name ("playground_log_scope_entry")
public func legacyLogScopeEntry(startLine: Int, endLine: Int, startColumn: Int, endColumn: Int) -> AnyObject {
public func legacyLogScopeEntry(startLine: Int, endLine: Int, startColumn: Int, endColumn: Int) -> AnyObject? {
guard !PGLGetThreadIsLogging() else { return nil }
PGLSetThreadIsLogging(true)
defer { PGLSetThreadIsLogging(false) }

let packet = LogPacket(scopeEntryWithStartLine: startLine, endLine: endLine, startColumn: startColumn, endColumn: endColumn)

// Encoding a scope entry packet should not fail under any circumstances.
Expand All @@ -78,7 +86,11 @@ public func legacyLogScopeEntry(startLine: Int, endLine: Int, startColumn: Int,
}

@_silgen_name ("playground_log_scope_exit")
public func legacyLogScopeExit(startLine: Int, endLine: Int, startColumn: Int, endColumn: Int) -> AnyObject {
public func legacyLogScopeExit(startLine: Int, endLine: Int, startColumn: Int, endColumn: Int) -> AnyObject? {
guard !PGLGetThreadIsLogging() else { return nil }
PGLSetThreadIsLogging(true)
defer { PGLSetThreadIsLogging(false) }

let packet = LogPacket(scopeExitWithStartLine: startLine, endLine: endLine, startColumn: startColumn, endColumn: endColumn)

// Encoding a scope exit packet should not fail under any circumstances.
Expand All @@ -88,7 +100,11 @@ public func legacyLogScopeExit(startLine: Int, endLine: Int, startColumn: Int, e
}

@_silgen_name ("playground_log_postprint")
public func legacyLogPostPrint(startLine: Int, endLine: Int, startColumn: Int, endColumn: Int) -> AnyObject {
public func legacyLogPostPrint(startLine: Int, endLine: Int, startColumn: Int, endColumn: Int) -> AnyObject? {
guard !PGLGetThreadIsLogging() else { return nil }
PGLSetThreadIsLogging(true)
defer { PGLSetThreadIsLogging(false) }

let printedString = Thread.current.threadDictionary[printedStringThreadDictionaryKey] as! String? ?? ""

Thread.current.threadDictionary.removeObject(forKey: printedStringThreadDictionaryKey)
Expand Down
19 changes: 19 additions & 0 deletions PlaygroundLogger/PlaygroundLogger/LoggerEntrypoints.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ func logResult(_ result: Any,
endLine: Int,
startColumn: Int,
endColumn: Int) {
guard !PGLGetThreadIsLogging() else { return }
PGLSetThreadIsLogging(true)
defer { PGLSetThreadIsLogging(false) }

let packet = LogPacket(describingResult: result, named: name, withPolicy: .default, startLine: startLine, endLine: endLine, startColumn: startColumn, endColumn: endColumn)

let data: Data
Expand Down Expand Up @@ -54,6 +58,10 @@ func logScopeEntry(startLine: Int,
endLine: Int,
startColumn: Int,
endColumn: Int) {
guard !PGLGetThreadIsLogging() else { return }
PGLSetThreadIsLogging(true)
defer { PGLSetThreadIsLogging(false) }

let packet = LogPacket(scopeEntryWithStartLine: startLine, endLine: endLine, startColumn: startColumn, endColumn: endColumn)

// Encoding a scope entry packet should not fail under any circumstances.
Expand All @@ -66,6 +74,10 @@ func logScopeExit(startLine: Int,
endLine: Int,
startColumn: Int,
endColumn: Int) {
guard !PGLGetThreadIsLogging() else { return }
PGLSetThreadIsLogging(true)
defer { PGLSetThreadIsLogging(false) }

let packet = LogPacket(scopeExitWithStartLine: startLine, endLine: endLine, startColumn: startColumn, endColumn: endColumn)

// Encoding a scope exit packet should not fail under any circumstances.
Expand All @@ -77,13 +89,20 @@ func logScopeExit(startLine: Int,
let printedStringThreadDictionaryKey: NSString = "org.swift.PlaygroundLogger.printedString"

func printHook(string: String) {
// Don't store the printed string if we're already logging elsewhere in this thread.
guard !PGLGetThreadIsLogging() else { return }

Thread.current.threadDictionary[printedStringThreadDictionaryKey] = string as NSString
}

func logPostPrint(startLine: Int,
endLine: Int,
startColumn: Int,
endColumn: Int) {
guard !PGLGetThreadIsLogging() else { return }
PGLSetThreadIsLogging(true)
defer { PGLSetThreadIsLogging(false) }

guard let printedString = Thread.current.threadDictionary[printedStringThreadDictionaryKey] as! String? else {
return
}
Expand Down
1 change: 1 addition & 0 deletions PlaygroundLogger/PlaygroundLogger/PlaygroundLogger.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ FOUNDATION_EXPORT double PlaygroundLoggerVersionNumber;
FOUNDATION_EXPORT const unsigned char PlaygroundLoggerVersionString[];

#import <PlaygroundLogger/PGLConcurrentMap.h>
#import <PlaygroundLogger/PGLThreadIsLogging.h>

#import <PlaygroundLogger/NSAttributedString+PGLKeyedArchivingUtilities.h>
#import <PlaygroundLogger/NSBezierPath+PGLKeyedArchivingUtilities.h>
Expand Down
2 changes: 1 addition & 1 deletion PlaygroundLogger/PlaygroundLogger/SendData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import Foundation

fileprivate func unsetSendData(_: NSData) {
internal /*testable*/ func unsetSendData(_: NSData) {
fatalError("PlaygroundLogger not initialized")
}

Expand Down
37 changes: 37 additions & 0 deletions PlaygroundLogger/PlaygroundLogger/Utilities/PGLThreadIsLogging.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//===--- PGLThreadIsLogging.h ---------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2018 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
//
//===----------------------------------------------------------------------===//

#import <sys/cdefs.h>
#import <stdbool.h>

__BEGIN_DECLS

/// A thread-local `bool` which indicates whether or not the current thread is
/// logging.
///
/// This is used by the functions in LoggerEntrypoints.swift and
/// LegacyEntrypoints.swift to prevent generating log packets while already
/// generating a log packet. It means the side-effects of logging are not
/// themselves logged.
extern __thread bool PGLThreadIsLogging;

/// A helper function to get the value of `PGLThreadIsLogging` safely from Swift.
static inline bool PGLGetThreadIsLogging(void) {
return PGLThreadIsLogging;
}

/// A helper function to set the value of `PGLThreadIsLogging` safely from Swift.
static inline void PGLSetThreadIsLogging(bool threadIsLogging) {
PGLThreadIsLogging = threadIsLogging;
}

__END_DECLS
15 changes: 15 additions & 0 deletions PlaygroundLogger/PlaygroundLogger/Utilities/PGLThreadIsLogging.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//===--- PGLThreadIsLogging.m ---------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2018 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
//
//===----------------------------------------------------------------------===//

#import <PlaygroundLogger/PGLThreadIsLogging.h>

__thread bool PGLThreadIsLogging = false;
Loading

0 comments on commit 7da6532

Please sign in to comment.