系统包含在ubuntu上移动的,g++无法解析REG_EIP



此代码始终无法在ubuntu 12.04、12.10、linux mint 13和14中构建,但它在ubuntu-maverick 10.10 上正确编译

#include <stdio.h>
#include <signal.h>
#include <stdio.h>
#include <signal.h>
#include <execinfo.h>
#include <stdlib.h>
#include <string.h>
//#define __USE_GNU
//#include <sys/ucontext.h>
#include <ucontext.h>
#ifndef __USE_GNU
#error "__USE_GNU HAS been undefined"
#endif
#include <cxxabi.h>
#include <iostream>

#ifndef _SYS_UCONTEXT_H
#error "sys/context HAS NOT BEEN INCLUDED"
#endif
void print_trace(const char * file, int line) //(FILE *out, const char *file, int line)
{
    const size_t max_depth = 100;
    size_t stack_depth;
    void *stack_addrs[max_depth];
    char **stack_strings;
    stack_depth = backtrace(stack_addrs, max_depth);
    stack_strings = backtrace_symbols(stack_addrs, stack_depth);
    //fprintf(out, "Call stack from %s:%d:n", file, line);
// demangle output: http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html
    // spec: http://www.ib.cnea.gov.ar/~oop/biblio/libstdc++/namespaceabi.html
    //string binary;
    // Usually e.start=1: we skip the first frame (traced_exception constructor)
    for( size_t i=1; i<stack_depth; ++i ){
        char *line = stack_strings[i];
        char *lb = strchr(line, '(');
        char *plus = 0;
        char *rb = 0;
        char *demangled = 0;
        if( lb != 0 ){
            /* Print out the path to the binary? Seems pointless.
            if( binary != string( line, lb-line ) ){
                binary = string( line, lb-line );
                stream << "in " << binary << ":n";
            }
            */
            *lb = '';
            plus = strchr(lb+1,'+');
            if( plus != 0 ){
                *plus = '';
                int status;
                demangled = abi::__cxa_demangle(lb+1, 0, 0, &status);
                /*if( status != 0 ){
                    cerr << "status: "<<status<<"tstring:"<<lb+1<<endl;
                }*/
                rb = strchr(plus+1, ')');
            }else{
                rb = strchr(lb+1, ')');
            }
            if( rb != 0 ){
                *rb = '';
            }
        }
        if( lb == 0 ){
            std::cout << line;
        }else{
            if( plus != 0 ){
                std::cout << "+" << (plus+1);
            }
            if( demangled != 0 ){
                std::cout << 't' << demangled;
                free(demangled);
            }else if( lb != 0 && rb > lb ){
                std::cout << 't' << (lb+1) << "()";
            }
        }
        std::cout << 'n';
    }
    free(stack_strings); // malloc()ed by backtrace_symbols
}

void bt_sighandler(int sig, siginfo_t *info,
                   void *secret) {
  printf("<<< SIGNAL HANDLER >>>n");
  print_trace("none" , 0);
  void *trace[16];
  char **messages = (char **)NULL;
  int i, trace_size = 0;
  ucontext_t *uc = (ucontext_t *)secret;
  /* Do something useful with siginfo_t */
  if (sig == SIGSEGV)
    printf("Got signal %d, faulty address is %p, "
           "from %pn", sig, info->si_addr, 
           uc->uc_mcontext.gregs[REG_EIP]);
  else
    printf("Got signal %d#92;n", sig);
  trace_size = backtrace(trace, 16);
  /* overwrite sigaction with caller's address */
  trace[1] = (void *) uc->uc_mcontext.gregs[REG_EIP];
  messages = backtrace_symbols(trace, trace_size);
  /* skip first stack frame (points here) */
  printf("[bt] Execution path:#92;n");
  for (i=1; i<trace_size; ++i)
  {
    printf("[bt] %s :", messages[i]);
    char syscom[256];
    sprintf(syscom,"addr2line %p -e %s", trace[i] , "executableName" ); //last parameter is the name of this app
    system(syscom);
    printf("n");
  }
  exit(0);
}

inline void initialise_signal_handlers()
{
    /* Install our signal handler */
    printf(" initialising signal handlers... n ");
    struct sigaction sa;
    sa.sa_sigaction = bt_sighandler;
    sigemptyset (&sa.sa_mask);
    sa.sa_flags = SA_RESTART | SA_SIGINFO;

    sigaction(SIGSEGV, &sa, NULL);
    sigaction(SIGUSR1, &sa, NULL);
    sigaction(SIGABRT, &sa, NULL);
    sigaction(SIGINT, &sa, NULL);
    sigaction(SIGBUS, &sa, NULL);
    sigaction(SIGSTKFLT, &sa, NULL);
    sigaction(SIGSYS, &sa, NULL);
    printf(" signal handlers initialised successfully n ");
}

