In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly explains "iOS Mach anomalies and signal signal analysis". The content of the explanation is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "iOS Mach anomalies and signal signal analysis".
1. IOS Mach exception
1.1 XNU
Darwin is the operating system of Mac OS and iOS, while XNU is the kernel part of the Darwin operating system. XNU is a hybrid kernel, which has the characteristics of both macro kernel and micro kernel, and Mach is its micro kernel.
The Darwin operating system corresponds to the MacOS and iOS system version numbers as shown in the above figure. Mac can execute the following command to check the Darwin version number.
System_profiler SPSoftwareDataType
1.2 Mach
Mach: [Macrok], the operating system microkernel, is the design basis of many new operating systems.
There are several basic concepts in the Mach microkernel:
Tasks, an object that owns a set of system resources, allowing "thread" to execute in it.
Threads, the basic unit of execution, has the context of task and shares its resources.
A set of protected message queues for communication between Ports,task; task can send / receive data to any port.
Message, which has a collection of typed data objects, can only be sent to port.
1.3 simulate Mach Message transmission
● Mach offers a small amount of API and less introduction to Apple documentation.
/ / create a message queue in the kernel to get the corresponding port
Mach_port_allocate ()
/ / Grant task the specified permissions on port
Mach_port_insert_right ()
/ / by setting the parameter: MACH_RSV_MSG/MACH_SEND_MSG is used to receive / send mach message
Mach_msg ()
The following code simulates sending Message to Mach Port and processing after receiving Message:
● first calls createPortAndAddListener to create Mach Port
● calls sendMachPortMessage: sends a message to the created MachPort
Example of ● execution result:
2018-02-27 09 33 create a port 37.797435 0800 xxx [54456 Swiss 5198921] 41731
2018-02-27 09 33 37.797697 0800 xxx [54456 5198921]
2018-02-27 09 remote_port 33 remote_port 37.797870 0800 xxx [54456 frog 5199525] Receive a mach message:, remote_port: 0, local_port: 41731, exception code: 28672
● sample code:
/ / create Mach Port and listen for messages
+ (mach_port_t) createPortAndAddListener {
Mach_port_t server_port
Kern_return_t kr = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, & server_port)
Assert (kr = = KERN_SUCCESS)
NSLog (@ "create a port:% d", server_port)
Kr = mach_port_insert_right (mach_task_self (), server_port, server_port, MACH_MSG_TYPE_MAKE_SEND)
Assert (kr = = KERN_SUCCESS)
[self setMachPortListener:server_port]
Return server_port
}
+ (void) setMachPortListener: (mach_port_t) mach_port {
Dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ {
Mach_message mach_message
Mach_message.Head.msgh_size = 1024
Mach_message.Head.msgh_local_port = server_port
Mach_msg_return_t mr
While (true) {
Mr = mach_msg (& mach_message.Head)
MACH_RCV_MSG | MACH_RCV_LARGE
0
Mach_message.Head.msgh_size
Mach_message.Head.msgh_local_port
MACH_MSG_TIMEOUT_NONE
MACH_PORT_NULL)
If (mr! = MACH_MSG_SUCCESS & & mr! = MACH_RCV_TOO_LARGE) {
NSLog (@ "error!")
}
Mach_msg_id_t msg_id = mach_message.Head.msgh_id
Mach_port_t remote_port = mach_message.Head.msgh_remote_port
Mach_port_t local_port = mach_message.Head.msgh_local_port
NSLog (@ "Receive a mach message: [% d], remote_port:% d, local_port:% d, exception code:% d"
Msg_id
Remote_port
Local_port
Mach_message.exception)
Abort ()
}
});
}
/ / send a message to the specified Mach Port
+ (void) sendMachPortMessage: (mach_port_t) mach_port {
Kern_return_t kr
Mach_msg_header_t header
Header.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0)
Header.msgh_size = sizeof (mach_msg_header_t)
Header.msgh_remote_port = mach_port
Header.msgh_local_port = MACH_PORT_NULL
Header.msgh_id = 100
NSLog (@ "Send a mach message: [% d].", header.msgh_id)
Kr = mach_msg (& header)
MACH_SEND_MSG
Header.msgh_size
0
MACH_PORT_NULL
MACH_MSG_TIMEOUT_NONE
MACH_PORT_NULL)
}
1.4 catch Mach exception
● task_set_exception_ports () sets the Port for the kernel to receive Mach exception messages, and when replaced with a custom Port, the exception messages generated during program execution can be captured.
Example of ● execution result:
2018-02-27 09 xxx 52V 11.4830760800 xxx [55018V 5253531] create a port: 23299
2018-02-27 09 BAD MEM ACCESS 52v 14.484272v 0800 xxx [55018 BAD MEM ACCESS 5253531] * Make a [BAD MEM ACCESS] now. **********
2018-02-27 09 remote_port 52V 14.484477V 0800 xxx [55018V 5253611] Receive a mach message: [2405], remote_port: 23555, local_port: 23299, exception code: 1
● sample code:
+ (void) createAndSetExceptionPort {
Mach_port_t server_port
Kern_return_t kr = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, & server_port)
Assert (kr = = KERN_SUCCESS)
NSLog (@ "create a port:% d", server_port)
Kr = mach_port_insert_right (mach_task_self (), server_port, server_port, MACH_MSG_TYPE_MAKE_SEND)
Assert (kr = = KERN_SUCCESS)
Kr = task_set_exception_ports (mach_task_self (), EXC_MASK_BAD_ACCESS | EXC_MASK_CRASH, server_port, EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, THREAD_STATE_NONE)
[self setMachPortListener:server_port]
}
/ / construct BAD MEM ACCESS Crash
-(void) makeCrash {
NSLog (@ "* Make a [BAD MEM ACCESS] now. *")
* ((int *) (0x1234)) = 122
}
1.5 Runloop
The application of Mach Port is not only at the kernel level, but also at the Cocoa Foundation and Core Foundation layers, such as Runloop.
There are two categories of Runloop sources:
1.Input sources
Port-Based sources
Custom Input sources
2.Timer sources
Port-Based sources is based on Mach Port and completes message delivery in Runloop.
The above Mach API is the kernel layer exit interface, and the Cocoa Foundation and Core Foundation layers respectively encapsulate the Mach Port interface for calling. For more information: Apple-Runloop Programming Guard, there is a detailed sample code.
2. Signal signal
Signal is a soft interrupt signal that provides asynchronous event handling mechanism. Signal is a rough way to communicate information between processes, using scenarios:
Related to process termination
Terminal interaction
Related to programming errors or hardware errors, when the system encounters an unrecoverable error, it triggers a crash mechanism to make the program exit, such as division of 0, memory write error, and so on.
Here we mainly consider the signal-related applications when the system encounters an unrecoverable error, that is, Crash. Signal signal processing is a UNIX operating system mechanism, so the Android platform is also used in theory, and Android Native Crash can be captured based on signal.
2.1 signal registration and processing
Signal ()
# import
Register for signal handler
When the call is successful, the current operation of the signo signal is removed and replaced by a new signal handler specified by handler
The signal processing function returns void because there is no place for the function to return. Register the custom signal processing function, construct the Crash, send out the signal and execute the custom signal processing logic.
[attached]: when Xcode Debug is running, add breakpoints and execute the pro hand-p true-s false SIGABRT command before Crash triggers.
(lldb) pro hand-p true-s false SIGABRT
NAME PASS STOP NOTIFY
= =
SIGABRT true false true
2018-02-27 12 NSRangeException' now 57 Make 25.284651 0800 xxx [58061 NSRangeException' now 5651844]. **********
2018-02-27 12 NSRangeException', reason 57 NSSingleObjectArrayI objectAtIndex 25.294945 0800 xxx [58061 NSRangeException', reason 5651844] * NSSingleObjectArrayI objectAtIndex:: index 1 beyond bounds [0. 0]'
2018-02-27 12 handle signal 57 handle signal 25.888332 0800 xxx [58061 purl 5651844]-handle signal: 6
● sample code:
/ / set custom signal processing function
+ (void) setSignalHandler {
Signal (SIGABRT, test_signal_handler)
}
Static void test_signal_handler (int signo) {
NSLog (@ "[signal handler]-handle signal:% d", signo)
}
/ / construct NSRangeException exception to trigger SIGABRT signal transmission
-(void) makeCrash {
NSLog (@ "* Make a 'NSRangeException' now. *")
NSArray * array = @ [@ "aaa"]
}
2.2 LLDB Debugger
When running App in Xcode Debug mode, the signal of the App process is captured by the LLDB Debugger debugger; you need to use the LLDB debug command to throw the specified signal processing to the user layer to facilitate debugging.
● views all signaling configurations:
/ / process handle abbreviation
Pro hand
● modifies the specified signaling configuration:
/ / option:
/ /-P: PASS
/ /-S: STOP
/ /-N: NOTIFY
Pro hand-option false signal name
/ example: SIGABRT signal processing does not stop in LLDB, but can be thrown to the user layer
Pro hand-s false SIGABRT
2.3 reentrant
When sending a signal to the kernel, the process may execute anywhere in the code, for example, the process is performing an important operation, an inconsistent state may occur after an interruption, or the process is processing another signal. So make sure that the signal handler only performs reentrant operations:
When ● writes an interrupt handler, it is assumed that the interrupt process may be in a non-reentrant function.
● carefully modifies global data.
2.4 Advanced signal processing
The signal () function is very basic and provides only a minimum standard for signal management. The sigaction () system call provides more powerful signal management capabilities. When the signal processor is running, it can be used to block the reception of specific signals, and it can also be used to obtain information about the status of various operating systems and processes when the signal is sent.
● sample code:
/ / set custom signal processing function
+ (void) setSignalHandlerInAdvance {
Struct sigaction act
/ / when sa_flags is set to SA_SIGINFO, set sa_sigaction to specify the signal processing function
Act.sa_flags = SA_SIGINFO
Act.sa_sigaction = test_signal_action_handler
Sigaction (SIGABRT, & act, NULL)
}
Static void test_signal_action_handler (int signo, siginfo_t * si, void * ucontext) {
NSLog (@ "[sigaction handler]-handle signal:% d", signo)
/ / handle siginfo_t
NSLog (@ "siginfo: {\ nsi_signo:% d,\ nsi_errno:% d,\ nsi_code:% d,\ nsi_pid:% d,\ nsi_uid:% d,\ nsi_status:% d,\ nsi_value:% d\ n}"
Si- > si_signo
Si- > si_errno
Si- > si_code
Si- > si_pid
Si- > si_uid
Si- > si_status
Si- > si_value.sival_int)
}
Thank you for your reading, the above is the content of "iOS Mach anomaly and signal signal Analysis". After the study of this article, I believe you have a deeper understanding of iOS Mach anomaly and signal signal analysis, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.