What should I do if the program crashes in objc_msgsend?
The most likely reason is that when you send a message to a released object, or although the pointer is correct, the content is damaged by other objects (such as out-of-memory ), or a dangling pointer is used ). Occasionally, the data structure at run time is damaged due to memory errors, but the problem is usually caused by the receiver itself.
Both debugger and crash log can obtain more information than backtrace.
Receiver and Selector registers)
Objc_msgsend () stores the recipient object and selector in the CPU register. These values can be used to help analyze problems.
The registers used in different architectures are different. The following table is for Mac OS X Leopard (snow leopard should also be the same ).
|
objc_msgSend objc_msgSend_fpret |
objc_msgSend_stret |
|
receiver |
SEL |
receiver |
SEL |
I386 |
Eax * |
ECX |
Eax * |
ECX |
X86_64 |
RDI |
RSI |
RSI |
RDX |
PPC |
R3 |
R4 |
R4 |
R5 |
Ppc64 |
R3 |
R4 |
R4 |
R5 |
Arm |
R0 |
R1 |
R1 |
R2 |
* Note in i386: the recipient object exists in most crashes.Eax. If the called path is too long, eax may save other values.
Interpreting the receiver and Invalid Address)
You can learn some tips by using recipient addresses and illegal addresses to create a crash. In the crash log, the receiver address is stored in the thread state using the registers listed in the above table, while the Invalid Address is listed at the top of the log (usually shown
Kern_protection_failure at <Invalid Address>). On the debugger console, invalid addresses are output when the program is stopped. You can use the registers listed in the preceding table to output the recipient's addresses.
Program received signal exc_bad_access, cocould not access memory.
Reason: kern_protection_failure at address: 0x00000001
0x00090ec4 in objc_msgsend ()
(GDB) P/x $ eax
$1 = 0x1
This test program collapsed in [(ID) 1 release].
Generally, one of the two situations is caused: the recipient's address is incorrect (the Invalid Address is the same at this time, or the offset is 16 or 32 bytes ), or the recipient's address is reasonable, and the Invalid Address is the recipient's Isa pointer. The latter is usually because you are trying to use a released object.
You need to search for these values in a targeted manner and the values nearby them. In some architectures, an invalid ISA may cause program to crash at ISA + 16 or ISA + 32.
Not aligned, cannot be divisible by 16 (not divisble by 16-misaligned)
Malloc () returns 16-byte alignment memory blocks. If your receiver address is not 16-byte aligned, it is probably not a correct object pointer.
Both the first two and the last two are set to the Free List of-malloc.
When a block is released, the memory distributor writes the Free List pointer. If you subsequently use the released object, the first two and the last two digits of its ISA pointer will be set.
All bits are retrieved from the Free List of anti-GC.
Similar to the above Free List of malloc, the Free List of GC will make the address value look wrong, ~ The address (reverse operation) value seems reasonable.
0xa1b1c1d3-CF container
Corefoundation containers uses this value to indicate items that have been deleted or cleared.
ASCII text
It may be because a released object is reassigned to a string, or a released string is reassigned to an object. Use the asciify command to output strings in different byte alignment modes for ease of viewing. The following is a URL-related string:
% Asciify 0x2e777777
###. Www ###
### Www .###
Trace selector (interrogating the selector)
Compilation optimization may make the call point (call site) pointing to the second segment in the call stack not a truly crashed call. It may have been called successfully, but a tail call of this method causes a crash. It is precisely because the tail call optimization will cause the intermediate call frames to be ignored and not displayed in the call stack. Here we can use the selector register to confirm the real crash call.
A selector points to a unique C string. There may be new system changes in the future, but now it can be easily used for debugging. If your program crashes in the debugger, open the debugger console and run the following command using the selector register listed in the above table:
(GDB) x/S $ ECx
0xa1029: "release"
The selector name has been added to the crash log provided by the snow leopard system:
Application Specific information:
Objc_msgsend () selector name: Release
In addition, it is very difficult to obtain the selector only from the crash log. Until snow leopard, you can use the following method:
1. Check the selector register values listed in the preceding table from the thread state of the crash log, for example:
ECX: 0x000a1029
2. From the binary images location of the crash log, find that an image contains this address. It is often either a program or libobjc. A. dylib. If the corresponding image is not found, give up.
0x8b000-0x0000ff7 libobjc. A. dylib ??? (???) <9b5973b7fa88f9aab7885530c7b278dd>/usr/lib/libobjc. A. dylib
3. Find the program file that matches the image listed in the crash log. You can use UUID to confirm their consistency.
% Dwarfdump-U/usr/lib/libobjc. A. dylib
UUID: 26347299-c6ea-b1c8-52d6-072ac874d400 (PPC)/usr/lib/libobjc. A. dylib
UUID: 9b5973b7-fa88-f9aa-b788-5530c7b278dd
(I386)/usr/lib/libobjc. A. dylib
UUID: D2A4E8E1-3C1C-E0D9-2249-125B6DD621F8 (x86_64)/usr/lib/libobjc. A. dylib
At the same time, ensure system version consistency.
4. Calculate the offset address of SEL in the image.
0xa1029-0x8b000 = 0x16029
5. Print the C string at the specified offset address in the image. Remember to specify the correct architecture.
% Otool-v-arch i386-S _ text _ cstring/usr/lib/libobjc. A. dylib | grep 16029
00016029 release
Reprinted please indicate the source: http://blog.csdn.net/horkychen
Original article address:
So you crashed in objc_msgsend ().