-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
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
Split OS::execute into two methods #44514
Conversation
e2b986e
to
3159077
Compare
1. execute(): Executes a command and returns the results. 2. create_process(): Creates a new process and returns the new process' id.
3159077
to
2a74b38
Compare
Rebased following merge of #44645. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, I don't have much experience with the Windows part, but the unix part seems good. Great job 🥇
@@ -617,7 +617,7 @@ MainLoop *test() { | |||
|
|||
List<String> args; | |||
args.push_back("-l"); | |||
Error err = OS::get_singleton()->execute("/bin/ls", args, true, nullptr, &ret); | |||
Error err = OS::get_singleton()->execute("/bin/ls", args, &ret); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure why this is here, but it's fine for now should probably be re-evaluated in a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! |
fprintf(stderr, "**ERROR** OS_Unix::execute - Could not create child process while executing: %s\n", p_path.utf8().get_data()); | ||
raise(SIGKILL); | ||
// The execvp() function only returns if an error occurs. | ||
CRASH_NOW_MSG("Could not create child process: " + p_path); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CRASH_NOW_MSG()
calls __builtin_trap()
. Although __builtin_trap()
is implementation dependent, it should raise a SIGTRAP
(to generate a stack trace if there is one) and then raise SIGKILL
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not triggering "Godot quit unexpectedly", but, unlike SIGKILL
generating a completely useless crash log twice (once it's generated by crash_handler_osx.mm
and redirected to null, and second time by OS crash handler).
Click to expand crash log
Exception Type: EXC_BAD_INSTRUCTION (SIGABRT)
Exception Codes: 0x0000000000000001, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Application Specific Information:
*** multi-threaded process forked ***
crashed on child side of fork pre-exec
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x00007fff2039f462 __pthread_kill + 10
1 libsystem_pthread.dylib 0x00007fff203cd610 pthread_kill + 263
2 libsystem_c.dylib 0x00007fff20320720 abort + 120
3 godot.osx.tools.x86_64 0x000000010068c71c handle_crash(int) + 2908 (crash_handler_osx.mm:153)
4 libsystem_platform.dylib 0x00007fff20411d7d _sigtramp + 29
5 ??? 0x00007ffeef56fd18 0 + 140732913876248
6 godot.osx.tools.x86_64 0x00000001046010e4 _OS::create_process(String const&, Vector<String> const&) + 228 (core_bind.cpp:252)
7 godot.osx.tools.x86_64 0x0000000104636aa6 void call_with_variant_args_ret_helper<__UnexistingClass, int, String const&, Vector<String> const&, 0ul, 1ul>(__UnexistingClass*, int (__UnexistingClass::*)(String const&, Vector<String> const&), Variant const**, Variant&, Callable::CallError&, IndexSequence<0ul, 1ul>) + 262 (binder_common.h:562)
8 godot.osx.tools.x86_64 0x000000010463696e void call_with_variant_args_ret_dv<__UnexistingClass, int, String const&, Vector<String> const&>(__UnexistingClass*, int (__UnexistingClass::*)(String const&, Vector<String> const&), Variant const**, int, Variant&, Callable::CallError&, Vector<Variant> const&) + 350 (binder_common.h:397)
9 godot.osx.tools.x86_64 0x0000000104636704 MethodBindTR<int, String const&, Vector<String> const&>::call(Object*, Variant const**, int, Callable::CallError&) + 228 (method_bind.h:451)
10 godot.osx.tools.x86_64 0x0000000104bd787e Object::call(StringName const&, Variant const**, int, Callable::CallError&) + 1038 (object.cpp:784)
11 godot.osx.tools.x86_64 0x000000010493f14a Variant::call(StringName const&, Variant const**, int, Variant&, Callable::CallError&) + 746 (variant_call.cpp:611)
12 godot.osx.tools.x86_64 0x00000001014c8a8f GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Callable::CallError&, GDScriptFunction::CallState*) + 35711 (gdscript_vm.cpp:1372)
13 godot.osx.tools.x86_64 0x00000001013b3a04 GDScriptInstance::call(StringName const&, Variant const**, int, Callable::CallError&) + 180 (gdscript.cpp:1555)
14 godot.osx.tools.x86_64 0x0000000104c09cc1 ScriptInstance::call(StringName const&, Variant const&, Variant const&, Variant const&, Variant const&, Variant const&) + 273 (script_language.cpp:314)
15 godot.osx.tools.x86_64 0x00000001030bd50d Node::_notification(int) + 4285 (node.cpp:147)
16 godot.osx.tools.x86_64 0x0000000103027bfb Node::_notificationv(int, bool) + 155 (node.h:45)
17 godot.osx.tools.x86_64 0x0000000103027aaf CanvasItem::_notificationv(int, bool) + 63 (canvas_item.h:164)
18 godot.osx.tools.x86_64 0x00000001030279bf Control::_notificationv(int, bool) + 63 (control.h:47)
19 godot.osx.tools.x86_64 0x0000000104bd4b2b Object::notification(int, bool) + 59 (object.cpp:793)
20 godot.osx.tools.x86_64 0x00000001030beb58 Node::_propagate_ready() + 280 (node.cpp:188)
21 godot.osx.tools.x86_64 0x00000001030beaee Node::_propagate_ready() + 174 (node.cpp:180)
22 godot.osx.tools.x86_64 0x00000001030c4b37 Node::_set_tree(SceneTree*) + 167 (node.cpp:2561)
23 godot.osx.tools.x86_64 0x00000001030fbf1d SceneTree::initialize() + 45 (scene_tree.cpp:395)
24 godot.osx.tools.x86_64 0x000000010068ed22 OS_OSX::run() + 66 (os_osx.mm:315)
25 godot.osx.tools.x86_64 0x00000001006c23f2 main + 1090 (godot_main_osx.mm:79)
26 libdyld.dylib 0x00007fff203e8621 start + 1
Nothing terrible, but it's a half minute of fully loaded CPU core and 70 KB of wasted disk space for each failed call, with no apparent benefits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It also looks like it's raising a SIGABRT
, so yes, it makes sense to use the previous approach.
Currently,
OS::execute
does two different things depending on whether the third parameter (blocking
) istrue
or not. This PR splitsOS::execute
into two methods:execute()
: Executes a command and returns the results. The old defaultexecute
blocking
=true
method.create_process()
: Creates a new process and returns the new process' id. The oldexecute
blocking
=false
method.Note: It now also appends the shell output
String
to the providedoutput
Array
instead of overwriting it.Closes #19302.
Part of #16863.