Why page fault is considered as trap instead of interrupt?
And what exactly is the stages take place when you try access null pointer until you get segmentation fault? and the signal which is sent in this situations I SIGILL, right?
Thanks!
A trap is an exception in user-space caused by the user-space program. In this specific case the user-space program accessed a page that was not mapped using the memory management unit (MMU) and therefore caused the trap. Interrupts on the other hand are generated by external hardware events, such as a timer.
Related
I have a situation in my renderer where I load some DLLs and perform some validation within them. When the validation fails, I throw an exception from the DLL to exit the renderer with a MessageBox detailing the error, and also logging the error to a file. Because of funkyness with throwing exceptions across DLLs, in order for Windows not to terminate the EXE, I purposely leak some std::unique_ptr objects by doing obj.release(), when the renderer is exiting via an exception. The idea is that, since we're exiting via an exceptional circumstance, the leaking of these objects is acceptable because the OS will cleanup the memory at app exit.
I'm running into a problem with AMD's Vulkan Memory Allocator. The allocator does an assertion check to make sure all its memory has been freed. Since I'm purposely leaking the memory, in this case, I don't want that assertion to trigger.
Is there a way to manually release the VMA memory such that this assertion is not triggered? Since I leaked the objects that point that memory, I can't release the memory on a per object basis.
I wish VMA would have a way to disable those assertions at runtime.
NOTE: This is all happening during development, in Debug mode. For now, Release mode is not a concern.
Is there a way to prevent an EXC_BAD_ACCESS from crashing an app, like with #try..#catch you can handle an exception gracefully.
Update:
The code crashes when it attempts to dereference an invalid pointer. This is a third party library and it interfaces with external hardware so I can't debug locally. I am trying to prevent it from crashing and output data to a debugging console on my app.
In ObjC, try/catch do not handle exceptions particularly gracefully. You will still leak memory and leave the system in an undefined state. With rare exception, the expectation is that you are simply catching so you can log some things before crashing. And in general, you should not use #catch anywhere but at the top level of your program for this purpose. There are some extraordinary situations where limited use of exceptions may be appropriate, but they are rare in ObjC. See the Exception Programming Guide for some more information. See especially the following from the ObjC ARC documentation:
The standard Cocoa convention is that exceptions signal programmer error and are not intended to be recovered from. Making code exceptions-safe by default would impose severe runtime and code size penalties on code that typically does not actually care about exceptions safety. Therefore, ARC-generated code leaks by default on exceptions, which is just fine if the process is going to be immediately terminated anyway. Programs which do care about recovering from exceptions should enable the option [-fobjc-arc-exceptions, which imposes speed and memory penalties on your program].
The same is true of EXC_BAD_ACCESS. You can catch it with a signal handler for the purpose of recording some information and then finishing your crash. For a good tool for doing this see PLCrashReporter. It is very difficult to write such a handler correctly, so I strongly recommend using an existing framework. You can easily get into deadlocks that drain the user's battery if you catch EXC_BAD_ACCESS incorrectly.
You get EXC_BAD_ACCESS often because you sent a message to a released object. Then you can examine the NSZombie. What is an NSZombie? You can see : this. It will catch the
EXC_BAD_ACCESS because of sent a message to the released object.
You can set NSZombie like this : Check the Enable Zombie Objects
And you can also get EXC_BAD_ACCESS because of the memory warnings level is too high , or your memory is too high , so the apple will shut your app down. This EXC_BAD_ACCESS is too hard to prevent . I think the only way is to manage your memory as low as you can , sometimes you can see the log where is receive memory warning , when the level is high, it may getEXC_BAD_ACCESS
You can rewrite your code to not have these errors. Try not to reference any null pointers and keep references to any object that you want to have access to.
I have a memory corruption error (I suspect), which is resulting in a program crash after specific UI actions. This is a Cocoa Objective-C application and does not use GC.
After many hours of debugging, I found a possible reason for the crash:
DiscSelectPopup *popupSelect = [[DiscSelectPopup alloc] initWithDataList:dataList count:count];
NSInteger result = [NSApp runModalForWindow:popupSelect.window];
The above popup routine is executed from a secondary thread. This thread is created and started every time the user clicks on a button. So, we can have several modal popup show up simultaneously.
When I run the program in debug mode with MallocStackLogging=1 and MallocStackLoggingNoCompact=1, it prints a malloc error log message at the runModalForWindow: call (but not always).
malloc: *** error for object 0xbc65840: double free
.....
malloc: *** error for object 0xbc547e0: pointer being freed was not allocated
Is it really bad to use runModalForWindow: from a secondary thread?
Could it be the reason for the crash?
Is it really bad to use runModalForWindow from the secondary thread?
Yes. UI stuff needs to happen on the main thread.
You also shouldn't use runModalForWindow: unless you specifically want to block all of the other windows in your application (essentially freezing your app except for that window). Just show the window. If you want to block a specific window (or your app is single-window), begin it as a sheet.
Edit: Looking again at the question, this caught my eye:
The above popup routine is executed from a secondary thread.
Don't do that. To show a window, just show it. Receive the action message from the button on the main thread, and then do only the actual work—if anything—on a secondary thread.
Note that showing the window will not block any other windows or anything else you're doing unless you specifically make it do so (i.e., use runModalForWindow:). If you show the window in the normal way, all your windows continue to work normally. Any timers and observers and similar things you've scheduled on the main thread also continue to work. You don't need to create threads or do anything else special for this; it all just works by default.
If the work that you'll eventually do may take a non-trivial amount of time, then you should put that on a secondary thread, only when it comes time to do it. You should also look into whether or not it'd be easier or better to construct as operation objects or blocks than as raw threads. It probably will.
Using valgrind memcheck, I concluded that the secondary thread runModalForWindow: calls are not directly connected with the memory corruption problem.
Yes, it is bad coding to manipulate UI components from non-main threads but such behavior alone cannot crash the program.
The malloc error message in the question was due to the mistakenly double released popup window object.
By the way, real cause of the memory corruption was the mismatched malloc/free call (freeing not malloced memory pointer).
I'm working with an embedded RTOS (CMX), but I think this applies to any embedded RTOS. I want to pass messages between various tasks. The problem is that one task sometimes 'locks' every other task out for a long period of time (several seconds).
Since I no longer wait for the message to be ACK'ed after ~100 ms or so, if I send a mailbox message during this time, the task that sent the message is no longer waiting for it reply, but the receiving task will get the message and try to act on it. The problem is that the receiving task has a pointer to the message, but since the sending task has moved on, the pointer is no longer pointing to the message which can cause huge problems.
I have no method of removing messages once they are in the queue. How can I handle this error gracefully?
This question actually covers several different issues / points.
First of all, I'm wondering why one task hogs the CPU for seconds at a time sometimes. Generally this is an indication of a design problem. But I don't know your system, and it could be that there is a reasonable explanation, so I won't go down that rabbit hole.
So from your description, you are enqueueing pointers to messages, not copies of messages. Nothing inherently wrong with that. But you can encounter exactly the problem you describe.
There are at least 2 solutions to this problem. Without knowing more, I cannot say which of these might be better.
The first approach would be to pass a copy of the message, instead of a pointer to it. For example, VxWorks msg queues (not CMX queues obviously) have you enqueue a copy of the message. I don't know if CMX supports such a model, and I don't know if you have the bandwidth / memory to support such an approach. Generally I avoid this approach when I can, but it has its place sometimes.
The second approach, which I use whenever I can in such a situation, is to have the sender allocate a message buffer (usually from my own msg/buffer pools, usually a linked-list of fixed size memory blocks - but that is an implementation detail - see this description of "memory pools" for an illustration of what I'm talking about). Anyway -- after the allocation, the sender fills in the message data, enqueues a pointer to the message, and releases control (ownership) of the memory block (i.e., the message). The receiver is now responsible for freeing/returning the memory after reading the message.
There are other issues that could be raised in this question, for example what if the sender "broadcasts" the msg to more than one receiver? How do the receivers coordinate/communicate so that only the last reader frees the memory (garbage collection)? But hopefully from what you asked, the 2nd solution will work for you.
I am really interested to know that, Is it possible that using try ... catch mechanism, we can avoid memory crash of our application ... ??
Let say the program part that we are expecting a chance of memory leak is kept under try...catch block, if the program crashes (ie memory leak) occurs then catch statement execute. So we can prevent our program from being crashed.
Is it possible ? If yes, How Or If not , why not ??
A try/catch block is there to catch an exception and stop it from propagating upwards in your callstack.
The idea goes that you catch it at the place where you know how to handle it, and then you get a chance to execute code in response to the exception.
It is not a magical solution that will prevent anything, it is just what I said above. What you do with the exception is what matters.
And a memory leak and a crash is not the same thing, it is rare that a program crashes due to memory leaks, unless it actually runs out of memory. A memory leak is rarely "fixable" after the fact. The correct, and usually only, way to fix a memory leak is to avoid it happening in the first place.
Also, yes, in a way you can keep your program from crashing by adding try/catch blocks all over, but the only thing you've succeeded in is to hide the crash from the user, and then let the program continue running. "Crashes" are not always safe to ignore, or rather, they are usually not safe to ignore.
If you are looking for some catch-all advice on how to avoid a program crashing, here's my advice:
Write a program that works correctly
I think we need to know more about what kinds of problems you're having, or you need to post a clearer question.
I would not trust any in process system to do the right thing in case of an out of memory condition. We have systems which completely lock up when a PermGen exception occurs and need a kill -9 to get rid off.
If you want the system to self correct, wrap it in a script or a system which monitors the health, a heart beat or a diagnostics page or whatever makes sense. If you receive no health indication kill it (hard if necessary) and restart it.
Best of all is to use testing and validation to include monitoring the memory (and disk) usage and make sure you really know how your system behaves and is properly configured so it does not happen.
The restarting solution is a poor alternative, because you then must test and ascertain that you can kill your application at any time and be confident it can be restarted correctly, which might even be more difficult.
If you are asking "can I catch segmentation faults with try catch", the answer is no.
try catch is for handling Objective-C exceptions i.e. those raised by executing an #throw statement. Segmentation faults caused by e.g. null pointer dereferences are generated by the operating system and are examples of Unix signals and can only be caught and handled by OS level system calls e.g. the sigaction(2) system call. Even then, the only sane thing you can do is terminate the program immediately because you might have a corrupt heap or stack.