Can mobilesubstrate hook this? - iphone

I want to hook a function called png_handle_IHDR declared locally in the ImageIO framework. I used MobileSafari as the filter. But while calling the original function, mobilesafari crashes. Upon inspection of the NSLog, i get this:
Jun 5 17:21:08 unknown MobileSafari[553] <Warning>: dlopen ImageIO success!
Jun 5 17:21:08 unknown MobileSafari[553] <Warning>: Zeroing of nlist success!
Jun 5 17:21:08 unknown MobileSafari[553] <Warning>: method name successfully assigned!
Jun 5 17:21:08 unknown MobileSafari[553] <Warning>: nlist SUCCESS! nlsetting..
Jun 5 17:21:08 unknown MobileSafari[553] <Warning>: nlset success! Hooking..
Jun 5 17:21:09 unknown MobileSafari[553] <Warning>: Png IHDR handle hooking!
Jun 5 17:21:09 unknown UIKitApplication:com.apple.mobilesafari[0x819][553] <Notice>: libpng error: Invalid IHDR chunk
Jun 5 17:21:09 unknown ReportCrash[554] <Notice>: Formulating crash report for process MobileSafari[553]
Jun 5 17:21:09 unknown com.apple.launchd[1] <Warning>: (UIKitApplication:com.apple.mobilesafari[0x819]) Job appears to have crashed: Abort trap: 6
Jun 5 17:21:09 unknown SpringBoard[530] <Warning>: Application 'Safari' exited abnormally with signal 6: Abort trap: 6
I immediately gathered that its very likely that I got the function prototype of the png_handle_IHDR wrong. The following is my code in the tweak:
#import <CoreFoundation/CoreFoundation.h>
#include <substrate.h>
#define ImageIO "/System/Library/Frameworks/ImageIO.framework/ImageIO"
void (*png_handle_IHDR)();
MSHook(void, png_handle_IHDR){
NSLog(#"Png IHDR handle hooking!\n");
_png_handle_IHDR(); //crashed here!!
NSLog(#"Png IHDR handle hooking finished!\n");
}
template <typename Type_>
static void nlset(Type_ &function, struct nlist *nl, size_t index) {
struct nlist &name(nl[index]);
uintptr_t value(name.n_value);
if ((name.n_desc & N_ARM_THUMB_DEF) != 0)
value |= 0x00000001;
function = reinterpret_cast<Type_>(value);
}
MSInitialize {
if (dlopen(ImageIO, RTLD_LAZY | RTLD_NOLOAD)!=NULL)
{
NSLog(#"dlopen ImageIO success!\n");
struct nlist nl[2];
bzero(&nl, sizeof(nl));
NSLog(#"Zeroing of nlist success!\n");
nl[0].n_un.n_name = (char*) "_png_handle_IHDR";
NSLog(#"method name successfully assigned!\n");
nlist(ImageIO,nl);
NSLog(#"nlist SUCCESS! nlsetting..\n");
nlset(png_handle_IHDR, nl, 0);
NSLog(#"nlset success! Hooking..\n");
MSHookFunction(png_handle_IHDR,MSHake(png_handle_IHDR));
}
}
My makefile is as such:
include theos/makefiles/common.mk
TWEAK_NAME = privateFunctionTest
privateFunctionTest_FILES = Tweak.xm
include $(THEOS_MAKE_PATH)/tweak.mk
privateFunctionTest_FRAMEWORKS = UIKit ImageIO CoreGraphics Foundation CoreFoundation
Edit: The question is, is knowing the original function arguments necessary for a successful hook? If yes, is getting the function prototype from the disassembly the only way? There is no definition of this in any of the SDK headers. Thanks.

Ok, I decompiled the function and get the function prototype guessed by the decompiler. As long as the parameters and return type broadly matched e.g. bool : int, unsigned int : int, it still works without killing the execution. So this works:
int *png_handle_IHDR(int a1, int a2, int a3);
MSHook(int, png_handle_IHDR, int a1, int a2, int a3){
NSLog(#"png_handle_IHDR(%d,%d,%d)", a1,a2,a3);
int val = _png_handle_IHDR(a1,a2,a3);
NSLog(#"Png IHDR handle hooking finished, returning %d as result!", val);
return val;
}

Related

Can eBPF's perf_submit() be used in a socket_filter program as well?

So I was trying to send some data from the kernel space program to the user space program using perf_submit.
I've done some studies and here(https://github.com/iovisor/bcc/issues/2423), yonghong-song answered(the last comment) that a socket_filter program can not access bpf_perf_event_output helper and therefore it can only be used for tracing program types.
However, on BCC reference site(https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md#2-bpf_perf_output), if you ctrl+f and search for : 3. perf_submit()
, it says on the fifth line that "for SOCKET_FILTER programs, the struct __sk_buff *skb must be used instead."
I believe this infers that perf_submit() can be used for socket_filter programs as well?
So I have hard time figuring out if perf_submit() can indeed be used for a socket filter program. Maybe some functionalities have been added since Yonghong-song answered the question above?
I'm checking if perf_submit() would work with a socket filter and there's not really a line of code that grabs the data output by perf_submit because just addint perf_submit() in the kernel program already omitted an error.
Here's the code for my program :
from bcc import BPF
# Network interface to be monoitored
INTERFACE = "br-netrome"
bpf_text = """
#include <uapi/linux/ptrace.h>
#include <net/sock.h>
#include <bcc/proto.h>
#include <linux/bpf.h>
#define IP_TCP 6
#define IP_UDP 17
#define IP_ICMP 1
#define ETH_HLEN 14
BPF_PERF_OUTPUT(events); // has to be delcared outside any function
int packet_monitor(struct __sk_buff *skb) {
u8 *cursor = 0;
u64 saddr;
u64 daddr;
u64 ttl;
u64 hchecksum;
struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
if (!(ethernet -> type == 0x0800)) {
return 0; // drop
}
struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
/*
if (ip->nextp != IP_TCP)
{
if (ip -> nextp != IP_UDP)
{
if (ip -> nextp != IP_ICMP)
return 0;
}
}
*/
saddr = ip -> src;
daddr = ip -> dst;
ttl = ip -> ttl;
hchecksum = ip -> hchecksum;
events.perf_submit(skb, &saddr, sizeof(saddr));
// bpf_trace_printk("saddr = %llu, daddr = %llu, ttl = %llu", saddr, daddr, ttl); // only three arguments can be passed using printk
// bpf_trace_printk("Incoming packet!!\\n");
return -1;
}
and here is the error code :
R0=inv2048 R6=ctx(id=0,off=0,imm=0) R7=inv0 R10=fp0,call_-1
4: (20) r0 = *(u32 *)skb[26]
5: (7b) *(u64 *)(r10 -8) = r0
6: (18) r2 = 0xffff9bde204ffa00
8: (18) r7 = 0xffffffff
10: (bf) r4 = r10
11: (07) r4 += -8
12: (bf) r1 = r6
13: (18) r3 = 0xffffffff
15: (b7) r5 = 8
16: (85) call bpf_perf_event_output#25
unknown func bpf_perf_event_output#25
Traceback (most recent call last):
File "packet_monitor.py", line 68, in <module>
function_skb_matching = bpf.load_func("packet_monitor", BPF.SOCKET_FILTER)
File "/usr/lib/python2.7/dist-packages/bcc/__init__.py", line 397, in load_func
(func_name, errstr))
TL;DR. BPF programs of type BPF_PROG_TYPE_SOCKET_FILTER can use bpf_perf_event_output only starting with Linux 5.4.
Which helpers a given BPF program has access to is defined by the get_func_proto member of objects struct bpf_verifier_ops. You can find which bpf_verifier_ops object corresponds to which program type by reading function find_prog_type() and file bpf_types.h. In the case of BPF_PROG_TYPE_SOCKET_FILTER, the corresponding function is sk_filter_func_proto().
If you git blame that function on recent kernel sources, you will get something like the following (you can do the same with GitHub's blame feature):
$ git blame net/core/filter.c
[...]
2492d3b867043 (Daniel Borkmann 2017-01-24 01:06:27 +0100 6080) static const struct bpf_func_proto *
5e43f899b03a3 (Andrey Ignatov 2018-03-30 15:08:00 -0700 6081) sk_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
2492d3b867043 (Daniel Borkmann 2017-01-24 01:06:27 +0100 6082) {
2492d3b867043 (Daniel Borkmann 2017-01-24 01:06:27 +0100 6083) switch (func_id) {
2492d3b867043 (Daniel Borkmann 2017-01-24 01:06:27 +0100 6084) case BPF_FUNC_skb_load_bytes:
2492d3b867043 (Daniel Borkmann 2017-01-24 01:06:27 +0100 6085) return &bpf_skb_load_bytes_proto;
4e1ec56cdc597 (Daniel Borkmann 2018-05-04 01:08:15 +0200 6086) case BPF_FUNC_skb_load_bytes_relative:
4e1ec56cdc597 (Daniel Borkmann 2018-05-04 01:08:15 +0200 6087) return &bpf_skb_load_bytes_relative_proto;
91b8270f2a4d1 (Chenbo Feng 2017-03-22 17:27:34 -0700 6088) case BPF_FUNC_get_socket_cookie:
91b8270f2a4d1 (Chenbo Feng 2017-03-22 17:27:34 -0700 6089) return &bpf_get_socket_cookie_proto;
6acc5c2910689 (Chenbo Feng 2017-03-22 17:27:35 -0700 6090) case BPF_FUNC_get_socket_uid:
6acc5c2910689 (Chenbo Feng 2017-03-22 17:27:35 -0700 6091) return &bpf_get_socket_uid_proto;
7c4b90d79d0f4 (Allan Zhang 2019-07-23 17:07:24 -0700 6092) case BPF_FUNC_perf_event_output:
7c4b90d79d0f4 (Allan Zhang 2019-07-23 17:07:24 -0700 6093) return &bpf_skb_event_output_proto;
2492d3b867043 (Daniel Borkmann 2017-01-24 01:06:27 +0100 6094) default:
2492d3b867043 (Daniel Borkmann 2017-01-24 01:06:27 +0100 6095) return bpf_base_func_proto(func_id);
2492d3b867043 (Daniel Borkmann 2017-01-24 01:06:27 +0100 6096) }
2492d3b867043 (Daniel Borkmann 2017-01-24 01:06:27 +0100 6097) }
[...]
As you can see, BPF_FUNC_perf_event_output was only recently added to the list of helpers these BPF programs can call. The commit which added this support, 7c4b90d79d0f4, was merged in Linux v5.4:
$ git describe --contains 7c4b90d79d0f4
v5.4-rc1~131^2~248^2~20

Setting device permission from driver code fails

I want to access I2C device driver nodes from user space in a linux kernel 3.10.14.
I added i2c-dev in the kernel configuration and got the /dev/i2c-* device nodes. However they have permission
$ ls -l /dev/i2c-*
crw------- root root 89, 1 2014-08-21 20:00 i2c-1
In drivers/i2c/i2c-dev.c I added the callback
static char *i2c_dev_devnode(struct device *dev, umode_t *mode)
{
if (!mode)
return NULL;
if (MAJOR(dev->devt) == I2C_MAJOR)
*mode = 0666;
return NULL;
}
and in the same file I added the callback to the device class struct:
static int __init i2c_dev_init(void)
{
...
i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");
...
/* set access rights */
i2c_dev_class->devnode = i2c_dev_devnode;
...
}
However the access rights of the device node remain
crw------- root root 89, 1 2014-08-21 20:00 i2c-1
There is no /lib/udev/rules.d or /etc/udev/rules.d
I would appreciate any suggestions what might go wrong here.
I am also interested in ideas how to test this issue.
You might try the following. This works at least with kernel 4.9.56.
static int my_uevent(struct device *dev, struct kobj_uevent_env *env)
{
add_uevent_var(env, "DEVMODE=%#o", 0666);
return 0;
}
static int __init i2c_dev_init(void)
{
...
i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");
...
/* set access rights */
i2c_dev_class->dev_uevent = my_uevent;
...
}
I understand the return value of devnode callback function shall not be "NULL" but device node name.
So,
Change your functions return value from "NULL" to devname. Refer the code:
----------------------patch--------------------
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index 6f638bb..35a42c6 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
## -614,6 +614,14 ## static int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action,
.notifier_call = i2cdev_notifier_call,
};
+static char *i2c_dev_devnode(struct device *dev, umode_t *mode)
+{
+ printk("\n\n****%s: %d\n\n",__func__,__LINE__);
+ if (mode != NULL)
+ *mode = 0666;
+ return kasprintf(GFP_KERNEL, "i2cr/%s", dev_name(dev));;
+}
+
/* ------------------------------------------------------------------------- */
/*
## -636,7 +644,12 ## static int __init i2c_dev_init(void)
goto out_unreg_chrdev;
}
i2c_dev_class->dev_groups = i2c_groups;
+ /* set access rights */
+ printk(KERN_INFO "i2c setting devnode\n");
+ i2c_dev_class->devnode = i2c_dev_devnode;
+
+
/* Keep track of adapters which will be added or removed later */
res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier);
if (res)
Results:
Without applying this patch:
root#x86-generic-64:~# ls -l /dev/i2c-*
crw------- 1 root root 89, 0 Nov 1 13:47 /dev/i2c-0
crw------- 1 root root 89, 1 Nov 1 13:47 /dev/i2c-1
With patch:
root#x86-generic-64:~# ls -l /dev/i2cr/*
crw-rw-rw- 1 root root 89, 0 Nov 1 13:38 /dev/i2cr/i2c-0
crw-rw-rw- 1 root root 89, 1 Nov 1 13:38 /dev/i2cr/i2c-1
Setting up device node is responsibility of udev. So we need to use correct udev rule. Further init.rc approach will fail if driver is loaded after boot time for example in case it is a loadable module. Your distribution might be using another way of supporting hotplug so we need to consult documentation about that distro.

Core data migration - Appstore build crashing on iOS 8 devices, working on iOS 9

My app store update build is crashing, it's a core data crash but I am getting this crash on only iOS 8 devices, it is working fine on iOS 9 devices.
I have correctly performed light weight migration as well added the new model version keeping the old one as a base, added the dictionary in options as well while adding "addPersistentStoreWithType".
ManagedObjectModel
lazy var managedObjectModel: NSManagedObjectModel = {
// The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model.
let modelURL = NSBundle.mainBundle().URLForResource("abcProject", withExtension: "momd")
NSLog("Url is - \(modelURL)")
return NSManagedObjectModel(contentsOfURL: modelURL!)!
}()
PersistentStoreCoordinator
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("abcProject")
var error: NSError? = nil
var failureReason = "There was an error creating or loading the application's saved data."
do {
let mOptions = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true]
NSLog("TEST564 - 7 URL - \(url)")
try coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: mOptions)
} catch var error1 as NSError {
error = error1
coordinator = nil
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error
error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("TEST564 Unresolved error \(error), \(error!.userInfo)")
abort()
} catch {
fatalError()
NSLog("TEST564 FATAL error")
}
return coordinator
}()
Above is my set of code for reference. I have searched everywhere and I get details about the light weight migration only.
Following is the device log after crash:-
> Jul 19 11:25:00 iPhone abcProject-Production[211] <Warning>: CoreData: error: -addPersistentStoreWithType:SQLite configuration:(null)
URL:file:///var/mobile/Containers/Data/Application/B12FCDA6-C91B-487E-8D03-CBBEB884996D/Documents/abcProject options:{
NSInferMappingModelAutomaticallyOption = 1;
NSMigratePersistentStoresAutomaticallyOption = 1;
} ... returned error Error Domain=NSCocoaErrorDomain Code=134130 "The operation couldn’t be completed. (Cocoa error 134130.)"
UserInfo=0x16b05490 {URL=file:///var/mobile/Containers/Data/Application/B12FCDA6-C91B-487E-8D03-CBBEB884996D/Documents/abcProject, metadata={
NSPersistenceFrameworkVersion = 519;
NSStoreModelVersionHashes = {
TabBanner = <3722cf8b 4ac58f43 20c84d7e 7d66865d a1382ecc 1ab25190 7b7c3fa7 843813fe>;
Video = <c51795f8 140c4936 de1b7615 03a944e7 f2b0451f 3c0b5887 2cfb31d3 07610d22>;
};NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers = (
""
);
NSStoreType = SQLite;
NSStoreUUID = "79788D63-BEF2-4339-BF60-1580904D9B44";
"_NSAutoVacuumLevel" = 2;
}, reason=Can't find model for source store} with userInfo dictionary {
URL = "file:///var/mobile/Containers/Data/Application/B12FCDA6-C91B-487E-8D03-CBBEB884996D/Documents/abcProject";
metadata = {
NSPersistenceFrameworkVersion = 519;
NSStoreModelVersionHashes = {
TabBanner = <3722cf8b 4ac58f43 20c84d7e 7d66865d a1382ecc 1ab25190 7b7c3fa7 843813fe>;
Video = <c51795f8 140c4936 de1b7615 03a944e7 f2b0451f 3c0b5887 2cfb31d3 07610d22>;
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers = (
""
);
NSStoreType = SQLite;
NSStoreUUID = "79788D63-BEF2-4339-BF60-1580904D9B44";
"_NSAutoVacuumLevel" = 2;
};
reason = "Can't find model for source store";
}
Jul 19 11:25:00 iPhone abcProject-Production[211] <Warning>: CoreData: annotation: NSPersistentStoreCoordinator's current model hashes are {
TabBanner = <2efd2387 6f370f71 d585132f 9d6aa8fe afcdc841 ef6e9b89 396625d1 cbc99cea>;
Video = <c51795f8 140c4936 de1b7615 03a944e7 f2b0451f 3c0b5887 2cfb31d3 07610d22>;
}
Jul 19 11:25:00 iPhone abcProject-Production[211] <Warning>: Unresolved error Optional(Error Domain=YOUR_ERROR_DOMAIN Code=9999 "Failed to initialize the application's saved data" UserInfo=0x168e0c90 {NSLocalizedDescription=Failed to initialize the application's saved data, NSUnderlyingError=0x16b05350 "The operation couldn’t be completed. (Cocoa error 134130.)", NSLocalizedFailureReason=There was an error creating or loading the application's saved data.}), [NSLocalizedDescription: Failed to initialize the application's saved data, NSUnderlyingError: Error Domain=NSCocoaErrorDomain Code=134130 "The operation couldn’t be completed. (Cocoa error 134130.)"
UserInfo=0x16b05490 {URL=file:///var/mobile/Containers/Data/Application/B12FCDA6-C91B-487E-8D03-CBBEB884996D/Documents/abcProject, metadata={
NSPersistenceFrameworkVersion = 519;
NSStoreModelVersionHashes = {
TabBanner = <3722cf8b 4ac58f43 20c84d7e 7d66865d a1382ecc 1ab25190 7b7c3fa7 843813fe>;
Video = <c51795f8 140c4936 de1b7615 03a944e7 f2b0451f 3c0b5887 2cfb31d3 07610d22>;
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers = (
""
);
NSStoreType = SQLite;
NSStoreUUID = "79788D63-BEF2-4339-BF60-1580904D9B44";
"_NSAutoVacuumLevel" = 2;
}, reason=Can't find model for source store}, NSLocalizedFailureReason: There was an error creating or loading the application's saved data.]
Jul 19 11:25:01 iPhone ReportCrash[212] <Error>: task_set_exception_ports(B07, 400, D03, 0, 0) failed with error (4: (os/kern) invalid argument)
Jul 19 11:25:01 iPhone ReportCrash[212] <Notice>: ReportCrash acting against PID 211
Jul 19 11:25:01 iPhone ReportCrash[212] <Notice>: Formulating crash report for process abcProject-Production[211]
Jul 19 11:25:01 iPhone SpringBoard[43] <Warning>: BSXPCMessage received error for message: Connection invalid
Jul 19 11:25:01 iPhone SpringBoard[43] <Warning>: Unable to get short BSD proc info for 211: No such process
Jul 19 11:25:01 iPhone SpringBoard[43] <Warning>: Unable to get short BSD proc info for 211: No such process
Jul 19 11:25:01 iPhone mediaserverd[37] <Notice>: '' com.abcProject(pid = 211) setting DiscoveryMode = DiscoveryMode_None, currentDiscoveryMode = DiscoveryMode_None
Jul 19 11:25:01 iPhone wifid[69] <Notice>: WiFi:[490600501.266659]: Foreground Network Application exited.
Jul 19 11:25:01 iPhone AppStore[175] <Warning>: [SSMetricsEventController] Direct-access controller is calling through XPC to flush Unreported Events
Jul 19 11:25:01 iPhone wifid[69] <Notice>: WiFi:[490600501.267352]: BG Application: Not Present, BG Daemon: Present. Daemons: apsd itunesstored networkd
Jul 19 11:25:01 iPhone locationd[64] <Notice>: Gesture EnabledForTopCLient: 0, EnabledInDaemonSettings: 0
Jul 19 11:25:01 iPhone com.apple.xpc.launchd[1] (UIKitApplication:com.abcProject[0xb6e0][211]) <Notice>: Service exited due to signal: Abort trap: 6
Jul 19 11:25:01 iPhone com.apple.xpc.launchd[1] (UIKitApplication:com.abcProject[0xb6e0]) <Notice>: Service only ran for 6 seconds. Pushing respawn out by 2147483641 seconds.
Jul 19 11:25:01 iPhone locationd[64] <Notice>: Gesture EnabledForTopCLient: 0, EnabledInDaemonSettings: 0
Jul 19 11:25:01 iPhone SpringBoard[43] <Warning>: Application 'UIKitApplication:com.abcProject[0xb6e0]' crashed.
Jul 19 11:25:01 iPhone assertiond[58] <Warning>: pid_suspend failed for <BKNewProcess: 0x1668b480; com.abcProject; pid: 211; hostpid: -1>: Unknown error: -1, Unknown error: -1
Jul 19 11:25:01 iPhone assertiond[58] <Warning>: Could not set priority of <BKNewProcess: 0x1668b480; com.abcProject; pid: 211; hostpid: -1> to 2, priority: No such process
Jul 19 11:25:01 iPhone assertiond[58] <Warning>: Could not set priority of <BKNewProcess: 0x1668b480; com.abcProject; pid: 211; hostpid: -1> to 4096, priority: No such process
Jul 19 11:25:01 iPhone UserEventAgent[17] <Warning>: id=com.abcProject pid=211, state=0
Jul 19 11:25:01 iPhone ReportCrash[212] <Notice>: Saved report to /var/mobile/Library/Logs/CrashReporter/abcProject-Production_2016-07-19-112501_iPhone.ips
Jul 19 11:25:06 iPhone wifid[69] <Notice>: WiFi:[490600506.681414]: WiFi unquiescing requested by "locationd"
Jul 19 11:25:06 iPhone wifid[69] <Notice>: WiFi:[490600506.686744]: WiFi unquiescing requested by "locationd"
Jul 19 11:25:06 iPhone wifid[69] <Notice>: WiFi:[490600506.743193]: WiFi unquiescing requested by "locationd"
Jul 19 11:25:08 iPhone wifid[69] <Notice>: WiFi:[490600508.843256]: Client itunesstored set type to normal application
Jul 19 11:25:08 iPhone wifid[69] <Notice>: WiFi:[490600508.844080]: __WiFiManagerSetEnableState: state TRUE, manager->enable.setting TRUE, manager->unlockedSinceBoot TRUE
Jul 19 11:25:08 iPhone wifid[69] <Notice>: WiFi:[490600508.845449]: BG Application: Not Present, BG Daemon: Present. Daemons: apsd networkd
Jul 19 11:25:09 iPhone locationd[64] <Notice>: Gesture EnabledForTopCLient: 0, EnabledInDaemonSettings: 0
Jul 19 11:25:12 iPhone aggregated[29] <Warning>: Scheduling parameters: 0 minutes before midnight, 4.0 time(s)/day
Jul 19 11:25:12 iPhone aggregated[29] <Warning>: delay: 595 into interval 21600 => 22195
Jul 19 11:25:12 iPhone aggregated[29] <Warning>: Next ADDaily run scheduled in 06:09:55 at 2016-07-19 12:05:07 +0000
Jul 19 11:25:12 iPhone addaily[213] <Warning>: addaily started
Jul 19 11:25:12 iPhone addaily[213] <Warning>: daily tasks for day 17000
Jul 19 11:25:13 iPhone addaily[213] <Warning>: Filtering only beta sessions
Jul 19 11:25:13 iPhone addaily[213] <Warning>: Saved Sessions as /var/mobile/Library/Logs/CrashReporter/log-sessions-2016-07-19-112513.session
Jul 19 11:25:23 iPhone addaily[213] <Warning>: addaily ended
The error, Can't find model for source store says that when the app tried to migrate the persistent store, it could not find the data model that had been used to create the store. Data migration requires both the old and new data stores. The old one is used to load the data, and the new one is used to update the data for future use.
The reason this works on iOS 9 is that iOS 9 added model caching for use in lightweight migrations of SQLite stores. On iOS 9 you can therefore get a successful migration without the old model, because the old version will be automatically cached. This feature was not available on iOS 8, so if you're still supporting 8 then you still need to include the old version of the model in your app.
Finally I got it resolved by doing a simple change .
Earlier code :-
url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("abcProject1")
Fixed code :-
url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("abcProject1.sqlite")
adding <.sqlite> extension to my url path solved the issue for me.
It is fully tested with all the possible scenarios.
Thank you all for your help.
To avoid the crash I created new database for iOS 8 because I didnt need existing data that much.
I changed my storeURL from
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("abcProject")
to
let url:NSURL
if (OS_VERSION<9.0)
{
url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("abcProject1")
}
else
{
url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("abcProject")
}
This fixed the crash for me.

Why makes calling error or done in a BodyParser's Iteratee the request hang in Play Framework 2.0?

I am trying to understand the reactive I/O concepts of Play 2.0 framework. In order to get a better understanding from the start I decided to skip the framework's helpers to construct iteratees of different kinds and to write a custom Iteratee from scratch to be used by a BodyParser to parse a request body.
Starting with the information available in Iteratees and ScalaBodyParser docs and two presentations about play reactive I/O this is what I came up with:
import play.api.mvc._
import play.api.mvc.Results._
import play.api.libs.iteratee.{Iteratee, Input}
import play.api.libs.concurrent.Promise
import play.api.libs.iteratee.Input.{El, EOF, Empty}
01 object Upload extends Controller {
02 def send = Action(BodyParser(rh => new SomeIteratee)) { request =>
03 Ok("Done")
04 }
05 }
06
07 case class SomeIteratee(state: Symbol = 'Cont, input: Input[Array[Byte]] = Empty, received: Int = 0) extends Iteratee[Array[Byte], Either[Result, Int]] {
08 println(state + " " + input + " " + received)
09
10 def fold[B](
11 done: (Either[Result, Int], Input[Array[Byte]]) => Promise[B],
12 cont: (Input[Array[Byte]] => Iteratee[Array[Byte], Either[Result, Int]]) => Promise[B],
13 error: (String, Input[Array[Byte]]) => Promise[B]
14 ): Promise[B] = state match {
15 case 'Done => { println("Done"); done(Right(received), Input.Empty) }
16 case 'Cont => cont(in => in match {
17 case in: El[Array[Byte]] => copy(input = in, received = received + in.e.length)
18 case Empty => copy(input = in)
19 case EOF => copy(state = 'Done, input = in)
20 case _ => copy(state = 'Error, input = in)
21 })
22 case _ => { println("Error"); error("Some error.", input) }
23 }
24 }
(Remark: All these things are new to me, so please forgive if something about this is total crap.)
The Iteratee is pretty dumb, it just reads all chunks, sums up the number of received bytes and prints out some messages. Everything works as expected when I call the controller action with some data - I can observe all chunks are received by the Iteratee and when all data is read it switches to state done and the request ends.
Now I started to play around with the code because I wanted to see the behaviour for these two cases:
Switching into state error before all input is read.
Switching into state done before all input is read and returning a Result instead of the Int.
My understanding of the documentation mentioned above is that both should be possible but actually I am not able to understand the observed behaviour. To test the first case I changed line 17 of the above code to:
17 case in: El[Array[Byte]] => copy(state = if(received + in.e.length > 10000) 'Error else 'Cont, input = in, received = received + in.e.length)
So I just added a condition to switch into the error state if more than 10000 bytes were received. The output I get is this:
'Cont Empty 0
'Cont El([B#38ecece6) 8192
'Error El([B#4ab50d3c) 16384
Error
Error
Error
Error
Error
Error
Error
Error
Error
Error
Error
Then the request hangs forever and never ends. My expectation from the above mentioned docs was that when I call the error function inside fold of an Iteratee the processing should be stopped. What is happening here is that the Iteratee's fold method is called several times after error has been called - well and then the request hangs.
When I switch into done state before reading all input the behaviour is quite similar. Changing line 15 to:
15 case 'Done => { println("Done with " + input); done(if (input == EOF) Right(received) else Left(BadRequest), Input.Empty) }
and line 17 to:
17 case in: El[Array[Byte]] => copy(state = if(received + in.e.length > 10000) 'Done else 'Cont, input = in, received = received + in.e.length)
produces the following output:
'Cont Empty 0
'Cont El([B#16ce00a8) 8192
'Done El([B#2e8d214a) 16384
Done with El([B#2e8d214a)
Done with El([B#2e8d214a)
Done with El([B#2e8d214a)
Done with El([B#2e8d214a)
and again the request hangs forever.
My main question is why the request is hanging in the above mentioned cases. If anybody could shed light on this I would greatly appreciate it!
Your understanding is perfectly right and I have just push a fix to master:
https://github.com/playframework/Play20/commit/ef70e641d9114ff8225332bf18b4dd995bd39bcc
Fixed both cases plus exceptions in the Iteratees.
Nice use of copy in case class for doing an Iteratee BTW.
Things must have changed with Play 2.1 - Promise is no longer parametric, and this example no longer compiles.

mmap brokes after strdup

I tried the following configuration with mmap:
open file (file is over 2 kB)
request statistics from file *f_file*
map file (file is smaller than a page, offset page 0, size is expected size)
verify values of *f_footer* in the map *f_fpage*
usage strdup
Code:
union{
...
struct {
char *f_fname;
struct clog_footer *f_footer;
char *f_fpage;
size_t f_size;
} f_ring; /* circular log file */
char *f_fname; /* Name use for Files|Pipes|TTYs. */
} f_un;
...
struct clog_footer {
uint32_t cf_magic;
};
...
1995 f->f_file = open(p+1, O_RDWR, 0 );
1996 if (f->f_file == -1) {
2000 }
2001 if (fstat(f->f_file,&sb)<0) {
2006 }
2014 f->f_un.f_ring.f_fpage = mmap(NULL,sb.st_size,PROT_READ|PROT_WRITE,MAP_SHARED,f->f_file,0);
2015 if (f->f_un.f_ring.f_fpage == MAP_FAILED) {
2020 }
2021 f->f_un.f_ring.f_footer = (struct clog_footer*)(f->f_un.f_ring.f_fpage + sb.st_size-sizeof(struct clog_footer));
2022 if (memcmp(&(f->f_un.f_ring.f_footer->cf_magic),MAGIC_CONST,4)!=0) {
2029 }
2031 f->f_un.f_fname = strdup (p+1);
...
I used read/write, file is filled with zero's up to 2 Kb. I parametrized mmap with file size and zero page size, but mmap fails to map the file.
Should the file to map have additional properties?
Is "0" a acceptable parameter as offset in mmap, once i want to map the file from beginning?