diff --git a/examples/darwin-framework-tool/BUILD.gn b/examples/darwin-framework-tool/BUILD.gn index 2c202475a70ea9..5e7b7d641030b8 100644 --- a/examples/darwin-framework-tool/BUILD.gn +++ b/examples/darwin-framework-tool/BUILD.gn @@ -209,6 +209,11 @@ executable("darwin-framework-tool") { "commands/discover/Commands.h", "commands/discover/DiscoverCommissionablesCommand.h", "commands/discover/DiscoverCommissionablesCommand.mm", + "commands/memory/Commands.h", + "commands/memory/DumpMemoryGraphCommand.h", + "commands/memory/DumpMemoryGraphCommand.mm", + "commands/memory/LeaksTool.h", + "commands/memory/LeaksTool.mm", "commands/pairing/Commands.h", "commands/pairing/DeviceControllerDelegateBridge.mm", "commands/pairing/GetCommissionerNodeIdCommand.h", diff --git a/examples/darwin-framework-tool/commands/memory/Commands.h b/examples/darwin-framework-tool/commands/memory/Commands.h new file mode 100644 index 00000000000000..d58d62db1cfe93 --- /dev/null +++ b/examples/darwin-framework-tool/commands/memory/Commands.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * 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. + * + */ + +#pragma once + +#include "commands/common/Commands.h" +#include "commands/memory/DumpMemoryGraphCommand.h" + +void registerCommandsMemory(Commands & commands) +{ + const char * clusterName = "memory"; + commands_list clusterCommands = { + make_unique(), + }; + + commands.RegisterCommandSet(clusterName, clusterCommands, "Commands for inspecting program memory."); +} diff --git a/examples/darwin-framework-tool/commands/memory/DumpMemoryGraphCommand.h b/examples/darwin-framework-tool/commands/memory/DumpMemoryGraphCommand.h new file mode 100644 index 00000000000000..aa46316beef414 --- /dev/null +++ b/examples/darwin-framework-tool/commands/memory/DumpMemoryGraphCommand.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * 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 "../common/CHIPCommandBridge.h" + +#include + +/** + * This command dump the memory graph of the program. + */ + +class DumpMemoryGraphCommand : public CHIPCommandBridge +{ +public: + DumpMemoryGraphCommand() : CHIPCommandBridge("dump-graph") + { + AddArgument("filepath", &mFilePath, "An optional filepath to save the memory graph to. Defaults to 'darwin-framework-tool.memgraph"); + } + + /////////// CHIPCommandBridge Interface ///////// + CHIP_ERROR RunCommand() override; + chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Milliseconds32(0); } + +private: + chip::Optional mFilePath; +}; diff --git a/examples/darwin-framework-tool/commands/memory/DumpMemoryGraphCommand.mm b/examples/darwin-framework-tool/commands/memory/DumpMemoryGraphCommand.mm new file mode 100644 index 00000000000000..15bb462f4c6554 --- /dev/null +++ b/examples/darwin-framework-tool/commands/memory/DumpMemoryGraphCommand.mm @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * 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 "DumpMemoryGraphCommand.h" + +#include "LeaksTool.h" + +CHIP_ERROR DumpMemoryGraphCommand::RunCommand() +{ + auto err = DumpMemoryGraph(mFilePath); + SetCommandExitStatus(err); + return err; +} diff --git a/examples/darwin-framework-tool/commands/memory/LeaksTool.h b/examples/darwin-framework-tool/commands/memory/LeaksTool.h new file mode 100644 index 00000000000000..101b437932b61b --- /dev/null +++ b/examples/darwin-framework-tool/commands/memory/LeaksTool.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * 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. + * + */ + +#pragma once + +#include + +CHIP_ERROR DumpMemoryGraph(chip::Optional filePath); +CHIP_ERROR PrintPools(); diff --git a/examples/darwin-framework-tool/commands/memory/LeaksTool.mm b/examples/darwin-framework-tool/commands/memory/LeaksTool.mm new file mode 100644 index 00000000000000..912134e163f956 --- /dev/null +++ b/examples/darwin-framework-tool/commands/memory/LeaksTool.mm @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * 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 "LeaksTool.h" + +#import +#include // For getpid() + +constexpr const char * kDefaultOutputGraphPath = "darwin-framework-tool.memgraph"; + +@interface LeaksTool : NSObject +- (BOOL)runWithArguments:(NSArray * _Nullable)arguments; +@end + +@implementation LeaksTool + +- (BOOL)runWithArguments:(NSArray * _Nullable)arguments +{ + pid_t pid = getpid(); + __auto_type * pidString = [NSString stringWithFormat:@"%d", pid]; + + __auto_type * task = [[NSTask alloc] init]; + task.launchPath = @"/usr/bin/leaks"; + task.arguments = @[ pidString ]; + if (arguments) { + task.arguments = [task.arguments arrayByAddingObjectsFromArray:arguments]; + } + + __auto_type * pipe = [NSPipe pipe]; + task.standardOutput = pipe; + task.standardError = pipe; + + __auto_type * fileHandle = [pipe fileHandleForReading]; + [task launch]; + [task waitUntilExit]; + + int exitCode = [task terminationStatus]; + if (exitCode != EXIT_SUCCESS) { + return NO; + } + + __auto_type * data = [fileHandle readDataToEndOfFile]; + __auto_type * output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + NSLog(@"%@", output); + + return YES; +} + +@end + +CHIP_ERROR DumpMemoryGraph(chip::Optional filePath) +{ + NSMutableString * outputGraphArgument = [NSMutableString stringWithFormat:@"--outputGraph=%s", kDefaultOutputGraphPath]; + if (filePath.HasValue()) { + outputGraphArgument = [NSMutableString stringWithFormat:@"--outputGraph=%s", filePath.Value()]; + } + + __auto_type * leaksTool = [[LeaksTool alloc] init]; + if (![leaksTool runWithArguments:@[ outputGraphArgument ]]) { + return CHIP_ERROR_INTERNAL; + } + + return CHIP_NO_ERROR; +} diff --git a/examples/darwin-framework-tool/main.mm b/examples/darwin-framework-tool/main.mm index ad31cfe32ee1cc..e0c6e94224ebec 100644 --- a/examples/darwin-framework-tool/main.mm +++ b/examples/darwin-framework-tool/main.mm @@ -27,6 +27,7 @@ #include "commands/delay/Commands.h" #include "commands/discover/Commands.h" #include "commands/interactive/Commands.h" +#include "commands/memory/Commands.h" #include "commands/pairing/Commands.h" #include "commands/payload/Commands.h" #include "commands/provider/Commands.h" @@ -46,6 +47,7 @@ int main(int argc, const char * argv[]) registerCommandsDelay(commands); registerCommandsDiscover(commands); registerCommandsInteractive(commands); + registerCommandsMemory(commands); registerCommandsPayload(commands); registerClusterOtaSoftwareUpdateProviderInteractive(commands); registerCommandsStorage(commands);