package main
import "fmt"
import "runtime"
import "time"
func check(id int) {
fmt.Println("Checked", id)
<-time.After(time.Duration(id)*time.Millisecond)
fmt.Println("Woke up", id)
}
func main() {
defer runtime.Goexit()
for i := 0; i <= 10; i++ {
fmt.Println("Called with", i)
go check(i)
}
fmt.Println("Done for")
}
I'm very new to Go, so any pointers would be great. How would I go about debugging such a thing?
You can run the snippet http://play.golang.org/p/SCr8TZXQUE
update: this works without the line <-time.After(time.Duration(id)*time.Millisecond) on playground, I want to know why? (As mentioned by #dystroy this maybe because of the way playground handles time)
When I try locally, this is the output:
Called with 0
Called with 1
Checked 0
Called with 2
Checked 1
Called with 3
Checked 2
Called with 4
Woke up 0
Checked 3
Called with 5
Checked 4
Called with 6
Checked 5
Called with 7
Checked 6
Called with 8
Checked 7
Called with 9
Checked 8
Called with 10
Checked 9
Woke up 1
Done for
Checked 10
Woke up 2
Woke up 3
Woke up 4
Woke up 5
Woke up 6
Woke up 7
Woke up 8
Woke up 9
Woke up 10
throw: all goroutines are asleep - deadlock!
goroutine 2 [syscall]:
created by runtime.main
/tmp/bindist046461602/go/src/pkg/runtime/proc.c:221
goroutine 5 [timer goroutine (idle)]:
created by addtimer
/tmp/bindist046461602/go/src/pkg/runtime/ztime_amd64.c:69
exit status 2
All the goroutines complete but throws a deadlock anyway. I should note that it doesn't matter if the timer is used, deadlocks either way.
From the documentation of Goexit :
Goexit terminates the goroutine that calls it. No other goroutine is affected. Goexit runs all deferred calls before terminating the goroutine.
You're exiting the main routine. Don't. As you do it, there isn't any routine running after the last one you launched with go check(i) has finished, hence the "deadlock". Simply remove this line :
defer runtime.Goexit()
If what you want is to wait in main for a group of goroutines to finish, you may use a sync.WaitGroup :
package main
import (
"fmt"
"sync"
"time"
)
func check(id int, wg *sync.WaitGroup) {
fmt.Println("Checked", id)
<-time.After(time.Duration(id)*time.Millisecond)
fmt.Println("Woke up", id)
wg.Done()
}
func main() {
var wg sync.WaitGroup
for i := 0; i <= 10; i++ {
wg.Add(1)
fmt.Println("Called with", i)
go check(i, &wg)
}
wg.Wait()
fmt.Println("Done for")
}
EDIT :
if you're testing it on golang's playground, any time.After will deadlock because time is frozen in playground and Goexit maybe exit a routine that doesn't even exist in a standard program.
all your goroutines are waiting for someone to consume the value they are sending in <-time.After.
you can just delete the <- or make main consume the value of all goroutines you launched.
Edit
this worked for me
package main
import "fmt"
//import "runtime"
import "time"
func check(id int) {
fmt.Println("Checked", id)
<-time.After(time.Duration(id)*time.Millisecond)
fmt.Println("Woke up", id)
}
func main() {
//defer runtime.Goexit()
for i := 0; i <= 10; i++ {
fmt.Println("Called with", i)
go check(i)
}
fmt.Println("Done for")
}
witch is the same solution someone proposed before so I'll propose a solution without a waitgroup
package main
import "fmt"
import "time"
func check(id int, c chan bool) {
fmt.Println("Checked", id)
time.After(time.Duration(id)*time.Millisecond)
fmt.Println("Woke up", id)
c <- true
}
func main() {
c := make(chan bool)
for i := 0; i <= 10; i++ {
fmt.Println("Called with", i)
go check(i, c)
}
var n uint
for n<10 {
<- c
n++
}
fmt.Println("Done for")
}
Related
I started with testing GoogleMock (1.8.0 release) on Windows. I wanted to show an example that it is not thread safe. After proving that successfully, I wanted to show that the same test runs fine on Linux. That failed however. That did not match my expectation.
Since the GoogleMock documentation says that it is, or should be, thread safe on systems with pthreads, it should be thread safe on Linux. I did have to add -pthread to the linker command line to build the executable. That means that GoogleMock or GoogleTest does use pthreads.
This is the code I use for testing:
#include <thread>
#include <vector>
#include "gmock/gmock.h"
class Dummy
{
public:
virtual void SomeMethod(int) {}
};
class DummyMock : public Dummy
{
public:
MOCK_METHOD1(SomeMethod, void(int));
};
using ::testing::Exactly;
constexpr static int nrCallsPerThread = 100 * 1000;
constexpr static int nrThreads = 10;
TEST(SomeTest, Test100)
{
DummyMock dummy;
std::vector<std::thread> threads;
for (int i = 0; i < nrThreads; i++)
{
EXPECT_CALL(dummy, SomeMethod(i)).Times(Exactly(nrCallsPerThread));
threads.emplace_back([&dummy, i]
{
for (int j = 0; j < nrCallsPerThread; j++)
{
dummy.SomeMethod(i);
}
});
}
for (auto& t: threads)
{
t.join();
}
}
int main(int argc, char** argv)
{
testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
The problem is, on Linux, not exposed every execution. But running the executable with --gtest_repeat=100 has a near 100% hit rate.
On Windows, using Visual Studio 2015, if get a Debug Assertion Failed! message with Expression: vector iterator not decrementable.
On Linux, Ubuntu 17.04, when I run the Debug build from the command line I get [ FATAL ] ../googletest-release-1.8.0/googletest/include/gtest/internal/gtest-port.h:1928:: pthread_mutex_lock(&mutex_)failed with error 22.
When running in a debugger on Linux, the program is (often) interrupted at gtest-port.h line 1100, which is line 2 in this callstack:
0 0x5555555a6633 testing::Cardinality::ConservativeUpperBound() const () (??:??)
1 0x5555555a1a13 testing::internal::ExpectationBase::CheckActionCountIfNotDone() const () (??:??)
2 0x555555563f98 testing::internal::TypedExpectation<void (int)>::ShouldHandleArguments(std::tuple<int> const&) const(this=0x5555557f58a0, args=std::tuple containing = {...}) (../googletest-release-1.8.0/googlemock/include/gmock/gmock-spec-builders.h:1100)
3 0x55555556397d testing::internal::FunctionMockerBase<void (int)>::FindMatchingExpectationLocked(std::tuple<int> const&) const(this=0x7fffffffde38, args=std::tuple containing = {...}) (../googletest-release-1.8.0/googlemock/include/gmock/gmock-spec-builders.h:1723)
4 0x555555563578 testing::internal::FunctionMockerBase<void (int)>::UntypedFindMatchingExpectation(void const*, void const**, bool*, std::ostream*, std::ostream*)(this=0x7fffffffde38, untyped_args=0x7fffde7fbe14, untyped_action=0x7fffde7fb7d0, is_excessive=0x7fffde7fb7c7, what=0x7fffde7fb900, why=0x7fffde7fba90) (../googletest-release-1.8.0/googlemock/include/gmock/gmock-spec-builders.h:1687)
5 0x5555555a265e testing::internal::UntypedFunctionMockerBase::UntypedInvokeWith(void const*) () (??:??)
6 0x55555555fcba testing::internal::FunctionMockerBase<void (int)>::InvokeWith(std::tuple<int> const&)(this=0x7fffffffde38, args=std::tuple containing = {...}) (../googletest-release-1.8.0/googlemock/include/gmock/gmock-spec-builders.h:1585)
7 0x55555555f16c testing::internal::FunctionMocker<void (int)>::Invoke(int)(this=0x7fffffffde38, a1=1) (../googletest-release-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h:101)
8 0x55555555ecb6 DummyMock::SomeMethod(this=0x7fffffffde30, gmock_a1=1) (/home/jos/Programming/ThreadSafeGMock/main.cpp:16)
9 0x55555555d31e SomeTest_Test100_Test::<lambda()>::operator()(void) const(__closure=0x5555557f5478) (/home/jos/Programming/ThreadSafeGMock/main.cpp:36)
10 0x55555555de98 std::_Bind_simple<SomeTest_Test100_Test::TestBody()::<lambda()>()>::_M_invoke<>(std::_Index_tuple<>)(this=0x5555557f5478) (/usr/include/c++/6/functional:1391)
11 0x55555555de22 std::_Bind_simple<SomeTest_Test100_Test::TestBody()::<lambda()>()>::operator()(void)(this=0x5555557f5478) (/usr/include/c++/6/functional:1380)
12 0x55555555ddf2 std::thread::_State_impl<std::_Bind_simple<SomeTest_Test100_Test::TestBody()::<lambda()>()> >::_M_run(void)(this=0x5555557f5470) (/usr/include/c++/6/thread:197)
13 0x7ffff7b0a83f ??() (/usr/lib/x86_64-linux-gnu/libstdc++.so.6:??)
14 0x7ffff76216da start_thread(arg=0x7fffde7fc700) (pthread_create.c:456)
15 0x7ffff735b17f clone() (../sysdeps/unix/sysv/linux/x86_64/clone.S:105)
Since it should be thread safe, I suspect that I am doing something wrong. But I do not see what.
Or did I hit a bug in GoogleTest or GoogleMock?
From the fine manual:
Important note: Google Mock requires expectations to be set before the mock functions are called, otherwise the behavior is undefined. In particular, you mustn't interleave EXPECT_CALL()s and calls to the mock functions.
Your original code fails on my system (cygwin) intermittently with error 22 or sometimes no message/error code whatsoever. This modification works flawlessly:
for (int i = 0; i < nrThreads; i++)
{
EXPECT_CALL(dummy, SomeMethod(i)).Times(Exactly(nrCallsPerThread));
}
std::vector<std::thread> threads;
for (int i = 0; i < nrThreads; i++)
{
threads.emplace_back([&dummy, i] ...
I am running GDB. I donot wish to use "s" command and step into the next line.
I directly want to jump to the starting line of the next function in the code flow.
And I havent put any breakpoint ( because I dont know which is the next function to be hit ).
Is there any command to do so ?
Edit:
Sorry. I did not ask my question clearly.
I will give 1 example.
line#1 int function(int a)
line#2 {
line#3 int b;
line#4 b = 10;
line#5 b = b + a;
...... ...
...... ...
...... ...
...... ...
...... ...
...... ...
...... ...
...... ...
...... ...
...... ...
...... ...
...... ...
line#1000 if (10 == b)
line#1001 {
line#1002 func1();
line#1003 } else
line#1004 {
line#1005 func2();
line#1006 }
line#1007 } // function(int a);
...... ...
...... ...
...... ...
line#2000 void func1()
line#2001 {
line#2002 printf("hello\n");
line#2003 }
line#2004 void func2()
line#2005 {
line#2006 printf("hi\n");
line#2007 }
Now, my control is currently at line#4.
I donot know if func1 will be called, or func2 will be called.
I have not put any breakpoint in func1 or func2.
Since function() is a big function, I donot want to use "step" command to reach either func1 or func2.
In this case, consider value of "a" is 0.
Hence func1() will be called.
Is there any command to directly jump from line#4 to line#2000 without putting any breakpoint ?
So, any command to directly jump to next function to be hit in the code flow ?
Thank you!
If your program sets up the frame base pointer $bp upon entry to a function, you can simply watch it, then continue, and execution will stop just after entry to another function. (This will also stop execution when a function returns.)
Note that some compilers don't emit code that uses a frame base pointer at all, and some may choose not to update the pointer in functions in which there aren't any local variables.
$ gdb -q args
(gdb) list
1 main(int argc, char **argv)
2 {
3 for(int i=0; i<argc; i++)
4 printf("arg %d is %s\n", i, argv[i]);
5 }
(gdb) start
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffdfa8) at args.c:3
3 for(int i=0; i<argc; i++)
(gdb) watch $bp
Watchpoint 2: $bp
(gdb) c
Continuing.
Watchpoint 2: $bp
Old value = -8608
New value = -8880
0x0000000000453e24 in vfprintf ()
(gdb) bt
#0 0x0000000000453e24 in vfprintf ()
#1 0x000000000040f3d6 in printf ()
#2 0x00000000004009f1 in main (argc=1, argv=0x7fffffffdfa8) at args.c:4
There is no built-in command to do this in gdb.
If you wanted to implement it, you could probably do so in Python. The idea would be to record the current frame, then invoke step repeatedly until the current frame changes. At that point you know the inferior has either called a function or returned from the current function.
I need a gtest that will pass if sigabrt doesn't happen, but need to know if it does happen, or fail the test. How would I do that?
I was thinking of this sort of thing:
TEST_F(TestTest, testSigabrtDoesntHappen)
{
MyObject &myObject = MyObject::instance();
for(int i=0; i<2; i++){
myObject.doWork(); //this will sigabrt on the second try, if at all
ASSERT_TRUE(myObject);
}
ASSERT_TRUE(myObject);
}
So assuming a sigabrt would exit out of the test if it occurs, then we would get 3 test passes otherwise. Any other ideas?
Not on Window:
::testing::KilledBySignal(signal_number) // Not available on Windows.
You should look the guide.
It seems like that for me (not tested) :
TEST_F(TestTest, testSigabrtDoesntHappen)
{
MyObject &myObject = MyObject::instance();
for(int i=0; i<2; i++){
EXPECT_EXIT(myObject.doWork(), ::testing::KilledBySignal(SIGBART)), "Regex to match error message");
ASSERT_TRUE(myObject);
}
ASSERT_TRUE(myObject);
}
On Window:
You'll have to handle signal yourself with this kind of code:
// crt_signal.c
// compile with: /EHsc /W4
// Use signal to attach a signal handler to the abort routine
#include <stdlib.h>
#include <signal.h>
#include <tchar.h>
void SignalHandler(int signal)
{
if (signal == SIGABRT) {
// abort signal handler code
} else {
// ...
}
}
int main()
{
typedef void (*SignalHandlerPointer)(int);
SignalHandlerPointer previousHandler;
previousHandler = signal(SIGABRT, SignalHandler);
abort(); //emit SIGBART ?
}
doc
But seriously if you have one time get a SIGBART running your code, there are some problems with your code that you have to remove before release the software.
But if you really want to debug your code (with googletest), use this with your debugger:
foo_test --gtest_repeat=1000 --gtest_break_on_failure
You can add others option to it, again : check the doc :)
I have console C++ application built in XCode 6 and want to add SIGTERM handler to it. There are a lot of examples, but I can't get them to work.
#include <csignal>
namespace
{
volatile std::sig_atomic_t gDone = 0;
}
static void term_handler(int i)
{
gDone = 1;
}
int main(int argc, const char * argv[])
{
std::signal(SIGTERM, term_handler);
while (!gDone);
return 0;
}
The debugger stopped on the while statement, but the handler was not called. The same problem with this code
#include <signal.h>
volatile sig_atomic_t gDone = 0;
void term_handler(int i)
{
gDone = 1;
}
int main(int argc, char* argv[])
{
struct sigaction sa;
sigset_t newset;
sigemptyset(&newset);
sigaddset(&newset, SIGHUP);
sigprocmask(SIG_BLOCK, &newset, 0);
sa.sa_handler = term_handler;
sigaction(SIGTERM, &sa, 0);
while(!gDone);
return 0;
}
Is there a problem with the code? What is the right way to handle signals in OSX?
After you send the signal, and the debugger stops, you have to continue to get to your breakpoint inside the signal handler.
(lldb) break set -n term_handler
Breakpoint 1: where = a.out`term_handler(int) + 4 at sig.cc:11, address = 0x0000000100000f54
(lldb) run
Process 42532 launched: './a.out' (x86_64)
Process 42532 stopped
* thread #1: tid = 0x18dc39, 0x0000000100000f30 a.out`main(argc=15, argv=0x00007fff5fbffb58) + 32 at sig.cc:17, queue = 'com.apple.main-thread', stop reason = signal SIGTERM
frame #0: 0x0000000100000f30 a.out`main(argc=15, argv=0x00007fff5fbffb58) + 32 at sig.cc:17
14 int main(int argc, const char * argv[])
15 {
16 std::signal(SIGTERM, term_handler);
-> 17 while (!gDone);
18 std::puts("done!");
19 return 0;
20 }
(lldb) c
Process 42532 resuming
Process 42532 stopped
* thread #1: tid = 0x18dc39, 0x0000000100000f54 a.out`term_handler(i=15) + 4 at sig.cc:11, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100000f54 a.out`term_handler(i=15) + 4 at sig.cc:11
8
9 static void term_handler(int i)
10 {
-> 11 gDone = 1;
12 }
13
14 int main(int argc, const char * argv[])
(lldb) `
OK, I'm home now and working on my Mac. Again, your code (second sample specifically) has proven just fine. The confirmation was done in Terminal with gcc and "kill -TERM ". Source refers to SIGTERM, like normal, but kill refers (on OS X) to TERM. The XCode pause you are seeing is due to XCode, not your code. I tried it both ways, Terminal and XCode. I could not find a pref to inhibit that interruption, however.
Just to focus here ...You asked, Is there a problem with the code? Answer: No. You asked, What is the right way to handle signals in OSX? Answer: The way you're already doing it. New question: How do I get XCode (lldb) to not pause when signals occur? Answer: How to tell LLDB debugger not to handle SIGBUS?
Your code is fine. Kill with:
kill -SIGTERM 31573
because
kill -9 31573
where 31573 was my process ID, did not exit gracefully. I added a printf to your code to tell me it was exiting gracefully.
I've been "playing around with" boost threads today as a learning exercise, and I've got a working example I built quite a few months ago (before I was interrupted and had to drop multi-threading for a while) that's showing unusual behaviour.
When I initially wrote it I was using MingW gcc 3.4.5, and it worked. Now I'm using 4.4.0 and it doesn't - incidentally, I've tried again using 3.4.5 (I kept that version it a separate folder when I installed 4.4.0) and it's still working.
The code is at the end of the question; in summary what it does is start two Counter objects off in two child threads (these objects simply increment a variable then sleep for a bit and repeat ad infinitum - they count), the main thread waits for the user via a cin.get() and then interrupts both threads, waits for them to join, then outputs the result of both counters.
Complied with 3.4.5 it runs as expected.
Complied with 4.4.0 it runs until the user input, then dies with a message like the below - it seems the the interrupt exceptions are killing the entire process?
terminate called after throwing an instance of '
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
boost::thread_interrupted'
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
From what I read, I think that any (?) uncaught exception that is allowed to propagate out of a child thread will kill the process? But, I'm catching the interrupts here, aren't I? At least I seem to be when using 3.4.5.
So, firstly, have I understood how interrupting works?
And, any suggestions as to what is happening and how to fix?
Code:
#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/date_time.hpp>
//fixes a linker error for boost threads in 4.4.0 (not needed for 3.4.5)
//found via Google, so not sure on validity - but does fix the link error.
extern "C" void tss_cleanup_implemented() { }
class CCounter
{
private:
int& numberRef;
int step;
public:
CCounter(int& number,int setStep) : numberRef(number) ,step(setStep) { }
void operator()()
{
try
{
while( true )
{
boost::posix_time::milliseconds pauseTime(50);
numberRef += step;
boost::this_thread::sleep(pauseTime);
}
}
catch( boost::thread_interrupted const& e )
{
return;
}
}
};
int main( int argc , char *argv[] )
{
try
{
std::cout << "Starting counters in secondary threads.\n";
int number0 = 0,
number1 = 0;
CCounter counter0(number0,1);
CCounter counter1(number1,-1);
boost::thread threadObj0(counter0);
boost::thread threadObj1(counter1);
std::cout << "Press enter to stop the counters:\n";
std::cin.get();
threadObj0.interrupt();
threadObj1.interrupt();
threadObj0.join();
threadObj1.join();
std::cout << "Counter stopped. Values:\n"
<< number0 << '\n'
<< number1 << '\n';
}
catch( boost::thread_interrupted& e )
{
std::cout << "\nThread Interrupted Exception caught.\n";
}
catch( std::exception& e )
{
std::cout << "\nstd::exception thrown.\n";
}
catch(...)
{
std::cout << "\nUnexpected exception thrown.\n"
}
return EXIT_SUCCESS;
}
Solved.
It turns out adding the complier flag -static-libgcc removes the problem with 4.4.0 (and has no apparent affect with 3.4.5) - or at least in this case the program returns the expected results.