Wednesday, December 2, 2015

Print Call stack where Exception Occure

Code: http://peerreview.in/code/s565f4c408bae0c31afe09543

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#ifndef __USE_GNU
#define __USE_GNU
#endif
#include <iostream>
#include <execinfo.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ucontext.h>
#include <unistd.h>

/* This structure mirrors the one found in /usr/include/asm/ucontext.h */

typedef struct _sig_ucontext {
 unsigned long     uc_flags;
 struct ucontext   *uc_link;
 stack_t           uc_stack;
 struct sigcontext uc_mcontext;
 sigset_t          uc_sigmask;
} sig_ucontext_t;

void crit_err_hdlr(int sig_num, siginfo_t * info, void * ucontext)
{
 void *             array[50];
 void *             caller_address;
 char **            messages;
 int                size, i;
 sig_ucontext_t *   uc;

 uc = (sig_ucontext_t *)ucontext;

 /* Get the address at the time the signal was raised */
#if defined(__i386__) // gcc specific
 caller_address = (void *) uc->uc_mcontext.eip; // EIP: x86 specific
#elif defined(__x86_64__) // gcc specific
 caller_address = (void *) uc->uc_mcontext.rip; // RIP: x86_64 specific
#else
#error Unsupported architecture. // TODO: Add support for other arch.
#endif

 fprintf(stderr, "signal %d (%s), address is %p from %p\n",
  sig_num, strsignal(sig_num), info->si_addr,
  (void *)caller_address);

 size = backtrace(array, 50);

 /* overwrite sigaction with caller's address */
 array[1] = caller_address;

 messages = backtrace_symbols(array, size);

 /* skip first stack frame (points here) */
 for (i = 1; i < size && messages != NULL; ++i)
 {
  fprintf(stderr, "[bt]: (%d) %s\n", i, messages[i]);
 }

 free(messages);

 exit(EXIT_FAILURE);
}

int crash()
{
 char * p = NULL;
 *p = 0;
 return 0;
}

int foo4()
{
 crash();
 return 0;
}

int foo3()
{
 foo4();
 return 0;
}

int foo2()
{
 foo3();
 return 0;
}

int foo1 () noexcept
{
 foo2();
 return 0;
}

/* How to run:
g++ -rdynamic -std=c++11  NECB.cpp
./a.out
*/
int main(int argc, char ** argv)
{
 struct sigaction sigact;

 sigact.sa_sigaction = crit_err_hdlr;
 sigact.sa_flags = SA_RESTART | SA_SIGINFO;

 if (sigaction(SIGSEGV, &sigact, (struct sigaction *)NULL) != 0)
 {
    fprintf(stderr, "error setting signal handler for %d (%s)\n",
    SIGSEGV, strsignal(SIGSEGV));

     exit(EXIT_FAILURE);
 }
 foo1();
 exit(EXIT_SUCCESS);
}

Exception propagation and noexcept C++11

exception propagation and noexcept C++11
=======================================

Q1. what is exception propagation?
-------------------------------------------
An exception propagates from method to method, up the call stack, until it's caught. So if a() calls b(), which calls c(), which calls d(), and if d() throws an exception, the exception will propagate from d to c to b to a, unless one of these methods catches the exception.
#include<iostream>
using namespace std;

void d() {
    cout<<"d start\n";
    throw 42;
    cout<<"d ends\n";
}
void c() {
    cout<<"c start\n";
    d();
    cout<<"c ends\n";
}
void b() {
    cout<<"b start\n";
    c();
    cout<<"b ends\n";
}
void a() {
    cout<<"a start\n";
    b();
    cout<<"a ends\n";
}

int main()
{
    try{
        a();
    }
    catch(...){
        cout<<"catched";
    }
}

Run Code online: http://peerreview.in/code/s565f3cbe8bae0c31afe09541

What is Stack Unwinding in C++?
-------------------------------
The process of removing function entries from function call stack at run time is called Stack Unwinding. Stack Unwinding is generally related to Exception Handling. In C++, when an exception occurs, the function call stack is linearly searched for the exception handler, and all the entries before the function with exception handler are removed from the function call stack. So exception handling involves Stack Unwinding if exception is not handled in same function (where it is thrown).

