From c3996b0deb797020469b14816a0591e6f7896620 Mon Sep 17 00:00:00 2001 From: hazmi-e205 Date: Wed, 18 Feb 2026 07:33:54 +0700 Subject: [PATCH 1/5] + instruments experimental --- Externals/_Patches/libidevice.patch | 13 --- Prj/libidevice.lua | 48 -------- Prj/libinstruments.lua | 71 ++++++++++++ Prj/lwip.lua | 78 +++++++++++++ Prj/picoquic.lua | 97 ++++++++++++++++ Prj/picotls.lua | 76 ++++++++++++ Prj/premake5.lua | 23 +++- Src/devicebridge.h | 5 +- Src/devicebridge_instrument.cpp | 174 +++++++++++++--------------- Src/deviceclient.cpp | 19 +-- Src/deviceclient.h | 10 +- Src/mainwindow_syslog.cpp | 41 ++++--- info.json | 32 +++-- 13 files changed, 472 insertions(+), 215 deletions(-) delete mode 100644 Externals/_Patches/libidevice.patch delete mode 100644 Prj/libidevice.lua create mode 100644 Prj/libinstruments.lua create mode 100644 Prj/lwip.lua create mode 100644 Prj/picoquic.lua create mode 100644 Prj/picotls.lua diff --git a/Externals/_Patches/libidevice.patch b/Externals/_Patches/libidevice.patch deleted file mode 100644 index 0b026ca..0000000 --- a/Externals/_Patches/libidevice.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/include/idevice/common/macro_def.h b/include/idevice/common/macro_def.h -index 0342349..6c5da76 100644 ---- a/include/idevice/common/macro_def.h -+++ b/include/idevice/common/macro_def.h -@@ -49,7 +49,7 @@ - #define IDEVICE_MEM_ALIGN(v, a) (((v) + (a)-1) & ~((a)-1)) - - // ASSERT --#define IDEVICE_ASSERT(exp, fmt, ...) if (!(exp)) { IDEVICE_LOG_E(fmt, ##__VA_ARGS__); } assert(exp) -+#define IDEVICE_ASSERT(exp, fmt, ...) //if (!(exp)) { IDEVICE_LOG_E(fmt, ##__VA_ARGS__); } assert(exp) - - // HELPER - #define IDEVICE_ATOMIC_SET_MAX(atomic_value, max_value) \ diff --git a/Prj/libidevice.lua b/Prj/libidevice.lua deleted file mode 100644 index dfab38d..0000000 --- a/Prj/libidevice.lua +++ /dev/null @@ -1,48 +0,0 @@ -include "common.lua" - -project "nskeyedarchiver" - kind "StaticLib" - QtConfigs {"force_debug_info"} - - files - { - "../Externals/libnskeyedarchiver/include/**.hpp", - "../Externals/libnskeyedarchiver/src/**.cpp", - } - - includedirs - { - "../Externals/libnskeyedarchiver/include", - "../Externals/libplist/include", - } - - defines - { - "LIBPLIST_STATIC", - } - -project "idevice" - kind "StaticLib" - QtConfigs {"force_debug_info"} - - files - { - "../Externals/libidevice/include/**.h", - "../Externals/libidevice/src/**.cpp", - } - - includedirs - { - "../Externals/libidevice/include", - "../Externals/libnskeyedarchiver/include", - "../Externals/libplist/include", - "../Externals/libimobiledevice/include", - } - - defines - { - "LIBIMOBILEDEVICE_STATIC", - "LIBPLIST_STATIC", - "LIBUSBMUXD_STATIC", - "LIMD_GLUE_STATIC", - } \ No newline at end of file diff --git a/Prj/libinstruments.lua b/Prj/libinstruments.lua new file mode 100644 index 0000000..32046e7 --- /dev/null +++ b/Prj/libinstruments.lua @@ -0,0 +1,71 @@ +include "common.lua" + +project "instruments" + kind "StaticLib" + QtConfigs {"force_debug_info"} + + files + { + -- Public headers + "../Externals/libinstruments/include/**.h", + + -- Utilities + "../Externals/libinstruments/src/util/**.h", + "../Externals/libinstruments/src/util/**.cpp", + + -- NSKeyedArchiver + "../Externals/libinstruments/src/nskeyedarchiver/**.h", + "../Externals/libinstruments/src/nskeyedarchiver/**.cpp", + + -- DTX protocol + "../Externals/libinstruments/src/dtx/**.h", + "../Externals/libinstruments/src/dtx/**.cpp", + + -- Connection + "../Externals/libinstruments/src/connection/**.h", + "../Externals/libinstruments/src/connection/**.cpp", + + -- Services + "../Externals/libinstruments/src/services/**.h", + "../Externals/libinstruments/src/services/**.cpp", + + -- Facade + "../Externals/libinstruments/src/instruments.cpp", + } + + includedirs + { + "../Externals/libinstruments/include", + "../Externals/libinstruments/src", + "../Externals/libinstruments/src/connection", -- lwipopts.h, arch/cc.h + "../Externals/libplist/include", + "../Externals/libimobiledevice/include", + "../Externals/libimobiledevice-glue/include", + "../Externals/libusbmuxd/include", + "../Externals/openssl/include", + "../Externals/picoquic/picoquic", + "../Externals/picotls/include", + "../Externals/picotls/picotlsvs/picotls", + "../Externals/lwip/src/include", + } + + defines + { + "INSTRUMENTS_STATIC", + "INSTRUMENTS_HAS_QUIC", + "INSTRUMENTS_ENABLE_LOGGING", + "LIBIMOBILEDEVICE_STATIC", + "LIBUSBMUXD_STATIC", + "LIBPLIST_STATIC", + "LIMD_GLUE_STATIC", + } + + buildoptions + { + "-Wno-unused-parameter", + "-Wno-missing-field-initializers", + } + + if IsWindows() then + defines { "_WINDOWS", "gettimeofday=gettimeofday" } + end diff --git a/Prj/lwip.lua b/Prj/lwip.lua new file mode 100644 index 0000000..84c2a6c --- /dev/null +++ b/Prj/lwip.lua @@ -0,0 +1,78 @@ +include "common.lua" + +project "lwip" + kind "StaticLib" + QtConfigs {"force_debug_info"} + language "C" + + files + { + -- Core TCP/IP stack + "../Externals/lwip/src/core/init.c", + "../Externals/lwip/src/core/def.c", + "../Externals/lwip/src/core/dns.c", + "../Externals/lwip/src/core/inet_chksum.c", + "../Externals/lwip/src/core/ip.c", + "../Externals/lwip/src/core/mem.c", + "../Externals/lwip/src/core/memp.c", + "../Externals/lwip/src/core/netif.c", + "../Externals/lwip/src/core/pbuf.c", + "../Externals/lwip/src/core/raw.c", + "../Externals/lwip/src/core/stats.c", + "../Externals/lwip/src/core/sys.c", + "../Externals/lwip/src/core/altcp.c", + "../Externals/lwip/src/core/altcp_alloc.c", + "../Externals/lwip/src/core/altcp_tcp.c", + "../Externals/lwip/src/core/tcp.c", + "../Externals/lwip/src/core/tcp_in.c", + "../Externals/lwip/src/core/tcp_out.c", + "../Externals/lwip/src/core/timeouts.c", + "../Externals/lwip/src/core/udp.c", + + -- IPv4 + "../Externals/lwip/src/core/ipv4/acd.c", + "../Externals/lwip/src/core/ipv4/autoip.c", + "../Externals/lwip/src/core/ipv4/dhcp.c", + "../Externals/lwip/src/core/ipv4/etharp.c", + "../Externals/lwip/src/core/ipv4/icmp.c", + "../Externals/lwip/src/core/ipv4/igmp.c", + "../Externals/lwip/src/core/ipv4/ip4.c", + "../Externals/lwip/src/core/ipv4/ip4_addr.c", + "../Externals/lwip/src/core/ipv4/ip4_frag.c", + + -- IPv6 + "../Externals/lwip/src/core/ipv6/dhcp6.c", + "../Externals/lwip/src/core/ipv6/ethip6.c", + "../Externals/lwip/src/core/ipv6/icmp6.c", + "../Externals/lwip/src/core/ipv6/inet6.c", + "../Externals/lwip/src/core/ipv6/ip6.c", + "../Externals/lwip/src/core/ipv6/ip6_addr.c", + "../Externals/lwip/src/core/ipv6/ip6_frag.c", + "../Externals/lwip/src/core/ipv6/mld6.c", + "../Externals/lwip/src/core/ipv6/nd6.c", + + -- API (minimal - only err.c needed for NO_SYS=1) + "../Externals/lwip/src/api/err.c", + + -- Network interface + "../Externals/lwip/src/netif/ethernet.c", + + -- Headers + "../Externals/lwip/src/include/**.h", + } + + includedirs + { + "../Externals/lwip/src/include", + -- lwipopts.h will be in libinstruments src/connection/ + "../Externals/libinstruments/src/connection", + } + + buildoptions + { + "-Wno-unused-parameter", + "-Wno-missing-field-initializers", + "-Wno-sign-compare", + "-Wno-address", + "-Wno-extra", + } diff --git a/Prj/picoquic.lua b/Prj/picoquic.lua new file mode 100644 index 0000000..eb39232 --- /dev/null +++ b/Prj/picoquic.lua @@ -0,0 +1,97 @@ +include "common.lua" + +project "picoquic" + kind "StaticLib" + QtConfigs {"force_debug_info"} + language "C" + + files + { + "../Externals/picoquic/picoquic/bbr.c", + "../Externals/picoquic/picoquic/bbr1.c", + "../Externals/picoquic/picoquic/bytestream.c", + "../Externals/picoquic/picoquic/c4.c", + "../Externals/picoquic/picoquic/cc_common.c", + "../Externals/picoquic/picoquic/config.c", + "../Externals/picoquic/picoquic/cubic.c", + "../Externals/picoquic/picoquic/ech.c", + "../Externals/picoquic/picoquic/error_names.c", + "../Externals/picoquic/picoquic/fastcc.c", + "../Externals/picoquic/picoquic/frames.c", + "../Externals/picoquic/picoquic/intformat.c", + "../Externals/picoquic/picoquic/logger.c", + "../Externals/picoquic/picoquic/logwriter.c", + "../Externals/picoquic/picoquic/loss_recovery.c", + "../Externals/picoquic/picoquic/newreno.c", + "../Externals/picoquic/picoquic/pacing.c", + "../Externals/picoquic/picoquic/packet.c", + "../Externals/picoquic/picoquic/paths.c", + "../Externals/picoquic/picoquic/performance_log.c", + "../Externals/picoquic/picoquic/picohash.c", + "../Externals/picoquic/picoquic/picoquic_lb.c", + "../Externals/picoquic/picoquic/picoquic_ptls_openssl.c", + "../Externals/picoquic/picoquic/picoquic_ptls_minicrypto.c", + "../Externals/picoquic/picoquic/picosplay.c", + "../Externals/picoquic/picoquic/port_blocking.c", + "../Externals/picoquic/picoquic/prague.c", + "../Externals/picoquic/picoquic/quicctx.c", + "../Externals/picoquic/picoquic/register_all_cc_algorithms.c", + "../Externals/picoquic/picoquic/sacks.c", + "../Externals/picoquic/picoquic/sender.c", + "../Externals/picoquic/picoquic/sim_link.c", + "../Externals/picoquic/picoquic/siphash.c", + "../Externals/picoquic/picoquic/spinbit.c", + "../Externals/picoquic/picoquic/ticket_store.c", + "../Externals/picoquic/picoquic/timing.c", + "../Externals/picoquic/picoquic/token_store.c", + "../Externals/picoquic/picoquic/tls_api.c", + "../Externals/picoquic/picoquic/transport.c", + "../Externals/picoquic/picoquic/unified_log.c", + "../Externals/picoquic/picoquic/util.c", + + -- Headers + "../Externals/picoquic/picoquic/**.h", + } + + -- Exclude socket layer (libinstruments handles its own I/O) and optional backends + excludes + { + "../Externals/picoquic/picoquic/picoquic_ptls_fusion.c", + "../Externals/picoquic/picoquic/picoquic_mbedtls.c", + "../Externals/picoquic/picoquic/memory_log.c", + "../Externals/picoquic/picoquic/winsockloop.c", + "../Externals/picoquic/picoquic/sockloop.c", + } + + includedirs + { + "../Externals/picoquic/picoquic", + "../Externals/picotls/include", + "../Externals/picotls/deps/cifra/src", + "../Externals/picotls/deps/cifra/src/ext", + "../Externals/picotls/deps/micro-ecc", + "../Externals/openssl/include", + } + + defines + { + "PTLS_WITHOUT_FUSION", + "DISABLE_DEBUG_PRINTF", + } + + buildoptions + { + "-Wno-unused-parameter", + "-Wno-missing-field-initializers", + "-Wno-sign-compare", + "-Wno-extra", + "-Wno-type-limits", + "-Wno-unknown-pragmas", + } + + + if IsWindows() then + defines { "_WINDOWS", "gettimeofday=gettimeofday", "_WIN32_WINNT=0x0A00" } + else + defines { "_GNU_SOURCE" } + end diff --git a/Prj/picotls.lua b/Prj/picotls.lua new file mode 100644 index 0000000..ac2e4d0 --- /dev/null +++ b/Prj/picotls.lua @@ -0,0 +1,76 @@ +include "common.lua" + +project "picotls" + kind "StaticLib" + QtConfigs {"force_debug_info"} + language "C" + + -- picotls-core + picotls-openssl sources + files + { + -- Core TLS implementation + "../Externals/picotls/lib/picotls.c", + "../Externals/picotls/lib/hpke.c", + "../Externals/picotls/lib/pembase64.c", + "../Externals/picotls/lib/asn1.c", + + -- OpenSSL backend (works with OpenSSL 1.1.x) + "../Externals/picotls/lib/openssl.c", + + -- Minicrypto backend (needed by picoquic for some operations) + "../Externals/picotls/lib/cifra.c", + "../Externals/picotls/lib/cifra/x25519.c", + "../Externals/picotls/lib/cifra/chacha20.c", + "../Externals/picotls/lib/cifra/aes128.c", + "../Externals/picotls/lib/cifra/aes256.c", + "../Externals/picotls/lib/cifra/random.c", + "../Externals/picotls/lib/minicrypto-pem.c", + "../Externals/picotls/lib/uecc.c", + "../Externals/picotls/lib/ffx.c", + + -- Cifra crypto primitives + "../Externals/picotls/deps/micro-ecc/uECC.c", + "../Externals/picotls/deps/cifra/src/aes.c", + "../Externals/picotls/deps/cifra/src/blockwise.c", + "../Externals/picotls/deps/cifra/src/chacha20.c", + "../Externals/picotls/deps/cifra/src/chash.c", + "../Externals/picotls/deps/cifra/src/curve25519.c", + "../Externals/picotls/deps/cifra/src/drbg.c", + "../Externals/picotls/deps/cifra/src/hmac.c", + "../Externals/picotls/deps/cifra/src/gcm.c", + "../Externals/picotls/deps/cifra/src/gf128.c", + "../Externals/picotls/deps/cifra/src/modes.c", + "../Externals/picotls/deps/cifra/src/poly1305.c", + "../Externals/picotls/deps/cifra/src/sha256.c", + "../Externals/picotls/deps/cifra/src/sha512.c", + + -- Headers + "../Externals/picotls/include/**.h", + } + + includedirs + { + "../Externals/picotls/include", + "../Externals/picotls/picotlsvs/picotls", + "../Externals/picotls/deps/cifra/src/ext", + "../Externals/picotls/deps/cifra/src", + "../Externals/picotls/deps/micro-ecc", + "../Externals/openssl/include", + } + + buildoptions + { + "-Wno-unused-parameter", + "-Wno-missing-field-initializers", + "-Wno-sign-compare", + "-Wno-cast-function-type", + "-Wno-incompatible-pointer-types", + } + + + if IsWindows() then + defines { "_WINDOWS", "gettimeofday=gettimeofday" } + else + defines { "_GNU_SOURCE" } + buildoptions { "-pthread" } + end diff --git a/Prj/premake5.lua b/Prj/premake5.lua index 84fca62..97b6bc2 100644 --- a/Prj/premake5.lua +++ b/Prj/premake5.lua @@ -8,10 +8,13 @@ solution "iDebugTool" include "libusbmuxd.lua" include "libimobiledevice.lua" include "libimobiledevice-glue.lua" - include "libidevice.lua" include "macholib.lua" include "zsign.lua" include "bit7z.lua" + include "picotls.lua" + include "picoquic.lua" + include "lwip.lua" + include "libinstruments.lua" project "SelfUpdater" kind "ConsoleApp" @@ -77,8 +80,10 @@ project "iDebugTool" "../Externals/MachOLib", "../Externals/zsign", "../Externals/bit7z/include", - "../Externals/libidevice/include", - "../Externals/libnskeyedarchiver/include", + "../Externals/picoquic/picoquic", + "../Externals/picotls/include", + "../Externals/lwip/src/include", + "../Externals/libinstruments/include", } links @@ -95,8 +100,10 @@ project "iDebugTool" "minizip", "zsign", "bit7z", - "nskeyedarchiver", - "idevice", + "instruments", + "picotls", + "picoquic", + "lwip", } libdirs @@ -106,6 +113,9 @@ project "iDebugTool" defines { + "INSTRUMENTS_STATIC", + "INSTRUMENTS_HAS_QUIC", + "INSTRUMENTS_ENABLE_LOGGING", "LIBIMOBILEDEVICE_STATIC", "LIBUSBMUXD_STATIC", "LIBPLIST_STATIC", @@ -116,6 +126,8 @@ project "iDebugTool" local copysrc = "$$PWD/../../../Build/" .. GetPathFromPlatform() .. "/libs" local copydst = "$$PWD/../../../Build/" .. GetPathFromPlatform() .. "/bin" if IsWindows() then + defines { "_WINDOWS" } + links { "Iphlpapi", @@ -154,5 +166,6 @@ project "iDebugTool" links { "dl", + "pthread", } end \ No newline at end of file diff --git a/Src/devicebridge.h b/Src/devicebridge.h index 5adc9e0..023f538 100644 --- a/Src/devicebridge.h +++ b/Src/devicebridge.h @@ -25,10 +25,7 @@ #include "deviceclient.h" #include "asyncmanager.h" -#include "idevice/instrument/dtxchannel.h" -#include "idevice/instrument/dtxconnection.h" -#include "idevice/instrument/dtxtransport.h" -using namespace idevice; +#include #define ITUNES_METADATA_PLIST_FILENAME "iTunesMetadata.plist" #define PKG_PATH "PublicStaging" diff --git a/Src/devicebridge_instrument.cpp b/Src/devicebridge_instrument.cpp index 900c155..ee70d02 100644 --- a/Src/devicebridge_instrument.cpp +++ b/Src/devicebridge_instrument.cpp @@ -1,11 +1,6 @@ #include "devicebridge.h" -#include "nskeyedarchiver/kavalue.hpp" -#include "nskeyedarchiver/kamap.hpp" -#include "nskeyedarchiver/kaarray.hpp" -#include -#include -using namespace idevice; +using namespace instruments; QStringList DeviceBridge::GetAttributes(AttrType type) { @@ -15,20 +10,25 @@ QStringList DeviceBridge::GetAttributes(AttrType type) if (!CreateClient(op)) return list; - m_clients[op]->transport = new DTXTransport(m_clients[op]->device, false); - m_clients[op]->connection = new DTXConnection(m_clients[op]->transport); - m_clients[op]->connection->Connect(); - - auto channel = m_clients[op]->connection->MakeChannelWithIdentifier("com.apple.instruments.server.services.deviceinfo"); - std::string selector = std::string("sysmon") + (type == AttrType::PROCESS ? "Process" : "System") + "Attributes"; - std::shared_ptr message = DTXMessage::CreateWithSelector(selector.c_str()); - auto response = channel->SendMessageSync(message); - if (response->PayloadObject()) { - QJsonDocument availableOpt = QJsonDocument::fromJson(response->PayloadObject()->ToJson().c_str()); - foreach (const auto& value, availableOpt.array()) - list.append(value.toString("")); + m_clients[op]->instrument = Instruments::Create(m_clients[op]->device, m_clients[op]->client); + if (!m_clients[op]->instrument) { + qDebug() << "ERROR: Failed to create Instruments connection"; + RemoveClient(op); + return list; + } + + std::vector attrs; + Error err; + if (type == AttrType::PROCESS) + err = m_clients[op]->instrument->Performance().GetProcessAttributes(attrs); + else + err = m_clients[op]->instrument->Performance().GetSystemAttributes(attrs); + + if (err == Error::Success) { + for (const auto& attr : attrs) + list.append(QString::fromStdString(attr)); } - channel->Cancel(); + RemoveClient(op); return list; } @@ -39,51 +39,42 @@ void DeviceBridge::StartMonitor(unsigned int interval_ms, QStringList system_att if (!CreateClient(op)) return; - m_clients[op]->transport = new DTXTransport(m_clients[op]->device, false); - m_clients[op]->connection = new DTXConnection(m_clients[op]->transport); - m_clients[op]->connection->Connect(); - - nskeyedarchiver::KAArray proccessAttrs(nskeyedarchiver::KAArray("NSSet", {"NSSet", "NSObject"})); - nskeyedarchiver::KAArray systemAttrs(nskeyedarchiver::KAArray("NSSet", {"NSSet", "NSObject"})); - - foreach (const auto& value, process_attr) - proccessAttrs.push_back(nskeyedarchiver::KAValue(value.toUtf8().data())); - - foreach (const auto& value, system_attr) - systemAttrs.push_back(nskeyedarchiver::KAValue(value.toUtf8().data())); - - m_clients[op]->channel = m_clients[op]->connection->MakeChannelWithIdentifier("com.apple.instruments.server.services.sysmontap"); - auto message = DTXMessage::CreateWithSelector("setConfig:"); - nskeyedarchiver::KAMap configs(nskeyedarchiver::KAMap("NSMutableDictionary", {"NSMutableDictionary", "NSDictionary", "NSObject"})); - configs["ur"] = interval_ms; - configs["sampleInterval"] = interval_ms * 1000000; - configs["bm"] = 0; - configs["cpuUsage"] = true; - configs["procAttrs"] = proccessAttrs; - configs["sysAttrs"] = systemAttrs; - message->AppendAuxiliary(nskeyedarchiver::KAValue(configs)); - auto response = m_clients[op]->channel->SendMessageSync(message); - response->Dump(); - - m_clients[op]->channel->SetMessageHandler([=](std::shared_ptr msg) { - if (msg->PayloadObject()) { - qDebug() << msg->PayloadObject()->ToJson().c_str(); - } - }); + m_clients[op]->instrument = Instruments::Create(m_clients[op]->device, m_clients[op]->client); + if (!m_clients[op]->instrument) { + qDebug() << "ERROR: Failed to create Instruments connection"; + RemoveClient(op); + return; + } - message = DTXMessage::CreateWithSelector("start"); - response = m_clients[op]->channel->SendMessageSync(message); - response->Dump(); + PerfConfig config; + config.sampleIntervalMs = interval_ms; + for (const auto& value : std::as_const(system_attr)) + config.systemAttributes.push_back(value.toStdString()); + for (const auto& value : std::as_const(process_attr)) + config.processAttributes.push_back(value.toStdString()); + + m_clients[op]->instrument->Performance().Start(config, + [](const SystemMetrics& m) { + qDebug() << "CPU:" << m.cpuTotalLoad << "% User:" << m.cpuUserLoad + << "% Sys:" << m.cpuSystemLoad << "%" + << "Net I/O:" << m.netBytesIn << "/" << m.netBytesOut; + }, + [](const std::vector& procs) { + for (const auto& p : procs) { + if (p.cpuUsage > 0.1) { + qDebug() << "PID:" << p.pid << p.name.c_str() + << "CPU:" << p.cpuUsage << "% MEM:" << p.memResident; + } + } + } + ); } void DeviceBridge::StopMonitor() { MobileOperation op = MobileOperation::SYSTEM_MONITOR; - if (m_clients[op]->channel) { - auto message = DTXMessage::CreateWithSelector("stop"); - m_clients[op]->channel->SendMessageSync(message); - m_clients[op]->channel->Cancel(); - } + if (m_clients[op]->instrument) + m_clients[op]->instrument->Performance().Stop(); RemoveClient(op); } @@ -93,17 +84,26 @@ void DeviceBridge::GetProcessList() if (!CreateClient(op)) return; - m_clients[op]->transport = new DTXTransport(m_clients[op]->device, false); - m_clients[op]->connection = new DTXConnection(m_clients[op]->transport); - m_clients[op]->connection->Connect(); + m_clients[op]->instrument = Instruments::Create(m_clients[op]->device, m_clients[op]->client); + if (!m_clients[op]->instrument) { + qDebug() << "ERROR: Failed to create Instruments connection"; + RemoveClient(op); + return; + } - m_clients[op]->channel = m_clients[op]->connection->MakeChannelWithIdentifier("com.apple.instruments.server.services.deviceinfo"); - std::shared_ptr message = DTXMessage::CreateWithSelector("runningProcesses"); - auto response = m_clients[op]->channel->SendMessageSync(message); - if (response->PayloadObject()) { - qDebug() << response->PayloadObject()->ToJson().c_str(); + std::vector procs; + Error err = m_clients[op]->instrument->Process().GetProcessList(procs); + if (err == Error::Success) { + for (const auto& p : procs) { + qDebug() << "PID:" << p.pid + << (p.isApplication ? "App" : "Proc") + << p.bundleId.c_str() + << p.name.c_str(); + } + } else { + qDebug() << "ERROR: GetProcessList failed with error:" << static_cast(err); } - m_clients[op]->channel->Cancel(); + RemoveClient(op); } @@ -113,40 +113,24 @@ void DeviceBridge::StartFPS(unsigned int interval_ms) if (!CreateClient(op)) return; - m_clients[op]->transport = new DTXTransport(m_clients[op]->device, false); - m_clients[op]->connection = new DTXConnection(m_clients[op]->transport); - m_clients[op]->connection->Connect(); - - m_clients[op]->channel = m_clients[op]->connection->MakeChannelWithIdentifier("com.apple.instruments.server.services.graphics.opengl"); - auto message = DTXMessage::CreateWithSelector("availableStatistics"); - m_clients[op]->channel->SendMessageSync(message); - - message = DTXMessage::CreateWithSelector("driverNames"); - m_clients[op]->channel->SendMessageSync(message); - - message = DTXMessage::CreateWithSelector("setSamplingRate:"); - message->AppendAuxiliary(nskeyedarchiver::KAValue((float)interval_ms / 100.f)); - m_clients[op]->channel->SendMessageSync(message); + m_clients[op]->instrument = Instruments::Create(m_clients[op]->device, m_clients[op]->client); + if (!m_clients[op]->instrument) { + qDebug() << "ERROR: Failed to create Instruments connection"; + RemoveClient(op); + return; + } - m_clients[op]->channel->SetMessageHandler([=](std::shared_ptr msg) { - if (msg->PayloadObject()) { - qDebug() << msg->PayloadObject()->ToJson().c_str(); + m_clients[op]->instrument->FPS().Start(interval_ms, + [](const FPSData& data) { + qDebug() << "FPS:" << data.fps << "GPU:" << data.gpuUtilization << "%"; } - }); - - message = DTXMessage::CreateWithSelector("startSamplingAtTimeInterval:"); - message->AppendAuxiliary(nskeyedarchiver::KAValue(0.0f)); - auto response = m_clients[op]->channel->SendMessageSync(message); - response->Dump(); + ); } void DeviceBridge::StopFPS() { MobileOperation op = MobileOperation::FPS_MONITOR; - if (m_clients[op]->channel){ - auto message = DTXMessage::CreateWithSelector("stopSampling"); - m_clients[op]->channel->SendMessageSync(message); - m_clients[op]->channel->Cancel(); - } + if (m_clients[op]->instrument) + m_clients[op]->instrument->FPS().Stop(); RemoveClient(op); } diff --git a/Src/deviceclient.cpp b/Src/deviceclient.cpp index 64c87ab..b87d00c 100644 --- a/Src/deviceclient.cpp +++ b/Src/deviceclient.cpp @@ -6,9 +6,7 @@ DeviceClient::DeviceClient() , client(nullptr) , lockdownd_error(LOCKDOWN_E_UNKNOWN_ERROR) , device_error(IDEVICE_E_UNKNOWN_ERROR) - , transport(nullptr) - , connection(nullptr) - , channel() + , instrument() , afc(nullptr) , house_arrest(nullptr) , installer(nullptr) @@ -84,20 +82,7 @@ DeviceClient::DeviceClient(RemoteAddress address, QStringList service_ids, QStri DeviceClient::~DeviceClient() { // instruments - if (channel) - { - channel = nullptr; - } - if (connection) - { - delete connection; - connection = nullptr; - } - if (transport) - { - delete transport; - transport = nullptr; - } + instrument.reset(); // services if (service) diff --git a/Src/deviceclient.h b/Src/deviceclient.h index 6c73888..f86989a 100644 --- a/Src/deviceclient.h +++ b/Src/deviceclient.h @@ -11,13 +11,11 @@ #include "libimobiledevice/installation_proxy.h" #include "libimobiledevice/mobile_image_mounter.h" #include "libimobiledevice/screenshotr.h" +#include "libimobiledevice/service.h" #include "libimobiledevice/syslog_relay.h" -#include "idevice/instrument/dtxconnection.h" -#include "idevice/instrument/dtxtransport.h" +#include #include "utils.h" -using namespace idevice; - class DeviceClient { public: @@ -32,9 +30,7 @@ class DeviceClient lockdownd_error_t lockdownd_error; idevice_error_t device_error; - DTXTransport* transport; - DTXConnection* connection; - std::shared_ptr channel; + std::shared_ptr instrument; afc_client_t afc; house_arrest_client_t house_arrest; diff --git a/Src/mainwindow_syslog.cpp b/Src/mainwindow_syslog.cpp index 37036d6..0ae673b 100644 --- a/Src/mainwindow_syslog.cpp +++ b/Src/mainwindow_syslog.cpp @@ -94,34 +94,39 @@ void MainWindow::OnClearClicked() void MainWindow::OnSaveClicked() { - bool is_capture = DeviceBridge::Get()->IsSystemLogsCaptured(); - DeviceBridge::Get()->CaptureSystemLogs(false); - - QString filepath = ShowBrowseDialog(BROWSE_TYPE::SAVE_FILE, "Log", this, "Text File (*.txt)"); - if (!filepath.isEmpty()) { - QFile f(filepath); - if (f.open(QIODevice::WriteOnly)) { - QTextStream stream(&f); - stream << ui->syslogEdit->toPlainText(); - f.close(); - } - } - - DeviceBridge::Get()->CaptureSystemLogs(is_capture); + // bool is_capture = DeviceBridge::Get()->IsSystemLogsCaptured(); + // DeviceBridge::Get()->CaptureSystemLogs(false); + + // QString filepath = ShowBrowseDialog(BROWSE_TYPE::SAVE_FILE, "Log", this, "Text File (*.txt)"); + // if (!filepath.isEmpty()) { + // QFile f(filepath); + // if (f.open(QIODevice::WriteOnly)) { + // QTextStream stream(&f); + // stream << ui->syslogEdit->toPlainText(); + // f.close(); + // } + // } + + // DeviceBridge::Get()->CaptureSystemLogs(is_capture); + DeviceBridge::Get()->GetProcessList(); } void MainWindow::OnStartLogging() { if (ui->startLogBtn->text().contains("start", Qt::CaseInsensitive)) { - DeviceBridge::Get()->CaptureSystemLogs(true); - DeviceBridge::Get()->StartSyslog(); + // DeviceBridge::Get()->CaptureSystemLogs(true); + // DeviceBridge::Get()->StartSyslog(); + auto system = QStringList();//DeviceBridge::Get()->GetAttributes(DeviceBridge::AttrType::SYSTEM); + auto process = DeviceBridge::Get()->GetAttributes(DeviceBridge::AttrType::PROCESS); + DeviceBridge::Get()->StartMonitor(100, system, process); ui->startLogBtn->setText("Stop Logging"); } else { - DeviceBridge::Get()->CaptureSystemLogs(false); - DeviceBridge::Get()->StopSyslog(); + // DeviceBridge::Get()->CaptureSystemLogs(false); + // DeviceBridge::Get()->StopSyslog(); + DeviceBridge::Get()->StopMonitor(); ui->startLogBtn->setText("Start Logging"); } } diff --git a/info.json b/info.json index a680f41..a306ed6 100644 --- a/info.json +++ b/info.json @@ -36,19 +36,35 @@ "use_submodules": false }, { - "project": "libidevice", - "url": "https://github.com/sandin/libidevice", + "project": "libinstruments", + "url": "https://github.com/hazmi-e205/libinstruments", + "branch": "main", + "revision": "b0c5366fc2301ed60824a14a16fb520561110705", + "path": "Externals/libinstruments", + "use_submodules": false + }, + { + "project": "lwip", + "url": "https://github.com/lwip-tcpip/lwip", + "branch": "master", + "revision": "4599f551dead9eac233b91c0b9ee5879f5d0620a", + "path": "Externals/lwip", + "use_submodules": false + }, + { + "project": "picoquic", + "url": "https://github.com/private-octopus/picoquic", "branch": "master", - "revision": "3844974cfaf8f70b36f281bd9c491e625012a4ba", - "path": "Externals/libidevice", + "revision": "3335f4029b55f59a4868cacf3e92c3fb84982115", + "path": "Externals/picoquic", "use_submodules": false }, { - "project": "libnskeyedarchiver", - "url": "https://github.com/sandin/libnskeyedarchiver", + "project": "picotls", + "url": "https://github.com/private-octopus/picotls", "branch": "master", - "revision": "212c21a3f0f32abb65921cb2d1b8a42dcda221a5", - "path": "Externals/libnskeyedarchiver", + "revision": "5a4461d8a3948d9d26bf861e7d90cb80d8093515", + "path": "Externals/picotls", "use_submodules": false }, { From 51ef3b9789fb377df1243e7b0322b27f1ee55257 Mon Sep 17 00:00:00 2001 From: hazmi-e205 Date: Thu, 5 Mar 2026 11:28:22 +0700 Subject: [PATCH 2/5] - revert single file --- Src/mainwindow_syslog.cpp | 41 +++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/Src/mainwindow_syslog.cpp b/Src/mainwindow_syslog.cpp index 0ae673b..37036d6 100644 --- a/Src/mainwindow_syslog.cpp +++ b/Src/mainwindow_syslog.cpp @@ -94,39 +94,34 @@ void MainWindow::OnClearClicked() void MainWindow::OnSaveClicked() { - // bool is_capture = DeviceBridge::Get()->IsSystemLogsCaptured(); - // DeviceBridge::Get()->CaptureSystemLogs(false); - - // QString filepath = ShowBrowseDialog(BROWSE_TYPE::SAVE_FILE, "Log", this, "Text File (*.txt)"); - // if (!filepath.isEmpty()) { - // QFile f(filepath); - // if (f.open(QIODevice::WriteOnly)) { - // QTextStream stream(&f); - // stream << ui->syslogEdit->toPlainText(); - // f.close(); - // } - // } - - // DeviceBridge::Get()->CaptureSystemLogs(is_capture); - DeviceBridge::Get()->GetProcessList(); + bool is_capture = DeviceBridge::Get()->IsSystemLogsCaptured(); + DeviceBridge::Get()->CaptureSystemLogs(false); + + QString filepath = ShowBrowseDialog(BROWSE_TYPE::SAVE_FILE, "Log", this, "Text File (*.txt)"); + if (!filepath.isEmpty()) { + QFile f(filepath); + if (f.open(QIODevice::WriteOnly)) { + QTextStream stream(&f); + stream << ui->syslogEdit->toPlainText(); + f.close(); + } + } + + DeviceBridge::Get()->CaptureSystemLogs(is_capture); } void MainWindow::OnStartLogging() { if (ui->startLogBtn->text().contains("start", Qt::CaseInsensitive)) { - // DeviceBridge::Get()->CaptureSystemLogs(true); - // DeviceBridge::Get()->StartSyslog(); - auto system = QStringList();//DeviceBridge::Get()->GetAttributes(DeviceBridge::AttrType::SYSTEM); - auto process = DeviceBridge::Get()->GetAttributes(DeviceBridge::AttrType::PROCESS); - DeviceBridge::Get()->StartMonitor(100, system, process); + DeviceBridge::Get()->CaptureSystemLogs(true); + DeviceBridge::Get()->StartSyslog(); ui->startLogBtn->setText("Stop Logging"); } else { - // DeviceBridge::Get()->CaptureSystemLogs(false); - // DeviceBridge::Get()->StopSyslog(); - DeviceBridge::Get()->StopMonitor(); + DeviceBridge::Get()->CaptureSystemLogs(false); + DeviceBridge::Get()->StopSyslog(); ui->startLogBtn->setText("Start Logging"); } } From d4dab919adbc8f025d6d210f2a81086d7a737932 Mon Sep 17 00:00:00 2001 From: hazmi-e205 Date: Thu, 5 Mar 2026 14:06:26 +0700 Subject: [PATCH 3/5] - update revision --- Src/devicebridge_instrument.cpp | 9 ++++++--- info.json | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Src/devicebridge_instrument.cpp b/Src/devicebridge_instrument.cpp index ee70d02..5d72af1 100644 --- a/Src/devicebridge_instrument.cpp +++ b/Src/devicebridge_instrument.cpp @@ -54,14 +54,16 @@ void DeviceBridge::StartMonitor(unsigned int interval_ms, QStringList system_att config.processAttributes.push_back(value.toStdString()); m_clients[op]->instrument->Performance().Start(config, - [](const SystemMetrics& m) { + [this](const SystemMetrics& m) { + emit SystemLogsReceived2(QString("SystemMetrics > CPU: %0 | User: %1 | Sys: %2 | Net I: %3 | Net O: %4").arg(m.cpuTotalLoad).arg(m.cpuUserLoad).arg(m.cpuSystemLoad).arg(m.netBytesIn).arg(m.netBytesOut)); qDebug() << "CPU:" << m.cpuTotalLoad << "% User:" << m.cpuUserLoad << "% Sys:" << m.cpuSystemLoad << "%" << "Net I/O:" << m.netBytesIn << "/" << m.netBytesOut; }, - [](const std::vector& procs) { + [this](const std::vector& procs) { for (const auto& p : procs) { if (p.cpuUsage > 0.1) { + emit SystemLogsReceived2(QString("ProcessMetrics > PID: %0 | Name: %1 | CPU: %2 | MEM: %3").arg(p.pid).arg(p.name.c_str()).arg(p.cpuUsage).arg(p.memResident)); qDebug() << "PID:" << p.pid << p.name.c_str() << "CPU:" << p.cpuUsage << "% MEM:" << p.memResident; } @@ -121,7 +123,8 @@ void DeviceBridge::StartFPS(unsigned int interval_ms) } m_clients[op]->instrument->FPS().Start(interval_ms, - [](const FPSData& data) { + [this](const FPSData& data) { + emit SystemLogsReceived2(QString("FPS: %0 | GPU: %1").arg(data.fps).arg(data.gpuUtilization)); qDebug() << "FPS:" << data.fps << "GPU:" << data.gpuUtilization << "%"; } ); diff --git a/info.json b/info.json index a306ed6..6c7a8a9 100644 --- a/info.json +++ b/info.json @@ -39,7 +39,7 @@ "project": "libinstruments", "url": "https://github.com/hazmi-e205/libinstruments", "branch": "main", - "revision": "b0c5366fc2301ed60824a14a16fb520561110705", + "revision": "7e5f9caf44e6ed7273b22d9c3f58143ef1588e72", "path": "Externals/libinstruments", "use_submodules": false }, From cd5c9b1ff1fb1032619f8fa46c31fe61962d6369 Mon Sep 17 00:00:00 2001 From: hazmi-e205 Date: Thu, 5 Mar 2026 14:09:14 +0700 Subject: [PATCH 4/5] - change action workflow --- .circleci/config.yml | 14 ++++++++++++-- .github/workflows/windows_nightly.yml | 6 ++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index db6b6d7..870669e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -71,5 +71,15 @@ jobs: workflows: Nightly: jobs: - - Windows x64 - - Linux x64 \ No newline at end of file + - Windows x64: + filters: + branches: + only: main + tags: + only: /.*/ + - Linux x64: + filters: + branches: + only: main + tags: + only: /.*/ diff --git a/.github/workflows/windows_nightly.yml b/.github/workflows/windows_nightly.yml index 282cebe..ac80bc6 100644 --- a/.github/workflows/windows_nightly.yml +++ b/.github/workflows/windows_nightly.yml @@ -1,9 +1,9 @@ name: Windows Nightly CI on: push: - branches: [ "main" ] + branches-ignore: [ "main" ] + tags-ignore: [ "*" ] pull_request: - branches: [ "main" ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: @@ -58,5 +58,3 @@ jobs: - - From d8595f8d1ce19bf5793ee877084dfeecd4e4d847 Mon Sep 17 00:00:00 2001 From: hazmi-e205 Date: Thu, 5 Mar 2026 14:11:15 +0700 Subject: [PATCH 5/5] Revert "- change action workflow" This reverts commit cd5c9b1ff1fb1032619f8fa46c31fe61962d6369. --- .circleci/config.yml | 14 ++------------ .github/workflows/windows_nightly.yml | 6 ++++-- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 870669e..db6b6d7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -71,15 +71,5 @@ jobs: workflows: Nightly: jobs: - - Windows x64: - filters: - branches: - only: main - tags: - only: /.*/ - - Linux x64: - filters: - branches: - only: main - tags: - only: /.*/ + - Windows x64 + - Linux x64 \ No newline at end of file diff --git a/.github/workflows/windows_nightly.yml b/.github/workflows/windows_nightly.yml index ac80bc6..282cebe 100644 --- a/.github/workflows/windows_nightly.yml +++ b/.github/workflows/windows_nightly.yml @@ -1,9 +1,9 @@ name: Windows Nightly CI on: push: - branches-ignore: [ "main" ] - tags-ignore: [ "*" ] + branches: [ "main" ] pull_request: + branches: [ "main" ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: @@ -58,3 +58,5 @@ jobs: + +