Compare commits

..
15 Commits
Author SHA1 Message Date
Ole André Vadla Ravnås f67d1e81df Dump alive tasks every 30s in server and agent
Route the dump through GLib.info() using the new
g_task_describe_alive_tasks(), so the agent's dump reaches
logcat where its stdio is not visible. Bump the GLib wrap to
the branch holding that function.
2026-07-29 18:12:10 +02:00
Ole André Vadla Ravnås a068c704d1 Trace agent session detach notification path
Log every hop that agent_session_detached has to survive, from
the agent emitting closed, through frida-server's provider and
control channel, the droidy relay, and finally Device's pending
detach request. Each silent id-keyed drop now reports whether
the lookup succeeded, so a hanging detach() points straight at
the hop that swallowed the notification.
2026-07-29 17:47:25 +02:00
Ole André Vadla Ravnås 34ac3a0d50 server: Add output redirection option
Add -o/--output for redirecting stdout and stderr to a file,
so output survives daemonizing. Skip the stdin debug console
when daemonized, as stdin is then /dev/null.
2026-07-29 15:10:37 +02:00
Ole André Vadla Ravnås 1ea81bcd59 server: Add stdin-based task debug console 2026-07-28 14:47:05 +02:00
Ole André Vadla Ravnås 0e1a53ba7a subprojects: Prepare for release 2026-07-22 00:30:06 +02:00
Ole André Vadla Ravnås bae82ee212 subprojects: Bump outdated 2026-07-22 00:28:46 +02:00
Ole André Vadla Ravnås 5d714719bc subprojects: Prepare for release 2026-07-20 17:55:53 +02:00
Ole André Vadla Ravnås 1d68703132 subprojects: Bump outdated 2026-07-20 17:46:45 +02:00
Ole André Vadla Ravnås afba4699c1 subprojects: Prepare for release 2026-07-19 22:25:17 +02:00
Ole André Vadla Ravnås 8a3afe7c37 subprojects: Bump outdated 2026-07-19 22:24:20 +02:00
Ole André Vadla Ravnås 5ed252adad linux: Stop helper inheriting embedder stdio
For stdio=inherit, pass the host's streams to the helper with each
spawn; with that in place, redirect the helper's own 0/1/2 to
/dev/null at launch so it no longer holds the embedder's pipes.
2026-07-19 22:20:24 +02:00
Ole André Vadla Ravnås 195c6b0618 darwin: Stop helper inheriting embedder stdio
For stdio=inherit, pass the host's streams to the helper with each
spawn; with that in place, redirect the helper's own 0/1/2 to
/dev/null at launch so it no longer holds the embedder's pipes.
2026-07-19 22:20:24 +02:00
Ole André Vadla Ravnås 5934b352b3 subprojects: Prepare for release 2026-07-18 13:30:24 +02:00
Ole André Vadla Ravnås 62f0b50694 subprojects: Bump outdated 2026-07-18 13:29:03 +02:00
Ole André Vadla Ravnås 405fb10d1e submodules: Bump releng 2026-07-18 13:29:02 +02:00
23 changed files with 235 additions and 36 deletions

No files matched your search