In this code (Run Code online: http://peerreview.in/code/s565f3cbe8bae0c31afe09541) The ouput is have only start no end.
a start
b start
c start
d start
catched

Is detractor called when Stack Unwinding ?
---------------------------------------------
On a side note, if there were some local class objects inside f1() and f2(), destructor for those local objects would have been called in Stack Unwinding process. But pointers are not released.

http://peerreview.in/code/s565f3da38bae0c31afe09542

What is noexcept operator (since C++11)?
------------------------------------------- 
The noexcept operator performs a compile-time check that returns true if an expression is declared to not throw any exceptions. It can be used within a function template's noexcept specifier to declare that the function will throw exceptions for some types but not others.

Example:
// whether foo is declared noexcept depends on if the expression T() will throw any exceptions
template <class T>
void foo() noexcept(noexcept(T())) {}
void bar() noexcept(true) {}
void baz() noexcept { throw 42; }  // noexcept is the same as noexcept(true)
int main()
{
    foo<int>();  // noexcept(noexcept(int())) => noexcept(true), so this is fine
    bar();  // fine
    baz();  // compiles, but at runtime this calls std::terminate
}
Crash as:
Program received signal SIGABRT, Aborted.
0x00007ffff7747cc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#0  0x00007ffff7747cc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007ffff774b0d8 in __GI_abort () at abort.c:89
...

Code: http://peerreview.in/code/s565f38328bae0c31afe09540

Q1. When should we use this?
----------------------------------
If a function cannot throw an exception or if the program isn't written to handle exceptions thrown by a function, that function can be declared noexcept. For example:
Example 1: When we use ?
    extern "C" double sqrt(double) noexcept; // will never throw
Example 2: When we not use?
 vector<double> my_computation(const vector<double>& v) noexcept // I'm not prepared to handle memory exhaustion , This is an error
 {
  vector<double> res(v.size()); // might throw
  for(int i; i<v.size(); ++i) res[i] = sqrt(v[i]);
  return res;
 }

Q2. What happens if we declare noexcept but it throws?
---------------------------------------------------------
If a function declared noexcept throws (so that the exception tries to propagate from the noexcept function) the program is terminated (by a call to terminate()). The call of terminate() cannot rely on objects being in well-defined states (i.e. there is no guarantees that destructor have been invoked, no guaranteed stack unwinding, and no possibility for resuming the program as if no problem had been encountered). This is deliberate and makes noexcept a simple, crude, and very efficient mechanism (much more efficient than the old dynamic throw() mechanism).


Q3. How to  make a function conditionally noexcept?
-------------------------------------------------------

It is possibly to make a function conditionally noexcept. For example, an algorithm can be specified to be noexcept if (and only if) the operations it uses on a template argument are noexcept:

template<class T>
void do_f(vector<T>& v) noexcept(noexcept(f(v.at(0)))) // can throw if f(v.at(0)) can
 {
  for(int i; i<v.size(); ++i)
   v.at(i) = f(v.at(i));
 }
Here, I first use noexcept as an operator: noexcept(f(v.at(0))) is true if f(v.at(0)) can't throw, that is if the f() and at()used are noexcept.

Another Example:
int pop(int idx) noexcept(noexcept(idx > 0))
{
  if (idx <= 0)
    throw std::out_of_range("My array doesnt go that high");
  return idx;
}
Actually the noexept specification expects a constant expression, not a runtime expression. noexcept(idx >0) returns true as comparing two integers does not throw, The declaration <int pop(int idx) noexcept(noexcept(idx > 0))
: says this function does not throw as long as idx > 0 does not throw, which is always the case for an int.

Q4. What is noexcept operator?
------------------------------------
The noexcept() operator is a constant expression and does not evaluate its operand. The general form of anoexcept declaration is noexcept(expression) and ``plain noexcept'' is simply a shorthand for noexcept(true). All declarations of a function must have compatible noexcept specifications. A destructor shouldn't throw; a generated destructor is implicitly noexcept (independently of what code is in its body) if all of the members of its class have noexcept destructors. It is typically a bad idea to have a move operation throw, so declare those noexcept whereever possible. A generated copy or move operation is implicitly noexcept if all of the copy or move operations it uses on members of its class have noexcept destructors. noexcept is widely and systematically used in the standard library to improve performance and clarify requirements.