我试着用构建这个

g++ -c SignalHandlers.cpp 
SignalHandlers.cpp: In function ‘void bt_sighandler(int, siginfo_t*, void*)’:
SignalHandlers.cpp:146:34: error: ‘REG_EIP’ was not declared in this scope
SignalHandlers.cpp:152:45: error: ‘REG_EIP’ was not declared in this scope

显然,在Maverick之后,/usr/include/sys/被移到了/usr/include/x86_64-linux-gnu/sys,但g++编译器路径在这次移动之后从未更新过。(这就是为什么以强制性的方式更新操作系统从来都不是一个好主意,最好在更新后让尘埃落定,但这台操作系统上的灰尘兔子似乎仍然被旋风困住了。(

在任何情况下,包括直接在ubuntu 12.04上的路径也不起作用:

$ g++ -I/usr/include/x86_64-linux-gnu/sys -c SignalHandlers.cpp 
In file included from /usr/include/x86_64-linux-gnu/sys/signal.h:1:0,
                 from /usr/include/x86_64-linux-gnu/sys/signal.h:1,
                 from /usr/include/x86_64-linux-gnu/sys/signal.h:1,
                 from /usr/include/x86_64-linux-gnu/sys/signal.h:1,
                 from /usr/include/x86_64-linux-gnu/sys/signal.h:1,
                 from /usr/include/x86_64-linux-gnu/sys/signal.h:1,
                 from /usr/include/x86_64-linux-gnu/sys/signal.h:1,
                 from /usr/include/x86_64-linux-gnu/sys/signal.h:1,
..............................................
                 from SignalHandlers.cpp:4:
/usr/include/x86_64-linux-gnu/sys/signal.h:1:20: error: #include nested too deeply
In file included from /usr/include/x86_64-linux-gnu/sys/signal.h:1:0,
                 from /usr/include/x86_64-linux-gnu/sys/signal.h:1,
                 from /usr/include/x86_64-linux-gnu/sys/signal.h:1,
                 from /usr/include/x86_64-linux-gnu/sys/signal.h:1,
                 from /usr/include/x86_64-linux-gnu/sys/signal.h:1,
                 from /usr/include/x86_64-linux-gnu/sys/signal.h:1,
 ..... and a lot more of those
                 from SignalHandlers.cpp:6:
/usr/include/x86_64-linux-gnu/sys/signal.h:1:20: error: #include nested too deeply
In file included from /usr/include/x86_64-linux-gnu/sys/signal.h:1:0,
                 from /usr/include/x86_64-linux-gnu/sys/signal.h:1,
                 from /usr/include/x86_64-linux-gnu/sys/signal.h:1,
                 from /usr/include/x86_64-linux-gnu/sys/signal.h:1,
                 from /usr/include/x86_64-linux-gnu/sys/signal.h:1,
                 from /usr/include/x86_64-linux-gnu/sys/signal.h:1,
                 from /usr/include/x86_64-linux-gnu/sys/signal.h:1,
                 from /usr/include/x86_64-linux-gnu/sys/signal.h:1,
.... and lots and lots more of those
                 from /usr/include/x86_64-linux-gnu/sys/ucontext.h:23,
                 from SignalHandlers.cpp:14:
/usr/include/x86_64-linux-gnu/sys/signal.h:1:20: error: #include nested too deeply
In file included from /usr/include/x86_64-linux-gnu/sys/unistd.h:1:0,
                 from /usr/include/x86_64-linux-gnu/sys/unistd.h:1,
                 from /usr/include/x86_64-linux-gnu/sys/unistd.h:1,
                 from /usr/include/x86_64-linux-gnu/sys/unistd.h:1,
.... lots and lots of that error
                 from /usr/include/c++/4.6/x86_64-linux-gnu/./bits/gthr-default.h:42,
                 from /usr/include/c++/4.6/x86_64-linux-gnu/./bits/gthr.h:170,
                 from /usr/include/c++/4.6/ext/atomicity.h:34,
                 from /usr/include/c++/4.6/bits/ios_base.h:41,
                 from /usr/include/c++/4.6/ios:43,
                 from /usr/include/c++/4.6/ostream:40,
                 from /usr/include/c++/4.6/iostream:40,
                 from SignalHandlers.cpp:19:
/usr/include/x86_64-linux-gnu/sys/unistd.h:1:20: error: #include nested too deeply
In file included from SignalHandlers.cpp:14:0:
/usr/include/x86_64-linux-gnu/sys/ucontext.h:139:5: error: ‘stack_t’ does not name a type
SignalHandlers.cpp:132:29: error: ‘siginfo_t’ has not been declared
SignalHandlers.cpp: In function ‘void bt_sighandler(int, int*, void*)’:
SignalHandlers.cpp:143:14: error: ‘SIGSEGV’ was not declared in this scope
SignalHandlers.cpp:145:36: error: request for member ‘si_addr’ in ‘* info’, which is of non-class type ‘int’
SignalHandlers.cpp:146:34: error: ‘REG_EIP’ was not declared in this scope
SignalHandlers.cpp:152:45: error: ‘REG_EIP’ was not declared in this scope
SignalHandlers.cpp: In function ‘void initialise_signal_handlers()’:
SignalHandlers.cpp:174:22: error: aggregate ‘initialise_signal_handlers()::sigaction sa’ has incomplete type and cannot be defined
SignalHandlers.cpp:177:29: error: ‘sigemptyset’ was not declared in this scope
SignalHandlers.cpp:178:19: error: ‘SA_RESTART’ was not declared in this scope
SignalHandlers.cpp:178:32: error: ‘SA_SIGINFO’ was not declared in this scope
SignalHandlers.cpp:181:15: error: ‘SIGSEGV’ was not declared in this scope
SignalHandlers.cpp:181:33: error: invalid use of incomplete type ‘struct initialise_signal_handlers()::sigaction’
SignalHandlers.cpp:174:12: error: forward declaration of ‘struct initialise_signal_handlers()::sigaction’
SignalHandlers.cpp:182:15: error: ‘SIGUSR1’ was not declared in this scope
SignalHandlers.cpp:182:33: error: invalid use of incomplete type ‘struct initialise_signal_handlers()::sigaction’
SignalHandlers.cpp:174:12: error: forward declaration of ‘struct initialise_signal_handlers()::sigaction’
SignalHandlers.cpp:183:15: error: ‘SIGABRT’ was not declared in this scope
SignalHandlers.cpp:183:33: error: invalid use of incomplete type ‘struct initialise_signal_handlers()::sigaction’
SignalHandlers.cpp:174:12: error: forward declaration of ‘struct initialise_signal_handlers()::sigaction’
SignalHandlers.cpp:184:15: error: ‘SIGINT’ was not declared in this scope
SignalHandlers.cpp:184:32: error: invalid use of incomplete type ‘struct initialise_signal_handlers()::sigaction’
SignalHandlers.cpp:174:12: error: forward declaration of ‘struct initialise_signal_handlers()::sigaction’
SignalHandlers.cpp:185:15: error: ‘SIGBUS’ was not declared in this scope
SignalHandlers.cpp:185:32: error: invalid use of incomplete type ‘struct initialise_signal_handlers()::sigaction’
SignalHandlers.cpp:174:12: error: forward declaration of ‘struct initialise_signal_handlers()::sigaction’
SignalHandlers.cpp:186:15: error: ‘SIGSTKFLT’ was not declared in this scope
SignalHandlers.cpp:186:35: error: invalid use of incomplete type ‘struct initialise_signal_handlers()::sigaction’
SignalHandlers.cpp:174:12: error: forward declaration of ‘struct initialise_signal_handlers()::sigaction’
SignalHandlers.cpp:187:15: error: ‘SIGSYS’ was not declared in this scope
SignalHandlers.cpp:187:32: error: invalid use of incomplete type ‘struct initialise_signal_handlers()::sigaction’
SignalHandlers.cpp:174:12: error: forward declaration of ‘struct initialise_signal_handlers()::sigaction’

g++版本:

$ g++ --version
g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

当我不使用-I。。。在命令行中。让我翻一翻,看看我能想出什么。

编辑:如果你不更改编译器的-I(不应该需要它(,那么我认为你要么需要传递-m32(为32位编译(,要么将REG_EIP更改为REG_RIP,因为你(我认为(是为64位编译。

像这样的东西会起作用:

#ifdef __x86_64__
#define REG_EIP REG_RIP
#endif

您正在为64位系统构建,因此REG_EIP不存在。它被REG_RIP取代。

最新更新