+18
View File
@@ -292,6 +292,8 @@ namespace Frida.Agent {
start.begin ((owned) padder);
start_alive_task_dumper ();
main_loop.run ();
main_context.pop_thread_default ();
@@ -362,6 +364,16 @@ namespace Frida.Agent {
padder = null;
}
// TEMPORARY DEBUG HACK: dump alive GTasks every 30 seconds.
private void start_alive_task_dumper () {
var source = new TimeoutSource.seconds (30);
source.set_callback (() => {
GLib.info ("%s", g_task_describe_alive_tasks ());
return Source.CONTINUE;
});
source.attach (main_context);
}
private void keep_running_eternalized () {
agent_gthread = new Thread<bool> ("frida-eternal-agent", () => {
var ignore_scope = new ThreadIgnoreScope (FRIDA_THREAD);
@@ -924,6 +936,8 @@ namespace Frida.Agent {
private void on_session_closed (BaseAgentSession base_session) {
LiveAgentSession session = (LiveAgentSession) base_session;
GLib.info ("detach-trace: Agent emitting provider closed id=%s", session.id.handle);
closed (session.id);
unregister_session (session);
@@ -1724,4 +1738,8 @@ namespace Frida.Agent {
return repeat;
});
}
// TEMPORARY DEBUG HACK: only present when GLib is built with G_ENABLE_DEBUG.
[CCode (cname = "g_task_describe_alive_tasks")]
private extern string g_task_describe_alive_tasks ();
}
+3
View File
@@ -361,6 +361,8 @@ namespace Frida {
private async void teardown_peer_connection_and_emit_closed () {
schedule_on_frida_thread (() => {
GLib.info ("detach-trace: AgentMessageTransmitter %p emitting closed, nice_agent=%p",
this, nice_agent);
if (nice_agent != null)
close_nice_resources_and_emit_closed.begin ();
else
@@ -598,6 +600,7 @@ namespace Frida {
private async void teardown_peer_connection_and_emit_closed () {
schedule_on_frida_thread (() => {
GLib.info ("detach-trace: AgentMessageTransmitter %p emitting closed", this);
closed ();
return Source.REMOVE;
});
+6
View File
@@ -57,6 +57,8 @@ namespace Frida {
}
public async void close (Cancellable? cancellable) throws IOError {
GLib.info ("detach-trace: BaseAgentSession.close() id=%s close_request=%p", id.handle, close_request);
while (close_request != null) {
try {
yield close_request.future.wait_async (cancellable);
@@ -85,6 +87,8 @@ namespace Frida {
yield transmitter.close (cancellable);
GLib.info ("detach-trace: BaseAgentSession.close() done id=%s", id.handle);
close_request.resolve (true);
}
@@ -276,6 +280,8 @@ namespace Frida {
transmitter.new_candidates.disconnect (on_transmitter_new_candidates);
transmitter.candidate_gathering_done.disconnect (on_transmitter_candidate_gathering_done);
GLib.info ("detach-trace: BaseAgentSession emitting closed id=%s", id.handle);
closed ();
}
+1 -1
Submodule releng updated: f3c2f0efbf...abb8238970.
+87 -4
View File
@@ -12,6 +12,7 @@ namespace Frida.Server {
private static string? directory = null;
#if !WINDOWS && !TVOS
private static bool daemonize = false;
private static string? output_path = null;
#endif
private static string? softener_flavor_str = null;
private static bool enable_preload = true;
@@ -42,6 +43,7 @@ namespace Frida.Server {
{ "directory", 'd', 0, OptionArg.STRING, ref directory, "Store binaries in DIRECTORY", "DIRECTORY" },
#if !WINDOWS && !TVOS
{ "daemonize", 'D', 0, OptionArg.NONE, ref daemonize, "Detach and become a daemon", null },
{ "output", 'o', 0, OptionArg.FILENAME, ref output_path, "Redirect output to FILE", "FILE" },
#endif
{ "policy-softener", 0, 0, OptionArg.STRING, ref softener_flavor_str, "Select policy softener", "system|internal" },
{ "disable-preload", 'P', OptionFlags.REVERSE, OptionArg.NONE, ref enable_preload, "Disable preload optimization", null },
@@ -78,6 +80,13 @@ namespace Frida.Server {
Environment.set_verbose_logging_enabled (verbose);
#if !WINDOWS && !TVOS
if (output_path != null && !daemonize) {
if (!redirect_output_to (output_path))
return 6;
}
#endif
EndpointParameters endpoint_params;
try {
endpoint_params = new EndpointParameters (listen_address, 0, parse_certificate (certpath), origin,
@@ -156,12 +165,15 @@ namespace Frida.Server {
Posix.setsid ();
var null_in = Posix.open ("/dev/null", Posix.O_RDONLY);
var null_out = Posix.open ("/dev/null", Posix.O_WRONLY);
Posix.dup2 (null_in, Posix.STDIN_FILENO);
Posix.dup2 (null_out, Posix.STDOUT_FILENO);
Posix.dup2 (null_out, Posix.STDERR_FILENO);
Posix.close (null_in);
Posix.close (null_out);
if (output_path == null || !redirect_output_to (output_path)) {
var null_out = Posix.open ("/dev/null", Posix.O_WRONLY);
Posix.dup2 (null_out, Posix.STDOUT_FILENO);
Posix.dup2 (null_out, Posix.STDERR_FILENO);
Posix.close (null_out);
}
}
var status = new uint8[1];
@@ -218,6 +230,22 @@ namespace Frida.Server {
return application.run ();
}
#if !WINDOWS && !TVOS
private static bool redirect_output_to (string path) {
int fd = Posix.open (path, Posix.O_WRONLY | Posix.O_CREAT | Posix.O_APPEND, 0644);
if (fd == -1) {
printerr ("Unable to open “%s”: %s\n", path, Posix.strerror (Posix.errno));
return false;
}
Posix.dup2 (fd, Posix.STDOUT_FILENO);
Posix.dup2 (fd, Posix.STDERR_FILENO);
Posix.close (fd);
return true;
}
#endif
namespace Environment {
public extern void init ();
public extern void set_verbose_logging_enabled (bool enabled);
@@ -274,6 +302,15 @@ namespace Frida.Server {
return false;
});
#if !WINDOWS && !TVOS
if (!daemonize)
process_commands.begin ();
#elif !WINDOWS
process_commands.begin ();
#endif
start_alive_task_dumper ();
exit_code = 0;
loop.run ();
@@ -281,6 +318,45 @@ namespace Frida.Server {
return exit_code;
}
#if !WINDOWS
// TEMPORARY DEBUG HACK: type “t” + Enter to dump alive GTasks.
private async void process_commands () {
var input = new DataInputStream (new UnixInputStream (Posix.STDIN_FILENO, false));
while (true) {
string? line;
try {
line = yield input.read_line_async (Priority.DEFAULT, io_cancellable);
} catch (GLib.Error e) {
return;
}
if (line == null)
return;
switch (line.strip ()) {
case "t":
g_task_print_alive_tasks ();
break;
case "":
break;
default:
printerr ("Unknown command; try “t”\n");
break;
}
}
}
#endif
// TEMPORARY DEBUG HACK: dump alive GTasks every 30 seconds.
private void start_alive_task_dumper () {
var source = new TimeoutSource.seconds (30);
source.set_callback (() => {
GLib.info ("%s", g_task_describe_alive_tasks ());
return Source.CONTINUE;
});
source.attach (MainContext.default ());
}
private async void start () {
try {
if (device_id != null && device_id != "local") {
@@ -355,4 +431,11 @@ namespace Frida.Server {
return new TlsCertificate.from_file (path);
}
// TEMPORARY DEBUG HACK: only present when GLib is built with G_ENABLE_DEBUG.
[CCode (cname = "g_task_print_alive_tasks")]
private extern void g_task_print_alive_tasks ();
[CCode (cname = "g_task_describe_alive_tasks")]
private extern string g_task_describe_alive_tasks ();
}
+7 -6
View File
@@ -762,12 +762,13 @@ namespace Frida {
private void on_agent_session_detached (AgentSessionId id, SessionDetachReason reason, CrashInfo crash) {
AgentSessionEntry entry;
if (agent_sessions.unset (id, out entry)) {
ControlChannel? controller = entry.controller;
if (controller != null) {
controller.agent_sessions.remove (id);
controller.agent_session_detached (id, reason, crash);
}
bool entry_found = agent_sessions.unset (id, out entry);
ControlChannel? controller = entry_found ? entry.controller : null;
GLib.info ("detach-trace: ControlService session detached id=%s reason=%d entry_found=%s controller=%p",
id.handle, reason, entry_found.to_string (), controller);
if (controller != null) {
controller.agent_sessions.remove (id);
controller.agent_session_detached (id, reason, crash);
}
}
+10 -1
View File
@@ -230,7 +230,16 @@ namespace Frida {
return yield fruit_controller.spawn (path, options, cancellable);
#endif
return yield helper.spawn (path, options, cancellable);
UnixInputStream? stdin_stream = null;
UnixOutputStream? stdout_stream = null;
UnixOutputStream? stderr_stream = null;
if (options.stdio == INHERIT) {
stdin_stream = new UnixInputStream (0, false);
stdout_stream = new UnixOutputStream (1, false);
stderr_stream = new UnixOutputStream (2, false);
}
return yield helper.spawn (path, options, stdin_stream, stdout_stream, stderr_stream, cancellable);
}
protected override async void await_exec_transition (uint pid, Cancellable? cancellable) throws Error, IOError {
+13 -4
View File
@@ -7,6 +7,8 @@
#include <dlfcn.h>
#include <errno.h>
#import <Foundation/Foundation.h>
#include <gio/gunixinputstream.h>
#include <gio/gunixoutputstream.h>
#include <glib-unix.h>
#include <spawn.h>
#include <stdio.h>
@@ -793,7 +795,8 @@ _frida_darwin_helper_backend_schedule_on_dispatch_queue (FridaDarwinHelperBacken
guint
_frida_darwin_helper_backend_spawn (FridaDarwinHelperBackend * self, const gchar * path,
FridaHostSpawnOptions * options, FridaStdioPipes ** pipes, GError ** error)
FridaHostSpawnOptions * options, GUnixInputStream * stdin_stream, GUnixOutputStream * stdout_stream,
GUnixOutputStream * stderr_stream, FridaStdioPipes ** pipes, GError ** error)
{
pid_t pid;
FridaSpawnInstance * instance;
@@ -830,11 +833,17 @@ _frida_darwin_helper_backend_spawn (FridaDarwinHelperBackend * self, const gchar
if (stdio_error != NULL)
goto propagate_stdio_error;
if (in_fd != NULL)
if (stdin_stream != NULL)
posix_spawn_file_actions_adddup2 (&file_actions, g_unix_input_stream_get_fd (stdin_stream), 0);
else if (in_fd != NULL)
posix_spawn_file_actions_adddup2 (&file_actions, in_fd->handle, 0);
if (out_fd != NULL)
if (stdout_stream != NULL)
posix_spawn_file_actions_adddup2 (&file_actions, g_unix_output_stream_get_fd (stdout_stream), 1);
else if (out_fd != NULL)
posix_spawn_file_actions_adddup2 (&file_actions, out_fd->handle, 1);
if (err_fd != NULL)
if (stderr_stream != NULL)
posix_spawn_file_actions_adddup2 (&file_actions, g_unix_output_stream_get_fd (stderr_stream), 2);
else if (err_fd != NULL)
posix_spawn_file_actions_adddup2 (&file_actions, err_fd->handle, 2);
aslr_value = g_hash_table_lookup (options->aux, "aslr");
+5 -3
View File
@@ -128,12 +128,13 @@ namespace Frida {
return dtrace_agent;
}
public async uint spawn (string path, HostSpawnOptions options, Cancellable? cancellable) throws Error, IOError {
public async uint spawn (string path, HostSpawnOptions options, UnixInputStream? stdin_stream,
UnixOutputStream? stdout_stream, UnixOutputStream? stderr_stream, Cancellable? cancellable) throws Error, IOError {
if (!FileUtils.test (path, EXISTS))
throw new Error.EXECUTABLE_NOT_FOUND ("Unable to find executable at '%s'", path);
StdioPipes? pipes;
var child_pid = _spawn (path, options, out pipes);
var child_pid = _spawn (path, options, stdin_stream, stdout_stream, stderr_stream, out pipes);
ChildWatch.add ((Pid) child_pid, on_child_dead);
@@ -670,7 +671,8 @@ namespace Frida {
protected extern void _destroy_dispatch_context ();
protected extern void _schedule_on_dispatch_queue (DispatchWorker worker);
protected extern uint _spawn (string path, HostSpawnOptions options, out StdioPipes? pipes) throws Error;
protected extern uint _spawn (string path, HostSpawnOptions options, UnixInputStream? stdin_stream,
UnixOutputStream? stdout_stream, UnixOutputStream? stderr_stream, out StdioPipes? pipes) throws Error;
protected extern static void _launch (string identifier, HostSpawnOptions options, LaunchCompletionHandler on_complete);
protected extern static bool _is_suspended (uint task) throws Error;
public extern static void resume_process (uint task) throws Error;
+2 -1
View File
@@ -35,7 +35,8 @@ namespace Frida {
throw_not_supported ();
}
public async uint spawn (string path, HostSpawnOptions options, Cancellable? cancellable) throws Error, IOError {
public async uint spawn (string path, HostSpawnOptions options, UnixInputStream? stdin_stream,
UnixOutputStream? stdout_stream, UnixOutputStream? stderr_stream, Cancellable? cancellable) throws Error, IOError {
throw_not_supported ();
}
+7 -1
View File
@@ -83,9 +83,12 @@ namespace Frida {
}
}
public async uint spawn (string path, HostSpawnOptions options, Cancellable? cancellable) throws Error, IOError {
public async uint spawn (string path, HostSpawnOptions options, UnixInputStream? stdin_stream,
UnixOutputStream? stdout_stream, UnixOutputStream? stderr_stream, Cancellable? cancellable) throws Error, IOError {
var helper = yield obtain (cancellable);
try {
if (stdin_stream != null)
return yield helper.spawn_with_stdio (path, options, stdin_stream, stdout_stream, stderr_stream, cancellable);
return yield helper.spawn (path, options, cancellable);
} catch (GLib.Error e) {
throw_helper_error (e);
@@ -340,6 +343,9 @@ namespace Frida {
GLib.SpawnFlags flags =
GLib.SpawnFlags.LEAVE_DESCRIPTORS_OPEN |
GLib.SpawnFlags.DO_NOT_REAP_CHILD |
GLib.SpawnFlags.STDOUT_TO_DEV_NULL |
GLib.SpawnFlags.STDERR_TO_DEV_NULL |
/* GLib.SpawnFlags.STDIN_FROM_DEV_NULL */ 2048 |
/* GLib.SpawnFlags.CLOEXEC_PIPES */ 256;
GLib.Process.spawn_async (null, argv, null, flags, null, out pending_pid);
+6 -1
View File
@@ -162,7 +162,12 @@ namespace Frida {
}
public async uint spawn (string path, HostSpawnOptions options, Cancellable? cancellable) throws Error, IOError {
return yield backend.spawn (path, options, cancellable);
return yield backend.spawn (path, options, null, null, null, cancellable);
}
public async uint spawn_with_stdio (string path, HostSpawnOptions options, UnixInputStream stdin_stream,
UnixOutputStream stdout_stream, UnixOutputStream stderr_stream, Cancellable? cancellable) throws Error, IOError {
return yield backend.spawn (path, options, stdin_stream, stdout_stream, stderr_stream, cancellable);
}
public async void launch (string identifier, HostSpawnOptions options, Cancellable? cancellable) throws Error, IOError {
+4 -1
View File
@@ -20,7 +20,8 @@ namespace Frida {
public abstract async void enable_spawn_gating (SpawnGatingScope scope, Cancellable? cancellable) throws Error, IOError;
public abstract async void disable_spawn_gating (Cancellable? cancellable) throws Error, IOError;
public abstract async HostSpawnInfo[] enumerate_pending_spawn (Cancellable? cancellable) throws Error, IOError;
public abstract async uint spawn (string path, HostSpawnOptions options, Cancellable? cancellable) throws Error, IOError;
public abstract async uint spawn (string path, HostSpawnOptions options, UnixInputStream? stdin_stream,
UnixOutputStream? stdout_stream, UnixOutputStream? stderr_stream, Cancellable? cancellable) throws Error, IOError;
public abstract async void launch (string identifier, HostSpawnOptions options,
Cancellable? cancellable) throws Error, IOError;
public abstract async void notify_launch_completed (string identifier, uint pid,
@@ -64,6 +65,8 @@ namespace Frida {
public abstract async void disable_spawn_gating (Cancellable? cancellable) throws GLib.Error;
public abstract async HostSpawnInfo[] enumerate_pending_spawn (Cancellable? cancellable) throws GLib.Error;
public abstract async uint spawn (string path, HostSpawnOptions options, Cancellable? cancellable) throws GLib.Error;
public abstract async uint spawn_with_stdio (string path, HostSpawnOptions options, UnixInputStream stdin_stream,
UnixOutputStream stdout_stream, UnixOutputStream stderr_stream, Cancellable? cancellable) throws GLib.Error;
public abstract async void launch (string identifier, HostSpawnOptions options, Cancellable? cancellable) throws GLib.Error;
public abstract async void notify_launch_completed (string identifier, uint pid,
Cancellable? cancellable) throws GLib.Error;
+5 -1
View File
@@ -993,7 +993,11 @@ namespace Frida {
private void on_remote_agent_session_detached (AgentSessionId remote_id, SessionDetachReason reason, CrashInfo crash) {
AgentSessionId? local_id;
if (!remote_agent_sessions.unset (remote_id, out local_id))
bool mapping_found = remote_agent_sessions.unset (remote_id, out local_id);
GLib.info ("detach-trace: Droidy remote session detached remote_id=%s reason=%d mapping_found=%s local_id=%s",
remote_id.handle, reason, mapping_found.to_string (),
mapping_found ? local_id.handle : "-");
if (!mapping_found)
return;
bool agent_session_found = agent_sessions.unset (local_id);
+13
View File
@@ -1885,6 +1885,9 @@ namespace Frida {
break;
}
}
GLib.info ("detach-trace: Device._release_session id=%s may_block=%s",
(session_id != null) ? session_id.handle : "-", may_block.to_string ());
if (session_id == null)
return;
@@ -1900,11 +1903,16 @@ namespace Frida {
} catch (Error e) {
assert_not_reached ();
}
GLib.info ("detach-trace: Device._release_session resumed id=%s", session_id.handle);
}
}
private void on_agent_session_detached (AgentSessionId id, SessionDetachReason reason, CrashInfo crash) {
var session = agent_sessions[id];
GLib.info ("detach-trace: Device session detached id=%s reason=%d session=%p pending=%s",
id.handle, reason, session, pending_detach_requests.has_key (id).to_string ());
if (session != null)
session._on_detached (reason, crash);
@@ -3837,15 +3845,20 @@ namespace Frida {
}
private async void close_session_and_peer_connection (Cancellable? cancellable) throws IOError {
GLib.info ("detach-trace: Session closing remote id=%s", id.handle);
try {
yield active_session.close (cancellable);
} catch (GLib.Error e) {
GLib.info ("detach-trace: Session remote close failed id=%s error=%s", id.handle, e.message);
if (e is IOError.CANCELLED) {
discard_peer_connection ();
return;
}
}
GLib.info ("detach-trace: Session remote close returned id=%s", id.handle);
yield teardown_peer_connection (cancellable);
}
+6 -1
View File
@@ -871,6 +871,8 @@ namespace Frida {
private void on_agent_session_provider_closed (AgentSessionId id) {
var closed_after_opening = agent_sessions.unset (id);
GLib.info ("detach-trace: BaseDBusHostSession provider closed id=%s closed_after_opening=%s",
id.handle, closed_after_opening.to_string ());
if (!closed_after_opening)
return;
var reason = SessionDetachReason.APPLICATION_REQUESTED;
@@ -973,7 +975,10 @@ namespace Frida {
var crash_info = (crash != null) ? crash : CrashInfo.empty ();
foreach (var id in entry.sessions) {
if (agent_sessions.unset (id))
bool still_registered = agent_sessions.unset (id);
GLib.info ("detach-trace: BaseDBusHostSession teardown id=%s reason=%d still_registered=%s",
id.handle, reason, still_registered.to_string ());
if (still_registered)
agent_session_detached (id, reason, crash_info);
}
+7 -2
View File
@@ -30,7 +30,8 @@ namespace Frida {
p.close ();
}
public async uint spawn (string path, HostSpawnOptions options, Cancellable? cancellable) throws Error, IOError {
public async uint spawn (string path, HostSpawnOptions options, UnixInputStream? stdin_stream,
UnixOutputStream? stdout_stream, UnixOutputStream? stderr_stream, Cancellable? cancellable) throws Error, IOError {
if (!FileUtils.test (path, EXISTS))
throw new Error.EXECUTABLE_NOT_FOUND ("Unable to find executable at '%s'", path);
@@ -56,7 +57,11 @@ namespace Frida {
if (pid == 0) {
Posix.setsid ();
if (pipes != null) {
if (stdin_stream != null) {
Posix.dup2 (stdin_stream.get_fd (), 0);
Posix.dup2 (stdout_stream.get_fd (), 1);
Posix.dup2 (stderr_stream.get_fd (), 2);
} else if (pipes != null) {
Posix.dup2 (in_fd.handle, 0);
Posix.dup2 (out_fd.handle, 1);
Posix.dup2 (err_fd.handle, 2);
+13 -4
View File
@@ -54,9 +54,10 @@ namespace Frida {
return _resource_store;
}
public async uint spawn (string path, HostSpawnOptions options, Cancellable? cancellable) throws Error, IOError {
public async uint spawn (string path, HostSpawnOptions options, UnixInputStream? stdin_stream,
UnixOutputStream? stdout_stream, UnixOutputStream? stderr_stream, Cancellable? cancellable) throws Error, IOError {
var helper = yield obtain_for_path (path, cancellable);
return yield helper.spawn (path, options, cancellable);
return yield helper.spawn (path, options, stdin_stream, stdout_stream, stderr_stream, cancellable);
}
public async void prepare_exec_transition (uint pid, Cancellable? cancellable) throws Error, IOError {
@@ -379,7 +380,12 @@ namespace Frida {
} catch (Error e) {
string[] argv = { helper_file.path, socket_address };
GLib.SpawnFlags flags = GLib.SpawnFlags.LEAVE_DESCRIPTORS_OPEN | /* GLib.SpawnFlags.CLOEXEC_PIPES */ 256;
GLib.SpawnFlags flags =
GLib.SpawnFlags.LEAVE_DESCRIPTORS_OPEN |
GLib.SpawnFlags.STDOUT_TO_DEV_NULL |
GLib.SpawnFlags.STDERR_TO_DEV_NULL |
/* GLib.SpawnFlags.STDIN_FROM_DEV_NULL */ 2048 |
/* GLib.SpawnFlags.CLOEXEC_PIPES */ 256;
GLib.Process.spawn_async (null, argv, envp, flags, null, out pending_pid);
}
@@ -498,8 +504,11 @@ namespace Frida {
proxy.uninjected.disconnect (on_uninjected);
}
public async uint spawn (string path, HostSpawnOptions options, Cancellable? cancellable) throws Error, IOError {
public async uint spawn (string path, HostSpawnOptions options, UnixInputStream? stdin_stream,
UnixOutputStream? stdout_stream, UnixOutputStream? stderr_stream, Cancellable? cancellable) throws Error, IOError {
try {
if (stdin_stream != null)
return yield proxy.spawn_with_stdio (path, options, stdin_stream, stdout_stream, stderr_stream, cancellable);
return yield proxy.spawn (path, options, cancellable);
} catch (GLib.Error e) {
throw_dbus_error (e);
+6 -1
View File
@@ -121,7 +121,12 @@ namespace Frida {
}
public async uint spawn (string path, HostSpawnOptions options, Cancellable? cancellable) throws Error, IOError {
return yield backend.spawn (path, options, cancellable);
return yield backend.spawn (path, options, null, null, null, cancellable);
}
public async uint spawn_with_stdio (string path, HostSpawnOptions options, UnixInputStream stdin_stream,
UnixOutputStream stdout_stream, UnixOutputStream stderr_stream, Cancellable? cancellable) throws Error, IOError {
return yield backend.spawn (path, options, stdin_stream, stdout_stream, stderr_stream, cancellable);
}
public async void prepare_exec_transition (uint pid, Cancellable? cancellable) throws Error, IOError {
+4 -1
View File
@@ -5,7 +5,8 @@ namespace Frida {
public abstract async void close (Cancellable? cancellable) throws IOError;
public abstract async uint spawn (string path, HostSpawnOptions options, Cancellable? cancellable) throws Error, IOError;
public abstract async uint spawn (string path, HostSpawnOptions options, UnixInputStream? stdin_stream,
UnixOutputStream? stdout_stream, UnixOutputStream? stderr_stream, Cancellable? cancellable) throws Error, IOError;
public abstract async void prepare_exec_transition (uint pid, Cancellable? cancellable) throws Error, IOError;
public abstract async void await_exec_transition (uint pid, Cancellable? cancellable) throws Error, IOError;
public abstract async void cancel_exec_transition (uint pid, Cancellable? cancellable) throws Error, IOError;
@@ -50,6 +51,8 @@ namespace Frida {
public abstract async void stop (Cancellable? cancellable) throws GLib.Error;
public abstract async uint spawn (string path, HostSpawnOptions options, Cancellable? cancellable) throws GLib.Error;
public abstract async uint spawn_with_stdio (string path, HostSpawnOptions options, UnixInputStream stdin_stream,
UnixOutputStream stdout_stream, UnixOutputStream stderr_stream, Cancellable? cancellable) throws GLib.Error;
public abstract async void prepare_exec_transition (uint pid, Cancellable? cancellable) throws GLib.Error;
public abstract async void await_exec_transition (uint pid, Cancellable? cancellable) throws GLib.Error;
public abstract async void cancel_exec_transition (uint pid, Cancellable? cancellable) throws GLib.Error;
+10 -1
View File
@@ -347,7 +347,16 @@ namespace Frida {
return yield robo_launcher.spawn (program, options, cancellable);
#endif
return yield helper.spawn (program, options, cancellable);
UnixInputStream? stdin_stream = null;
UnixOutputStream? stdout_stream = null;
UnixOutputStream? stderr_stream = null;
if (options.stdio == INHERIT) {
stdin_stream = new UnixInputStream (0, false);
stdout_stream = new UnixOutputStream (1, false);
stderr_stream = new UnixOutputStream (2, false);
}
return yield helper.spawn (program, options, stdin_stream, stdout_stream, stderr_stream, cancellable);
}
protected override async void prepare_exec_transition (uint pid, Cancellable? cancellable) throws Error, IOError {
+1 -1
View File
@@ -1,6 +1,6 @@
[wrap-git]
url = https://github.com/frida/frida-gum.git
revision = 17.16.0
revision = 17.16.4
depth = 1
[provide]
+1 -1
View File
@@ -1,6 +1,6 @@
[wrap-git]
url = https://github.com/frida/glib.git
revision = 92d65736b198c2cf131f691dd83db0b25f7b02d2
revision = 90a8b77b3d4cdf0482eb398fb2000dcceaeb15f0
depth = 1
[provide]