简体   繁体   中英

What are _Unwind_SjLj_Unregister and _Unwind_SjLj_Register?

What are _Unwind_SjLj_Unregister and _Unwind_SjLj_Register? I get them as my top processor time users in my gprof report. google only returns links to people complaining about errors with these two.

heres the only part of my report that has times:= 0:

Flat profile:

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total           
 time   seconds   seconds    calls  ms/call  ms/call  name    
 33.33      0.03     0.03                             _Unwind_SjLj_Unregister
 22.22      0.05     0.02                             _Unwind_SjLj_Register
 11.11      0.06     0.01    13886     0.00     0.00  toint(std::string, int)
 11.11      0.07     0.01     4380     0.00     0.00  hexlify(std::string)
 11.11      0.08     0.01     2994     0.00     0.00  std::_Deque_iterator<unsigned char, unsigned char const&, unsigned char const*>::operator+(int) const
 11.11      0.09     0.01                             std::string::assign(char const*, unsigned int)

im running windows 7 x64, and compiling with codeblocks 10.05 gcc

edit:

after enabling functions that force the program to run 64 seconds, it now looks like:

Flat profile:

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total           
 time   seconds   seconds    calls   s/call   s/call  name    
  8.45      3.49     3.49                             _Unwind_SjLj_Register
  7.36      6.53     3.04  4000006     0.00     0.00  CAST128::setkey(std::string)
  5.86      8.95     2.42                             _Unwind_SjLj_Unregister
  4.36     10.75     1.80 64000080     0.00     0.00  CAST128::F(int&, unsigned int&, unsigned int&, unsigned char&)
  3.68     12.27     1.52                             __dynamic_cast
  3.37     13.66     1.39                             std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&)
  3.25     15.00     1.34                             std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()
  2.88     16.19     1.19                             std::istreambuf_iterator<char, std::char_traits<char> > std::num_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::_M_extract_int<unsigned long long>(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, std::_Ios_Iostate&, unsigned long long&) const

I believe it is exception handling. The problems mostly come up when people try to link to a C++ library built in a different compiler.

I can't give the best answer here, but I do know that SjLj refers to setjmp and longjmp. These are commonly used for exception handling. I think the _Unwind_SjLj_Register will be used internally by the compiler when you enter a try statement (to "register" a SjLj exception handler) and _Unwind_SjLj_Unregister will be used when you exit the try statement. Sort of guessing though.

First: it would probably be worth mentioning your compiler and platform for questions like this one.

Now: On some platforms/some configurations/some compilers, exception handling in C++ is implemented using the "setjmp" and "longjmp" functions (part of the standard C library). The _Unwind_SjLj_[Un]register methods are to do with this. Roughly speaking, when a try..catch block is entered, a handler needs to be registered, and when the block is left, the handler needs to be unregistered.

This is a quite specific case, but I encountered this error using the Rcpp package in R. Turns out the -std=c++11 flag caused the issue, and things worked just fine with -std=c++0x.

In my experience of using gcc on Windows, you can avoid a lot of this overhead by avoiding allocation of memory or the potential for allocation of memory in your inner loops. The other answers point out that you get these calls when an exception might be thrown and cause calls to destructors. In my programs the exception that could be thrown in the most places is std::bad_alloc which you get when a memory allocation fails.

So if the potential exceptions in your program are also mostly std::bad_alloc, and you can move the allocation or the potential for an allocation out of your inner loop, then GCC won't have to deal with cleaning up after potential std::bad_alloc exceptions inside your inner loop. That should speed things up. Remember to consider that things like vector::push_back can allocate memory. Even if you call vector::reserve first to rule out reallocations, GCC might not be smart enough to realize that reallocation isn't going to happen.

I don't know what version of GCC you are using, but I believe that the newest version of GCC uses an exception handling mechanism that does not have this overhead. I could be wrong on that, though. It is certainly possible to implement an exception handling mechanism that does not require registering destructors dynamically since the destructors that need to be called can be inferred from the program counter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM