Ошибка abort has been called

I am doing multithreading in C++. I’m on Windows.
This is what I have:

int i;
    try {
        std::vector<std::thread> threads;
        for (i = 0; i < threadscount; i++) {
            threads.push_back(std::thread(myvoid));
            std::cout << "startedn";
        }

        for (i = 0; i < threadscount; i++) {
            threads[i].join();
            std::cout << "joinedn";
        }
    }
    catch (...) {} 

But when I set threadscount to 2000 threads I get:

abort() has been called.

Why does this happen? Can I get a solution to fix this?

bznein's user avatar

bznein

8987 silver badges21 bronze badges

asked Dec 11, 2015 at 14:17

Mrd. Qasim's user avatar

5

It seems that on windows the limitiation is stack space. You can increase the number of threads if you reduce the amount of stack space given to each.

reference here:

https://blogs.msdn.microsoft.com/oldnewthing/20050729-14/?p=34773/

edit:

just knocked up this test program on my imac. managed to create 2047 threads before running out of resources. Your mileage may vary :-)

#include <iostream>
#include <thread>
#include <exception>
#include <stdexcept>
#include <vector>


void myvoid()
{
    std::this_thread::sleep_for(std::chrono::seconds(5));
}

void start_thread(std::vector<std::thread>& threads)
{
    try
    {
        threads.push_back(std::thread(myvoid));
        std::cout << "started " << threads.size() <<"n";
    }
    catch(...) {
        std::cout << "failed to start at " << threads.size() + 1 << "n";
        throw;
    }
}

auto main() -> int
{
    std::vector<std::thread> threads;
    try {
        for(;;)
            start_thread(threads);
    }
    catch(...)
    {

    }

    for (auto& t : threads) {
        if (t.joinable()) {
            t.join();
        }
    }

    return 0;
}

sample output:

...
started 2042
started 2043
started 2044
started 2045
started 2046
started 2047
failed to start at 2048
$

answered Dec 11, 2015 at 14:23

Richard Hodges's user avatar

Richard HodgesRichard Hodges

67.9k6 gold badges90 silver badges142 bronze badges

1

Because no one can expect to be able to launch 2000 threads. You computer does not have resources for this.

There is a simple solution to this — use a sane number of threads. Hint — anything above 50 is likely insane, unless you have a very special circumstances.

answered Dec 11, 2015 at 14:18

SergeyA's user avatar

SergeyASergeyA

61.4k5 gold badges75 silver badges136 bronze badges

8

If the system runs out of resources while trying to create all those threads then this line will probably throw an exception:

        threads.push_back(std::thread(myvoid));

That will destroy the vector threads, which will then call std::terminate() because it destroys a std::thread that is joinable.

You can make the code safe by moving the declaration of threads before the try block, and then making sure you join (or detach) all the threads in the catch handler.

answered Dec 11, 2015 at 14:23

Jonathan Wakely's user avatar

Jonathan WakelyJonathan Wakely

166k25 gold badges337 silver badges520 bronze badges

2

  • Remove From My Forums
  • Question

  • Hello im trying to use threads, but i cant stop the threads without getting the error: Abort() has been called.

    using namespace std;
    
    void print1()
    {
    	//while(true)
    	cout << "Function 1" << endl;
    }
    
    void print2()
    {
    	//while(true)
    	cout << "Function 2" << endl;
    }
    
    int main(int argc, char argv[])
    {
    	//Creates Threads
    	thread PrimaryThread(print1);
    	thread SecondaryThread(print2);
    
    	//Assigns the threas to pointers
    	thread* pPrimeThread = &PrimaryThread;
    	thread* pSecondaryThread = &PrimaryThread;
    
    	LPDWORD pExitCode = 0;
    	if(GetExitCodeThread(pPrimeThread,pExitCode) != 0)
    	{
    		ExitThread((DWORD)pExitCode);
    		cout << "Thread Closed" << endl;
    
    		if(CloseHandle(pPrimeThread))
            {
                cout << "Handle closed" << endl;
            }
    
    	}
    
    	system("pause");
        return 0;
    
    }

