1
0

CrashHandler_MacOS.mm 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /******************************************************************************
  2. Copyright (C) 2025 by Patrick Heyer <[email protected]>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ******************************************************************************/
  14. @import Foundation;
  15. #import "CrashHandler.hpp"
  16. namespace {
  17. NSURL *getDiagnosticReportsDirectory()
  18. {
  19. NSFileManager *fileManager = [NSFileManager defaultManager];
  20. NSArray<NSURL *> *libraryURLs = [fileManager URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask];
  21. if (libraryURLs.count == 0) {
  22. blog(LOG_ERROR, "Unable to get macOS user library directory URL");
  23. return nil;
  24. }
  25. NSURL *diagnosticsReportsURL = [libraryURLs[0] URLByAppendingPathComponent:@"logs/DiagnosticReports"];
  26. return diagnosticsReportsURL;
  27. }
  28. } // namespace
  29. namespace OBS {
  30. PlatformType CrashHandler::getPlatformType() const
  31. {
  32. return PlatformType::macOS;
  33. }
  34. std::filesystem::path CrashHandler::findLastCrashLog() const
  35. {
  36. std::filesystem::path crashLogDirectoryPath;
  37. NSURL *diagnosticsReportsURL = getDiagnosticReportsDirectory();
  38. if (!diagnosticsReportsURL) {
  39. return crashLogDirectoryPath;
  40. }
  41. BOOL (^enumerationErrorHandler)(NSURL *_Nonnull, NSError *_Nonnull) =
  42. ^BOOL(NSURL *_Nonnull url __unused, NSError *_Nonnull error) {
  43. blog(LOG_ERROR, "Failed to enumerate diagnostics reports directory: %s",
  44. error.localizedDescription.UTF8String);
  45. return NO;
  46. };
  47. NSFileManager *fileManager = [NSFileManager defaultManager];
  48. NSDirectoryEnumerator *dirEnumerator = [fileManager
  49. enumeratorAtURL:diagnosticsReportsURL
  50. includingPropertiesForKeys:@[NSURLNameKey, NSURLIsDirectoryKey]
  51. options:(NSDirectoryEnumerationSkipsHiddenFiles) errorHandler:enumerationErrorHandler];
  52. NSMutableArray<NSURL *> *reportCandidates = [NSMutableArray array];
  53. for (NSURL *entry in dirEnumerator) {
  54. NSString *fileName = nil;
  55. [entry getResourceValue:&fileName forKey:NSURLNameKey error:nil];
  56. if ([fileName hasPrefix:@"OBS"] && [fileName hasSuffix:@".ips"]) {
  57. [reportCandidates addObject:entry];
  58. }
  59. }
  60. NSArray<NSURL *> *sortedCandidates = [reportCandidates
  61. sortedArrayUsingComparator:^NSComparisonResult(NSURL *_Nonnull obj1, NSURL *_Nonnull obj2) {
  62. NSDate *creationDateObj1 = nil;
  63. NSDate *creationDateObj2 = nil;
  64. [obj1 getResourceValue:&creationDateObj1 forKey:NSURLCreationDateKey error:nil];
  65. [obj2 getResourceValue:&creationDateObj2 forKey:NSURLCreationDateKey error:nil];
  66. NSComparisonResult result = [creationDateObj2 compare:creationDateObj1];
  67. return result;
  68. }];
  69. if (sortedCandidates.count > 0) {
  70. NSURL *lastDiagnosticsReport = sortedCandidates[0];
  71. crashLogDirectoryPath = std::filesystem::u8path(lastDiagnosticsReport.path.UTF8String);
  72. }
  73. return crashLogDirectoryPath;
  74. }
  75. std::filesystem::path CrashHandler::getCrashLogDirectory() const
  76. {
  77. std::filesystem::path crashLogDirectoryPath;
  78. NSURL *diagnosticsReportsURL = getDiagnosticReportsDirectory();
  79. if (diagnosticsReportsURL) {
  80. crashLogDirectoryPath = std::filesystem::u8path(diagnosticsReportsURL.path.UTF8String);
  81. }
  82. return crashLogDirectoryPath;
  83. }
  84. } // namespace OBS