Am getting a SIGABRT error in my main file, and don't know what to do.
Maim file is:
#import <UIKit/UIKit.h>
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
The error message highlights the line reading:
int retVal = UIApplicationMain(argc, argv, nil, nil);
and reads: "Thread 1: Program received signal: "SIGABRT"
Can you tell me what's wrong, and what I need to do to get it compile?
Thank you.
It's an error elsewhere in your application. You'll have to run the debugger and step through the screen that causes the crash until you reach the line where it jumps to SIGABRT in main. Usually it'll have something to do with memory management (over-releasing an object and then accessing it) or improper initialisation of UIKit objects, which UIKit then attempts to render (which includes returning an object of the wrong type, or accidentally assigning the wrong tag to a UI element so it's sent a message it can't handle). If it's improper initialisation, though, you should get an additional error printed to inform you of that.
EDIT: Actually, yes, you mention it can't compile? SIGABRT is a signal sent to the running application, so I don't see how it can come up during compilation.
Related
I'm testing an antidebug solution with ptrace method
int main(int argc, char **argv) {
void *handle;
long (*go)(enum __ptrace_request request, pid_t pid);
// get a handle to the library that contains 'ptrace'
handle = dlopen ("libc.so", RTLD_LAZY);
// reference to the dynamically-resolved function 'ptrace'
go = dlsym(handle, "ptrace");
if (go(PTRACE_TRACEME, 0) < 0) {
puts("being traced");
exit(1);
}
puts("not being traced");
// cleanup
dlclose(handle);
return 0;
}
When I execute it, I'm always getting a stopped error,
# ./a.out
not being traced
[4]+ Stopped ./a.out
Then I tried to add the SIGSTOP handler like this
int main(int argc, char **argv) {
signal(SIGSTOP, SIG_IGN);
And it's still getting a stopped error, any ideas?
Here's what's happening:
handle = dlopen ("libc.so", RTLD_LAZY) assigns NULL to handle. Dlopen fails because on your GNU/Linux distro (and most other modern distros) lib.so isn't a shared library - it's a GNU ld script.
dlopen ("libc.so.6", RTLD_LAZY) would have succeeded.
go = dlsym(handle, "ptrace") succeeds(!). With glibc, it's OK to pass a NULL pointer as the handle argument to dlsym because glibc happens to use ((void *) 0) as RTLD_DEFAULT.
This generally won't work on other systems. FreeBSD's dlsym uses ((void *) -2) as RTLD_DEFAULT, and if you call dlsym with a NULL handle, it will look for the symbol within the executable or shared library that called dlsym.
go(PTRACE_TRACEME, 0) succeeds.
dlclose(handle) can't tolerate a NULL handle, and it causes a segfault, so the SIGSEGV signal is raised.
since the process is being traced, receiving a signal results in it being stopped (suspended). Typing jobs to your shell will show the signal that made the process stop.
The code
signal(SIGSTOP, SIG_IGN);
won't really do anything. SIGSTOP is one of the signals that cannot be caught, ignored, or held.
Using C++11 STL with VS2013 to implementing a asynchronous print class.
Failing to get thread.join() returns with no deadlocking.
I am trying to debug and finally find this issue may caused by global/local class variable declaration. Here is the details and I dont know why it happened?
#include <iostream>
#include <string>
#include <chrono>
#include <mutex>
#include <thread>
#include <condition_variable>
#include "tbb/concurrent_queue.h"
using namespace std;
class logger
{
public:
~logger()
{
fin();
}
void init()
{
m_quit = false;
m_thd = thread(bind(&logger::printer, this));
//thread printer(bind(&logger::printer, this));
//m_thd.swap(printer);
}
void fin()
{
//not needed
//unique_lock<mutex> locker(m_mtx);
if (m_thd.joinable())
{
m_quit = true;
write("fin");
//locker.unlock();
m_thd.join();
}
}
void write(const char *msg)
{
m_queue.push(msg);
m_cond.notify_one();
}
void printer()
{
string msgstr;
unique_lock<mutex> locker(m_mtx);
while (1)
{
if (m_queue.try_pop(msgstr))
cout << msgstr << endl;
else if (m_quit)
break;
else
m_cond.wait(locker);
}
cout << "printer quit" <<endl;
}
bool m_quit;
mutex m_mtx;
condition_variable m_cond;
thread m_thd;
tbb::concurrent_queue<string> m_queue;
};
For more convenience I placed thread.join into class's destructor in order to ensure the m_thread can be quit normally.
I test the whole class and something wrong occured.
m_thd.join() never return when class logger declared as a global var
like this:
logger lgg;
void main()
{
lgg.init();
for (int i = 0; i < 100; ++i)
{
char s[8];
sprintf_s(s, 8, "%d", i);
lgg.write(s);
}
//if first call lgg.fin() here, m_thd can be joined normally
//lgg.fin();
system("pause");
//dead&blocked here and I observed that printer() finished successfully
}
If class logger declared as a local variable, it seems everything works well.
void main()
{
logger lgg;
lgg.init();
for (int i = 0; i < 100; ++i)
{
char s[8];
sprintf_s(s, 8, "%d", i);
lgg.write(s);
}
system("pause");
}
update 2015/02/27
I tried to delete std::cout in printer(), but program still blocked at same place, seems it is not the std::cout problem?
Deleting supernumerary lock in fin()
Globals and statics are constructed and destructed just prior or post to DllMain getting called respectively for DLL_PROCESS_ATTACH and DLL_PROCESS_DETACH. The problem with this is that it occurs inside the loader lock. Which is the most dangerous place on the planet to be if dealing with kernel objects as it may cause deadlock, or the application to randomly crash. As such you should never use thread primitives as statics on windows EVER. Thus dealing with threading in a destructor of a global object is basically doing the exact things we're warned not to do in DllMain.
To quote Raymond Chen
The building is being demolished. Don't bother sweeping the floor and emptying the trash cans and erasing the whiteboards. And don't line up at the exit to the building so everybody can move their in/out magnet to out. All you're doing is making the demolition team wait for you to finish these pointless housecleaning tasks.
and again:
If your DllMain function creates a thread and then waits for the thread to do something (e.g., waits for the thread to signal an event that says that it has finished initializing, then you've created a deadlock. The DLL_PROCESS_ATTACH notification handler inside DllMain is waiting for the new thread to run, but the new thread can't run until the DllMain function returns so that it can send a new DLL_THREAD_ATTACH notification.
This deadlock is much more commonly seen in DLL_PROCESS_DETACH, where a DLL wants to shut down its worker threads and wait for them to clean up before it unloads itself. You can't wait for a thread inside DLL_PROCESS_DETACH because that thread needs to send out the DLL_THREAD_DETACH notifications before it exits, which it can't do until your DLL_PROCESS_DETACH handler returns.
This also occurs even when using an EXE because the visual C++ runtime cheats and registers its constructors and destructors with the C runtime to be run when the runtime is loaded or unloaded, thus ending up with the same issue:
The answer is that the C runtime library hires a lackey. The hired lackey is the C runtime library DLL (for example, MSVCR80.DLL). The C runtime startup code in the EXE registers all the destructors with the C runtime library DLL, and when the C runtime library DLL gets its DLL_PROCESS_DETACH, it calls all the destructors requested by the EXE.
I'm wondering how you're using m_mtx. The normal pattern is that both thread lock it and both threads unlock it. But fin() fails to lock it.
Similarly unexpected is m_cond.wait(m_mtx). This would release the mutex, except that it isn't locked in the first place!
Finally, as m_mtx isn't locked, I don't see how m_quit = true should become visible in m_thd.
One problem you have is that std::condition_variable::notify_one is called while the same std::mutex that the waiting thread is holding, is held (happens when logger::write is called by logger::fin).
This causes the notified thread to immediately block again, and hence the printer thread will block possibly indefinitely upon destruction (or until spurious wakeup).
You should never notify while holding the same mutex as the waiting thread(s).
Quote from en.cppreference.com:
The notifying thread does not need to hold the lock on the same mutex as the one held by the waiting thread(s); in fact doing so is a pessimization, since the notified thread would immediately block again, waiting for the notifying thread to release the lock.
I'm writing a multi-threaded application using Core Data.
I'm under the impression that - [NSManagedObjectContext lock] does not work as a standard lock. As a proof of concept here is a sample built after the Xcode 3 "Command-line tool" template, "Core Data" flavor:
int main (int argc, const char * argv[])
{
objc_startCollectorThread();
NSManagedObjectContext *context = managedObjectContext();
[context lock];
[context lock];
NSLog(#"hello world! (context=%#)", context);
[context unlock];
[context unlock];
return 0;
}
That should result in a deadlock, instead when running under Mac OS X 10.6.8 or 10.7.4, I've got this log:
2012-07-18 16:53:40.206 test[20004:a0b] hello world! (context=<NSManagedObjectContext: 0x20000df40>)
Can anybody tell me what is happening?
(if I use instances of NSLock instead of the context, the deadlock happens as expected)
here is an excerpt from Apple Documentation about NSManagedObjectContext lock
lock
Attempts to acquire a lock on the receiver.
- (void)lock
Discussion
This method blocks a thread’s execution until the lock can be acquired. An application protects a critical section of code by requiring a thread to acquire a lock before executing the code. Once the critical section is past, the thread relinquishes the lock by invoking unlock.
Sending this message to a managed object context helps the framework to understand the scope of a transaction in a multi-threaded environment. It is preferable to use the NSManagedObjectContext’s implementation of NSLocking instead using of a separate mutex object.
If you lock (or successfully tryLock) a managed object context, the thread in which the lock call is made must have a retain until it invokes unlock. If you do not properly retain a context in a multi-threaded environment, this will result in deadlock.
Availability
Available in Mac OS X v10.4 and later.
It appears that for an unknown reason, subsequent NSManagedObject locks are ignored when happening in a same thread.
Here is another sample code working as expected (no log at execution):
#implementation NSManagedObjectContext (Test)
- (void)testLock:(id)sender
{
[self lock];
NSLog(#"hello world! (context=%#)", self);
[self unlock];
}
#end
int main (int argc, const char * argv[])
{
objc_startCollectorThread();
NSManagedObjectContext *context = managedObjectContext();
[context lock];
[NSThread detachNewThreadSelector:#selector(testLock:) toTarget:context withObject:nil];
sleep(2);
}
Note:
- (BOOL)[NSManagedObjectContext tryLock] also return YESfor any subsequent calls.
I had a perfectly working OpenCV code (having the function cvCaptureFromCAM(0)). But when I modified it to run in a separate thread, I get this "Video Source" selection dialog box and it asks me to choose the Webcam. Even though I select a cam, it appears that the function cvCaptureFromCAM(0) returns null. I also tried by passing the values 0, -1,1, CV_CAP_ANYto this function. I have a doubt that this dialog box causes this issue. Is there any way to avoid this or does anyone have any other opinion?
I've followed the following posts when debugging:
cvCreateCameraCapture returns null
OpenCV cvCaptureFromCAM returns zero
EDIT
Code structure
//header includes
CvCapture* capture =NULL;
IplImage* frame = NULL;
int main(int argc, char** argv){
DWORD qThreadID;
HANDLE ocvThread = CreateThread(0,0,startOCV, NULL,0, &qThreadID);
initGL(argc, argv);
glutMainLoop();
CloseHandle(ocvThread);
return 0;
}
void initGL(int argc, char** argv){
//Initialize GLUT
//Create the window
//etc
}
DWORD WINAPI startOCV(LPVOID vpParam){
//capture = cvCaptureFromCAM(0); //0 // CV_CAP_ANY
if ((capture = cvCaptureFromCAM(1)) == NULL){ // same as simply using assert(capture)
cerr << "!!! ERROR: vCaptureFromCAM No camera found\n";
return -1;
}
frame = cvQueryFrame(capture);
}
//other GL functions
Thanks.
Since this is a problem that only happens on Windows, an easy fix is to leave cvCaptureFromCAM(0) on the main() thread and then do the image processing stuff on a separate thread, as you intented originally.
Just declare CvCapture* capture = NULL; as a global variable so all your threads can access it.
Solved. I couldn't get rid of the above mentioned dialog box, but I avoided the error by simply duplicating the line capture = cvCaptureFromCAM(0);
capture = cvCaptureFromCAM(0);
capture = cvCaptureFromCAM(0);
It was just random. I suspect it had something to do with behavior of Thread. What's your idea?
Thanks all for contributing.
#include<pthread.h>
#include<stdio.h>
#include<semaphore.h>
void func();
int a;
int main()
{
pthread_t thread1;
sem_t semaphore1;
sem_init(&semaphore1,0,1);
pthread_create(&thread1,NULL,(void *)func,NULL);
sem_wait (&semaphore1);
a=62;
printf("%d",a); \\ as i found on google
sleep(2); \\ i believe a value should be sticked to 62
sleep(1); \\ but output shows different why?
printf("%d",a);
sem_post(&semaphore1);
}
void func()
{
a=45;
sleep(1);
a=32;
a=75;
printf("hello");
}
When i Googled it.I found sem_wait locks the global variable so that no other thread access the variable.
But when i tried these code the output is
62
hello
75.
The a value got changed but note that the printf("%d",a) is under the sem_wait ,Whats wrong with my code?
Semaphores offer only advisory locking. They don't know about variables and such, they lock regions of your code. They don't enforce anything so you must call wait and post yourself.
Here is what wait and post really mean when used in your example.
sem_wait (&semaphore1); /* AKA "may I enter this region" */
sem_post(&semaphore1); /* AKA "I am done with this region. */
The way I see it, main asks for permission before entering. func doesn't ask for permission before modifying a.
So func should wait and post.
void func()
{
sem_wait (&semaphore1);
a=45;
sleep(1);
a=32;
a=75;
printf("hello");
sem_post (&semaphore1);
}
Of course, for this sempahore1 should be globally accessible.