Answers

  • On 2/12/2013 3:36 AM, Farmek wrote:

    But it still gives me a «Abort() has been called» when i try to exit the application.

    You must call join() or detach() methods on thread object before that object is destroyed. If ~thread destructor is reached while the object is still attached to a thread of execution (in other words, while joinable() returns true), the destructor calls
    terminate().


    Igor Tandetnik

    • Marked as answer by

      Tuesday, February 12, 2013 3:12 PM

  • Forum
  • Beginners
  • Debug Error abort() has been called

Debug Error abort() has been called

I tried debugging it when the error window came up by clicking continue and a breakpoint poped up at min = stoi(temp); which is in the Read Method. idk why though. Idk if this helps but i’m using a static library containing all the classes then linking it to main. but i see no errors

main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>
#include "Album.h"

using namespace std;

int main() 
{
	Song total;
	int choice;
	string m_filename;
	Album x;
	cout << "Album Program" << endl;
	cout << "----------" << endl;
	cout << "1 - Read ablbum info from a file" << endl;
	cout << "2 - Write album info to a file" << endl;
	cout << "3 - Show all album info on screen" << endl;
	cout << "4 - Show ablum time on screen" << endl;
	cout << "5 - Exit" << endl;
	cout << "Enter Choice: ";
	cin >> choice;
	cout << endl;
	cout << "Enter File Name: ";
	cin >> m_filename;

	for (int i = 0; i < 6; i++)
	{
		switch (choice)
		{
		case 1:
			x.Read(m_filename);
			cout << "Enter Choice: ";
			cin >> choice;

			break;
		case 2:
			x.Write(m_filename);
			cout << "Enter Choice: ";
			cin >> choice;

			break;
		case 3:
			x.Display();
			cout << "Enter Choice: ";
			cin >> choice;


			break;
		case 4:
			x.CalcTotalTime();
			cout << "Enter Choice: ";
			cin >> choice;


		case 5:
			return 0;
		}

	}


	return 0;
}

Album.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "Album.h"
#include <fstream>
#include <iostream>
#include <iomanip>
using namespace std;
Album::Album()
{
	Title = "no name";
}

string Album::GetTitle()
{
	return Title;
}


void Album::SetTitle(string NewTitle)
{
	Title = NewTitle;
}

Time Album::CalcTotalTime()
{
	int TotalMin = 0;
	int TotalSec = 0;
	Time A;
	for (int i = 0; i < 5; i++)
	{
		TotalMin = TotalMin + S[i].GetTime().GetMinutes();
	}

	for (int i = 0; i <= 5; i++)
	{
		TotalSec = TotalSec + S[i].GetTime().GetSeconds();

		if (TotalSec > 59)
		{

			TotalMin++;
			TotalSec = TotalSec - 60;
		}
	}
	A.SetMinutes(TotalMin);
	A.SetSeconds(TotalSec);
	return A;
}

void Album::Read(string filename)
{
	string Country;
	string AlbumName;
	string SongTitle;
	string temp;
	ifstream Read;
//	Time m_Time;
//	int sec;
//	int min;
	Read.open(filename);
	m_Artist.SetName(AlbumName);
	m_Artist.SetCountryofOrigin(Country);
	getline(Read, Title);
	getline(Read, AlbumName);
	getline(Read, Country);
	for (int i = 0; i < 6; i++)
	{
		Time m_Time;
		int sec;
		int min;
		getline(Read, SongTitle);
		S[i].SetTitle(SongTitle);
		
		getline(Read, temp);

		min = stoi(temp);
		m_Time.SetMinutes(min);
		
		getline(Read, temp);

		sec = stoi(temp);
		m_Time.SetSeconds(sec);

		S[i].SetTime(m_Time);

	}
}

void Album::Write(string filename)
{
	cout << "Enter File Name" << endl;
	cin >> filename;
	ofstream Write;
	Write.open(filename);
	Write << GetTitle() << endl;
	Write << m_Artist.GetName() << endl;
	Write << m_Artist.GetCountryofOrigin();
	


	for (int i = 0; i < 6; i++)
	{
		Write << S[i].GetTitle() << endl;
		Write << S[i].GetTime().GetMinutes() << endl;
		Write << S[i].GetTime().GetSeconds() << endl;

	}
}

