Leaks in JVM from Valgrind - jvm

First time I used JNI to access a c library and I thought of using valgrind to check for any memory leaks. Valgrind reported so many leaks in jvm.:(
Used Push/Poplocal frame for managing local references and of course releasing references from Get(UTFChars/Arrays) which needs be. Aside from that it also reports a possible lost in AttachCurrentThread method when in fact I detached it successfully through DetachCurrentThread in my call back function.
And now I just need advise/explanation that the reported leaks were not true at all and will not affect my application especially its on the server side. Well for me I suspect that the unloading of the library and destroying had not yet been done after my app exits and valgrind already did its checking part. Hope to hear from anyone who had experience this kind of case as well.
//sample code
void event_callback(void .., int ..)
{
printf("--Enter event_callback Function--\n");
int detach = 0;
//store our jnienv for this thread
JNIEnv *g_env = NULL;
// if our jni env is not attached for this thread, then we will attach it
int getEnvStat = (*g_jvm)->GetEnv(g_jvm, (void **)&g_env, JNI_VERSION_1_6);
if (getEnvStat == JNI_EDETACHED)
{
//if not attached, then lets attached g_env
printf("JNIEnv not attached. Attaching..\n");
if ((*g_jvm)->AttachCurrentThread(g_jvm, (void **) &g_env, NULL) != 0)
{
printf("Failed to attach\n");
return;
}
else
{
detach = 1;
}
}
else if (getEnvStat == JNI_OK)
{
printf("GetEnv: jenv is just OK, already attached.\n");
}
else if (getEnvStat == JNI_EVERSION)
{
printf("GetEnv: version not supported\n");
return;
}
if((*g_env)->PushLocalFrame(g_env, 10)<0)
{
printf("Out of memory\n");
}
//...some useful code here
(*g_env)->PopLocalFrame(g_env, NULL);
if(detach == 1)
{
int result = (*g_jvm)->DetachCurrentThread(g_jvm);
printf("DetachCurrentThread result: %d\n", result);
}
printf("--Exit event_callback Function--\n");
}
Report:
==20914== 432 bytes in 1 blocks are possibly lost in loss record 903 of 1,035
==20914== at 0x4028876: malloc (vg_replace_malloc.c:236)
==20914== by 0x4950461: os::malloc(unsigned int) (in /usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/client/libjvm.so)
==20914== by 0x464470C: CHeapObj::operator new(unsigned int) (in /usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/client/libjvm.so)
==20914== by 0x496BB13: ParkEvent::Allocate(Thread*) (in /usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/client/libjvm.so)
==20914== by 0x4A13CCD: Thread::Thread() (in /usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/client/libjvm.so)
==20914== by 0x4A15091: JavaThread::JavaThread(bool) (in /usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/client/libjvm.so)
==20914== by 0x4853723: attach_current_thread.isra.103.part.104 (in /usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/client/libjvm.so)
==20914== by 0x7B17791: event_callback (in /home/Wrapper/TJNIBridge/libJNIBridge.so)
==20914== by 0x7B44431: xmpp_event_main (my_xmpp.c:562)
==20914== by 0x412146D: clone (clone.S:130)
I also pasted some of the reported leaks below all from jvm lib.
==20914== 4,612 (1,284 direct, 3,328 indirect) bytes in 1 blocks are definitely lost in loss record 1,009 of 1,035
==20914== at 0x4028876: malloc (vg_replace_malloc.c:236)
==20914== by 0x4950461: os::malloc(unsigned int) (in /usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/client/libjvm.so)
==20914== by 0x464470C: CHeapObj::operator new(unsigned int) (in /usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/client/libjvm.so)
==20914== by 0x4A14BE9: WatcherThread::start() (in /usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/client/libjvm.so)
==20914== by 0x4A192DF: Threads::create_vm(JavaVMInitArgs*, bool*) (in /usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/client/libjvm.so)
==20914== by 0x4865BD8: JNI_CreateJavaVM (in /usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/client/libjvm.so)
==20914== by 0x41ECD30: start_thread (pthread_create.c:304)
==20914== by 0x412146D: clone (clone.S:130)
==20914== 8 bytes in 1 blocks are definitely lost in loss record 41 of 1,035
==20914== at 0x4028876: malloc (vg_replace_malloc.c:236)
==20914== by 0x4950461: os::malloc(unsigned int) (in /usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/client/libjvm.so)
==20914== by 0x464470C: CHeapObj::operator new(unsigned int) (in /usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/client/libjvm.so)
==20914== by 0x470E29D: CSpaceCounters::CSpaceCounters(char const*, int, unsigned int, ContiguousSpace*, GenerationCounters*) (in /usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/client/libjvm.so)
==20914== by 0x47A3BF9: DefNewGeneration::DefNewGeneration(ReservedSpace, unsigned int, int, char const*) (in /usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/client/libjvm.so)
==20914== by 0x47FC623: GenerationSpec::init(ReservedSpace, int, GenRemSet*) (in /usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/client/libjvm.so)
==20914== by 0x47EF9D4: GenCollectedHeap::initialize() (in /usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/client/libjvm.so)
==20914== by 0x4B95FF3: ??? (in /usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/client/libjvm.so)
Ubuntu 11.10
OpenJDK 7

The JVM and Valgrind don't get along. Just running the JVM under Valgrind with no input for me gives tons of warnings.
You will need to generate suppressions for the JVM errors.
Try disabling JIT.

Related

Realm Objective-C migration error

I am seeing crashes via Crashlytics and hearing from customers that the application is crashing right as they open it.
This is narrowed down to the application migrating one of the realm databases. I have not been able to recreate the issue unfortunately because I am not able to make any sense of the error I am seeing.
I have logic that checks when the app starts up to check and see if the realm needs to be compacted. When doing that the realm determines that it needs to be migrated and hit the migration block.
config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) {
if (oldSchemaVersion < 17) {
[migration enumerateObjects:Event.className block:^(RLMObject *oldObject, RLMObject *newObject) {
NSString *className = [[oldObject[#"endDateTime"] objectSchema] className];
if ([className isEqualToString:#"DateObject"]) {
newObject[#"endDateTime"] = oldObject[#"endDateTime"][#"value"];
}
}];
}
};
Due to a mistake on my end when doing previous migrations I was manually checking to see if a property if of a specific type before deciding to migrate it.
Unfortunately when doing so the oldObject which should be of type RLMObject seems to be of type NSTaggedDate according to Crashlytics
[__NSTaggedDate objectSchema]: unrecognized selector sent to instance 0xe41bf592ee000000
Fatal Exception: NSInvalidArgumentException
0 CoreFoundation 0x186419d04 __exceptionPreprocess
1 libobjc.A.dylib 0x185668528 objc_exception_throw
2 CoreFoundation 0x1864271c8 __methodDescriptionForSelector
3 CoreFoundation 0x18641f6b0 ___forwarding___
4 CoreFoundation 0x18630501c _CF_forwarding_prep_0
5 MY_mobile_ios_common 0x10199c8c0 __34+[MYRealm getRealmConfigByName:]_block_invoke_2 (MYRealm.m:44)
6 Realm 0x1011b6598 -[RLMMigration enumerateObjects:block:] (RLMMigration.mm:99)
7 MY_mobile_ios_common 0x10199c830 __34+[MYRealm getRealmConfigByName:]_block_invoke (MYRealm.m:40)
8 Realm 0x1011b6ab4 -[RLMMigration execute:] (RLMMigration.mm:131)
9 Realm 0x1012297ec std::__1::__function::__func<+[RLMRealm realmWithConfiguration:error:]::$_1, std::__1::allocator<+[RLMRealm realmWithConfiguration:error:]::$_1>, void (std::__1::shared_ptr<realm::Realm>, std::__1::shared_ptr<realm::Realm>, realm::Schema&)>::operator()(std::__1::shared_ptr<realm::Realm>&&, std::__1::shared_ptr<realm::Realm>&&, realm::Schema&) (RLMRealm.mm:410)
10 Realm 0x10124fa90 std::__1::__function::__func<realm::Realm::update_schema(realm::Schema, unsigned long long, std::__1::function<void (std::__1::shared_ptr<realm::Realm>, std::__1::shared_ptr<realm::Realm>, realm::Schema&)>, std::__1::function<void (std::__1::shared_ptr<realm::Realm>)>, bool)::$_2, std::__1::allocator<realm::Realm::update_schema(realm::Schema, unsigned long long, std::__1::function<void (std::__1::shared_ptr<realm::Realm>, std::__1::shared_ptr<realm::Realm>, realm::Schema&)>, std::__1::function<void (std::__1::shared_ptr<realm::Realm>)>, bool)::$_2>, void ()>::operator()() (memory:4625)
11 Realm 0x101181f64 realm::ObjectStore::apply_schema_changes(realm::Group&, unsigned long long, realm::Schema&, unsigned long long, realm::SchemaMode, std::__1::vector<realm::SchemaChange, std::__1::allocator<realm::SchemaChange> > const&, std::__1::function<void ()>) (object_store.cpp:753)
12 Realm 0x10124bbb8 realm::Realm::update_schema(realm::Schema, unsigned long long, std::__1::function<void (std::__1::shared_ptr<realm::Realm>, std::__1::shared_ptr<realm::Realm>, realm::Schema&)>, std::__1::function<void (std::__1::shared_ptr<realm::Realm>)>, bool) (functional:1860)
13 Realm 0x101226a10 +[RLMRealm realmWithConfiguration:error:] (functional:1860)
14 MY_mobile_ios_common 0x10199cba0 +[MYRealm mainRealmCompact] (MYRealm.m:137)
15 MY App 0x1002b49dc -[AppDelegate compactRealmIfNeeded] (AppDelegate.m:808)
16 MY App 0x1002af940 -[AppDelegate application:didFinishLaunchingWithOptions:] (AppDelegate.m:48)
Any thoughts on what I could be doing wrong here, am about to just delete the realm databases and force the users to go back through the initial loading of data again.
ProductName: Mac OS X
ProductVersion: 10.12.6
BuildVersion: 16G1036
/Applications/Xcode.app/Contents/Developer
Xcode 9.1
Build version 9B55
/usr/local/bin/pod
1.3.1
Realm (2.10.2)
Realm (= 2.10.2)
/bin/bash
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16)
(not in use here)
/usr/local/bin/git
git version 2.12.2
The crash log is telling you that your call to [oldObject[#"endDateTime"] objectSchema] is seeing oldObject[#"endDateTime"] evaluate to an NSDate, which does not respond to -objectSchema. If the endDateTime property can be of different types depending on which schema version you're updating from, you'll need to do further checks on the object before sending -objectSchema to it.

Swift Singleton Memory Leak

I'm using a singleton as a container for localization strings, dictionary keys, and notification names used throughout the app. It is initialized as follows:
class ConstantsManager {
private init() {}
class var sharedInstance: ConstantsManager {
struct Static {
static let instance: ConstantsManager! = ConstantsManager()
}
return Static.instance
}
let localization = "NSLocalizedString(etc.)"
let dictKey = "aKey"
let notificationName = Notification.Name("name")
}
The first use of the singleton occurs in AppDelegate's application(_ application: didFinishLaunchingWithOptions:). When Instruments / Leaks reaches
let manager = ConstantsManager.sharedInstance
a leak is indicated. Does the call tree below indicate that initialization is occurring twice? I'm wondering if the properties associated with a second initialization represent the leak. Strangely, the leak doesn't occur on the simulator. (I'm using Xcode 8.2.1 and OS X 10.12.3 for iOS 10.2 deployment.)
Bytes Used # Leaks Symbol Name
448 Bytes 100.0% 14 ConstantsManager.init() -> ConstantsManager
448 Bytes 100.0% 14 ConstantsManager.__allocating_init() -> ConstantsManager
448 Bytes 100.0% 14 globalinit_33_8D935C4E2193156DAA2AB3DF99F55E80_func0
448 Bytes 100.0% 14 static ConstantsManager.(sharedInstance.getter).(Static #1).instance.unsafeMutableAddressor
448 Bytes 100.0% 14 static ConstantsManager.sharedInstance.getter
448 Bytes 100.0% 14 AppDelegate.registerUserDefaults() -> ()
448 Bytes 100.0% 14 AppDelegate.application(UIApplication, didFinishLaunchingWithOptions : [UIApplicationLaunchOptionsKey : Any]?) -> Bool
448 Bytes 100.0% 14 #objc AppDelegate.application(UIApplication, didFinishLaunchingWithOptions : [UIApplicationLaunchOptionsKey : Any]?) -> Bool
448 Bytes 100.0% 14 main

Stack overflow in release binary but not in Xcode-Debugger

My (Cocoa)-App runs perfectly fine when I start it from within Xcode. However when I archive / release it, that version will crash. The error reporter that pops open says:
[...]
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Application Specific Information:
[9082] stack overflow
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x00007fff944a7212 __pthread_kill + 10
1 libsystem_c.dylib 0x00007fff9290caf4 pthread_kill + 90
2 libsystem_c.dylib 0x00007fff92950e9e __abort + 159
3 libsystem_c.dylib 0x00007fff92951d17 __stack_chk_fail + 195
[...]
While it also gives me the line of code where execution stopped, this really does not help me as the exact same code path is executed in debug mode (but succeedes).
So I'm wondering: might it actually be that the stack sizes are different for a release and a debug version? And how big is the stack after all on a Mac (64 bit / Mountain Lion)? I'm not aware of putting insanely much data on the stack...
If I have too much data on the stack, what patterns would I need to avoid to reduce my stack load?
[Update]
ok, I got my App running by adding the -fno-stack-protector flag. (BTW: I'm compiling with LLVM)
Before that, I stepped through the crashing code line by line and found the following bahaviour which I don't understand:
the method foo(x) calls bacon(x). x is 8 and is handed from foo to bacon without modification. Yet when I step into bacon(x), x suddenly is 4295939448 (each time). If I set -fno-stack-protector the value is correct.
To my naive eyes, this looks as if the stack-protector sets the magic value 4295939448 somewhere in the stack and makes it read-only. And while my functions put their parameters on the stack, at some point parameter x happens to be put on that magic address and thus cannot be written (subsequent parameters seem to be written correctly). In my case x is a buffer length parameter, which naturally leads to a buffer-overflow and crash.
Does somebody have a deeper understanding of the stack-protector? Why is this happening? And in what cases is it safe and legal to disable the stack-protector and in what cases is it dangerous?
[Update 2: Original Code]
This method calls the other Decrypt below. stIVLen at that point is 8
BOOL CEracomSE::Decrypt(
PBYTE pMsg, size_t stLen,
const CSK* pKey /* = NULL */,
PBYTE pIV /* = NULL */, size_t stIVLen /* = 0 */,
FBM fbm /* = FBM_CBC */,
PADDING padding /* = NO_PADDING */
)
{
//stIVLen == 8
return Decrypt( (uint64_t)0, pMsg, stLen, pKey, pIV, stIVLen, fbm, padding );
}
When Decrypt is called stIVLen is 4295939448, the other parameter are still correct
BOOL CEracomSE::Decrypt(
uint64_t qwOffset,
PBYTE pMsg, size_t stLen,
const CSK* pKey /* = NULL */,
PBYTE pIV /* = NULL */, size_t stIVLen /* = 0 */,
FBM fbm /* = FBM_CBC */,
PADDING padding /* = NO_PADDING */
)
{
//stIVLen now is 4295939448
BYTE a_iv[16] = {0};
size_t a_iv_len;
BYTE a_key[32] = {0};
size_t a_key_len = 0;
size_t nBytes;
size_t nDataOffset;
size_t nRemainingData = stLen;
bool ret;
//[...]
}
I recently faced this situation with my app. I know its an old thread but responding anyways with the intent that someone else could benefit from the findings.
Passing -fno-stack-protector did solve the problem as suggested in the question. However, digging a little deeper we found that, changing all occurrences of literal array declaration to a longer declaration did solve the problem without passing the compiler flag.
so changing all occurrences of
#[#(1), #(2)]
to
[NSArray arrayWithObjects:#(1), #(2), nil]
May be its specific to our app only but hope it helps others as well.

OSX - NSLog prevents application crash in debug mode

Developing an app for OSX. There's still bugs and it crashes in release builds.
However, it runs in debug builds, when there's a blank NSLog statement in a few spots. If the NSLog statements are removed, the app crashes on run.
The first statement, in a run loop (prints calculated ticks and drawn frames, it simulates a fluid in an NSView)
NSLog(#"%d ticks, %d frames", ticks, frames);
The second statement, in the tick method that gets called every loop,
NSLog(#"");
In debug mode, running from Xcode, it works just fine with these two statements. If either is removed, it crashes. After several hours searching, I can't find any reference to apps crashing without blank NSLog statements.
Edit: The final question is: Is there anything I should look out for that might be causing this?
Edit 2: The run and tick methods are
-(void) run {
timeval start = gettime();
timeval end = gettime();
float dt = 1./60;
self.E.dt = dt;
float tick = 1e6*dt;
float unprocessed;
int ticks = 0;
int frames = 0;
timeval now;
while ( TRUE ) {
now = gettime();
unprocessed += diff(end, now)/tick;
end = now;
BOOL shouldRender = true; // set false to limit framerate to tickrate
while ( unprocessed >= 1 ) {
ticks++;
[self tick];
unprocessed -= 1;
shouldRender = true;
}
if ( shouldRender ) {
frames++;
}
if ( diff(start, gettime()) > 1000000 ) {
start.tv_sec += 1;
NSLog(#"%d ticks, %d frames", ticks, frames);
frames = 0;
ticks = 0;
}
}
}
-(void) tick {
NSLog(#"");
NSDictionary* fs = [NSDictionary dictionaryWithObjectsAndKeys:self.u, #"u", self.v, #"v", self.p, #"p", self.T, "#T", nil];
NSDictionary* gs = [self.E evolve:fs];
[self.u swap:[gs objectForKey:#"u"]];
[self.v swap:[gs objectForKey:#"v"]];
[self.p swap:[gs objectForKey:#"p"]];
[self.T swap:[gs objectForKey:#"T"]];
[self.view setNeedsDisplay:YES];
}
Edit 3: This is clearly an issue with LLVM. When I compile with GCC, I get no crash. Unfortunately there's an extraordinary amount of memory leaks now due to no ARC. Confusion level increased.
Edit 4: Backtrace
Crashed Thread: 2
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000010
External Modification Warnings:
Debugger attached to process.
VM Regions Near 0x10:
-->
__TEXT 0000000103a9b000-0000000103a9c000 [ 4K] r-x/rwx SM=COW /Users/USER/Library/Developer/Xcode/DerivedData/Splash-ahjwbarsbqqbuzfcnxstxpslekdi/Build/Products/Debug/Splash.app/Contents/MacOS/Splash
Application Specific Information:
objc_msgSend() selector name: copy
objc[32100]: garbage collection is OFF
Thread 2 Crashed:
0 libobjc.A.dylib 0x00007fff8e43ee90 objc_msgSend + 16
1 com.apple.CoreFoundation 0x00007fff87edf8ac -[__NSPlaceholderDictionary initWithObjects:forKeys:count:] + 668
2 com.apple.CoreFoundation 0x00007fff87efcd13 +[NSDictionary dictionaryWithObjectsAndKeys:] + 1203
3 com.mbarriault.Splash 0x0000000103a9d488 -[Game tick] + 328 (Game.m:95)
4 com.mbarriault.Splash 0x0000000103a9d2a9 -[Game run] + 361 (Game.m:76)
5 com.apple.Foundation 0x00007fff9020874e -[NSThread main] + 68
6 com.apple.Foundation 0x00007fff902086c6 __NSThread__main__ + 1575
7 libsystem_c.dylib 0x00007fff8dba18bf _pthread_start + 335
8 libsystem_c.dylib 0x00007fff8dba4b75 thread_start + 13
Thread 2 crashed with X86 Thread State (64-bit):
rax: 0x0000000103aa5a00 rbx: 0x0000000000000004 rcx: 0x0000000000000000 rdx: 0x0000000000000000
rdi: 0x0000000103aa3071 rsi: 0x00007fff8f9ea7d0 rbp: 0x0000000107b47970 rsp: 0x0000000107b47900
r8: 0x0000000000000004 r9: 0x0000000103aa5ab0 r10: 0x0000000000000001 r11: 0x0000000000000000
r12: 0x0000000000000003 r13: 0x0000000107b47928 r14: 0x0000000107b479a0 r15: 0x0000000107b47980
rip: 0x00007fff8e43ee90 rfl: 0x0000000000010202 cr2: 0x0000000000000010
Logical CPU: 3
I removed ID information and the logs for threads that didn't crash, as the whole log went over the post length limit.
Edit 5: Changing the dictionary creation from NSDictionary:dictionaryWithObjectsAndKeys: to NSDictionary:dictionaryWithObjects:forKeys: seems to have fixed all my problems. I'm not entirely certain why, but I'll take it! Thanks everyone!
Edit 6: The correct answer, believe if you will, was a simple typo in a string.
From the look of the backtrace it is crashing when allocating the NSDictionary. Probably one of the object references being used to initialize the NSDictionary is invalid. If you post code from the tick method it could help narrow down what the problem is. Also, if you try debugging with NSZombie on it could tell us which object type it is crashing on.
Edit:
OK. Now that I see the tick code, I can see the problem. I didn't see it at first, but you are using the c-string "#T", which you probably intended to be #"T".

valgrind - invalid write size

we have couple of C applications which talk using the shared memory. first application adds the message and the second one always reads from the shared memory.
struct messagestruct {
unsigned int sessionid;
uint8_t message[16]; //unsigned 8bit int
}__attribute__ ((__packed__));
we need to have 3 sessions (for 3 users). so defined shared memory size as
#define SHARED_SIZE ( 3 * sizeof(messagestruct)) + sizeof(int)
we access the shared memory as
int sesskey = ftok("/path/to/a/file", "B");
int shmemoryid = shmget(sesskey, SHARED_SIZE, 0666 | IPC_CREAT);
during copying structs to shared memory, valgrind reports error (invalid write size 1)
void *shmaddr = shmat(shmemoryid, NULL, 0);
int *sessnum;
struct messagestruct *msgstruct;
sessnum = (int *)shmaddr;
msgstruct = (struct messagestruct*)((void*) shmaddr + sizeof(int));
memcpy(shmaddr, currentsessionsstruct, SHARED_SIZE); //-->valgrind error invalid write size 1
thanks for any helpful info.
memcpy(shmaddr, currentsessionsstruct, SHARED_SIZE);
You are copying 3 * sizeof(messagestruct) + sizeof(int). I believe you want to copy only sizeof(currentsessionstruct).