void Album::Display()
{
	cout << setw(12) << "Title:" << GetTitle() << endl;
	cout << setw(12) << "Artist:" << m_Artist.GetName() << endl;
	cout << setw(12) << "Title:" << m_Artist.GetCountryofOrigin() << endl;

}

Last edited on

a breakpoint poped up at min = stoi(temp); which is in the Read Method

Very good, so you know where the problem is.

You need to inspect with the debugger what value temp has.
If temp is not a valid int you need to find out how it got there.

So I didnt see anything that raised my suspicion but i saw that the int min wasnt never given a value. I’m still not sure if thats the problem but i set min and sec to 0 reran it and again it picked up a breaker but in a different location, now in the main.cpp cout << "Enter Choice: "; and I just dont see whats wrong with that code.

Edit: nevermind its still at the min = stoi(temp);

Last edited on

So in the debugger i noticed my temp has No value at all. So i made temp equal 0 temp = '0'; right before the loop and it seems to got rid of the error but still the program isnt working properly

Ok, the next step is to find out why it didn’t have a value.
Probably sth. wrong with your read function.
Without knowing the file format it’s impossible to tell.

Topic archived. No new replies allowed.

Comments

@DerKleinePunk

Log with LOG(DEBUG) << «Text» —> work
sdlLogger_->info(logText); —> don’t work
CLOG(INFO, «SDL») << logText; —> work

Visual Studio 2015 Update 3 Platform v140 Unicode

complier warnings:
easylogging++.cc(211): warning C4706: assignment within conditional expression
easylogging++.cc(1119): warning C4244: ‘/=’: conversion from ‘const double’ to ‘unsigned __int64’, possible loss of data

@abumq

Hi @DerKleinePunk,

can you please try following?

#undef ELPP_VARIADIC_TEMPLATES_SUPPORTED
#define ELPP_VARIADIC_TEMPLATES_SUPPORTED 1

and try to re-compile? If this works, let us know and I will add support for forcing VARIADIC_TEMPLATES as the header doesn’t have proper compiler flags to determine whether variadic templates are supported or not.

P.S Thanks for the warnings and I will note them but they are not the reasons for it’s not working

@DerKleinePunk

2 participants

@abumq

@DerKleinePunk

В приложении, которое я пишу, я использую исключения для большей части моей обработки ошибок. Я еще не определил свои собственные классы исключений, я просто сделал следующее:

namespace Mage {
typedef std::exception Exception;
}

Таким образом, мне не придется менять весь мой код, когда я позже определю свой собственный тип, который должен использовать тот же интерфейс.

Тем не менее, любое исключение вызывает сбой моего приложения. Принимая во внимание вышеприведенное определение, с чего бы это крушение?

void Mage::Root::initialize(Mage::String& p_log) {
// initialize GLFW and GLEW.
if (!glfwInit()) {
throw new Mage::Exception("failed to initialize OpenGL");
return;
} else m_GLFWInitialized = true;

Будь я удалить или оставить «новый», он все равно потерпит крах. Я что-то пропустил? Я посмотрел учебники, но они не делают меня мудрее.

Я также ловлю ошибку прямо здесь:

try {
MAGE_ROOT.initialize(Mage::String("Mage.log"));
} catch (Mage::Exception& e) {
std::cerr << e.what() << std::endl;
}

Авария, которую я получаю, это:

Debug Error!

Program: ...sual Studio 2010ProjectMage3DBinariesDebugTest.exe

R6010
- abort() has been called

(Press Retry to debug application)

1

Решение

Проблема в том, что вы не ловите свое исключение.

Я не знал, что ты должен поймать исключение (из комментариев)

Да, ты должен. Если вы не поймали выброшенное исключение, std::terminate() будет называться. Это предполагаемое поведение: существуют исключения, которые не позволяют программистам забывая об обработке ошибок.

Это сказал, я предлагаю:

  • метание по значению;
  • ловить по ссылке

Например:

void foo()
{
// ...
throw std::logic_error("Error!");
//    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
//    Throw by value (std::logic_error derives from std::exception)
// ...
}

void bar()
{
try
{
// ...
foo();
// ...
}
catch (std::exception& e)
^^^^^^^^^^^^^^^
//     Catch by reference
{
std::cout << e.what(); // For instance...
}
}

ОБНОВИТЬ:

Что касается кода, который вы разместили, вы бросаете указатель и ловить ссылка. Обработчик не будет совпадать. И поскольку нет другого подходящего обработчика, std::terminate() будет называться.

Вместо этого вы должны выбросить исключение по значению:

throw Mage::Exception("failed to initialize OpenGL");

И если код, который вы разместили, действительно тот, который вы используете, вы увидите, что управление передается вашему обработчику.

11

Другие решения

Основываясь на сообщении об ошибке, вы используете Visual Studio (2010) для вашего проекта. Если вы не заключите свой бросок в блок try / catch, он будет «проплывать через крышу» и будет «обрабатываться» средой выполнения C ++, что означает вызов abort (). Вы, вероятно, хотите что-то подобное выше в стеке вызовов:

try
{
SomeFunctionThatUltimatelyThrows();
}
catch(Exception & e)
{
// .. handle error - log, resume, exit, whatever
}

Обратите внимание также на совет Скотта Мейерса всегда отлавливать исключения по ссылке. «Исключение»: если вы используете исключения MFC CExceptions, вы хотите перехватить указатель и вызвать метод Delete для самоуничтожения исключений на основе кучи.

Основываясь на ваших изменениях, вы можете иметь несоответствие между броском «по указателю» и отловом «по ссылке». Если вы решили это и по-прежнему не выполняете свой блок catch, вы можете попробовать отладить вызов abort () с помощью CRT SetAbortHandler, чтобы установить собственную функцию прерывания. Это может просто включить в существующую, но даст возможность установить точку останова и проверить стек вызовов, чтобы увидеть, что происходит не так.

2

C ++ try-catch-throw логика для чайников. Обратите внимание, что это НЕ охватывает RAII / размещение / уничтожение на основе стека.

  • Когда вы выбрасываете исключение, исключение называется «распространяющимся». Он распространяется вверх по стеку вызовов до тех пор, пока не найдет первый обработчик, который сможет его обработать (чтобы он был перехвачен), или пока он не достигнет корня стека вызовов.
    • Если он перехвачен, выполнение продолжается с того момента, когда перехвачено исключение. Исключение уничтожается в конце блока catch.
    • Если он находит корень, он вызывает std :: unhandled_exception, который обычно вызывает std :: terminate, который обычно вызывает abort (). Короче говоря, все выпало как можно скорее.
  • Если вы генерируете исключение во время распространения исключения, у вас будет по два одновременно. Java и C # имеют хитроумные способы справиться с этим, но это никогда не должно происходить в первую очередь — нет обработчика исключений, который логически собирается обрабатывать комбинации исключений. Не выбрасывайте исключения, пока одно из них распространяется. Это правило не слишком сложно соблюдать, даже если вы не используете std :: uncaught_exception (), чего не следует делать.
  • При разматывании стека / распространении исключения все объекты, найденные в стеке, уничтожаются. Эти деструкторы никогда не должны выдавать исключение — в конце концов, когда уничтожение объекта «не удается», что еще вы будете делать после того, как деструктор его исправит?
  • Всегда бросать по значению, ловить по ссылке. Если вы бросите & поймать по указателю, вы, скорее всего, что-то утечет, что невозможно по ссылке. Если вы поймете по значению, вы отрежете свои производные типы исключений. Поймать по ссылке.
  • В корне вашего программного обеспечения, включить всеобъемлющее — catch(...), Это не позволяет вам узнать, что именно вы поймали, но, по крайней мере, вы можете безопасно потерпеть крах. Делайте это также, когда вызываемый код может выбросить «что-то», чего вы не знаете.

1

Понравилась статья? Поделить с друзьями:

Не пропустите эти материалы по теме:

  • Яндекс еда ошибка привязки карты
  • Ошибка abgasanlage defekt
  • Ошибка 9с54 бмв е60
  • Ошибка abd2 bmw
  • Ошибка 9с48 windows 7 как исправить

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии