最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - GDB different function names and addresses than expected - Stack Overflow

programmeradmin1浏览0评论

I'm trying to capture when a child executes an abort.

The following is a MCVE that should give an idea of what I'm trying to do.

#include <iostream>
#include <cstdio>
#include <iomanip> //to make things legible

#include <sys/ptrace.h>
#include <sys/wait.h>
#include <libunwind-ptrace.h>

#include <unistd.h>
#include <sys/types.h>

using namespace std;
int getBacktrace(pid_t pid)
{
  int rv = 0;

  unw_addr_space_t as = unw_create_addr_space(&_UPT_accessors, 0);

  if(!as)
  {
    return rv;
  }

  void *context = _UPT_create(pid);

  unw_cursor_t cursor;

  if(unw_init_remote(&cursor, as, context) == 0)
  {
    cout << "Abort: " << std::hex << (long)*abort << endl;
    do
    {
      unw_proc_info_t pi;
      if(unw_get_proc_info(&cursor, &pi) >= 0)
      {
        if((long)pi.start_ip == (long)abort)
        {
          cout << "abort found!\n";
          //do some recovery stuff here.so WIFEXITED won't work and WIFSIGNALED can give a false alarm
          rv = 1;
          break;
        }

        //Just for fun, let's print the backtrace
        unw_word_t offset, pc;
        char sym[4096];
        if(unw_get_reg(&cursor, UNW_REG_IP, &pc) != 0)
        {
          cout << "Unknown PC\n";
        }
        else
        {
          cout << "0x" << std::hex << pc << " ";
        }

        if(unw_get_proc_name(&cursor, sym, sizeof(sym), &offset) != 0)
        {
          cout << "<unknown>\n";
        }
        else
        {
          cout << sym << "+0x" << std::hex << offset << endl;
        }

        cout << "\tfunction range: " << std::hex << pi.start_ip << "-" << pi.end_ip << endl;
      }
    }while(unw_step(&cursor) > 0);
    cout << endl << endl; //Add spacing to make it easier to read.
  }

  if(context)
  {
    _UPT_destroy(context);
  }
  cout << std::dec;
  return rv;
}

int childFunction()
{
  //This is just an example function maybe it throws maybe it doesn't
  sleep(5);
  throw 42;
}

int main()
{
  pid_t childPid;

  if((childPid = fork()) == 0)
  {
    ptrace(PTRACE_TRACEME, 0, nullptr, nullptr);
    //child
    childFunction();
  }
  else
  {
    while(true)
    {
      waitpid(childPid, nullptr, 0);

      if(getBacktrace(childPid))
      {
        //do some logging or functionality here
        cout << "Child aborted\n";
        break;
      }
      ptrace(PTRACE_CONT, childPid, nullptr, nullptr);
    }
  }
}

However, I get output similar to the following:

Abort: 3fffac87c3b8
0x3fffac6e4bc0 <unknown>
        function range: 3fffac6e4a70-3fffac6e4c30
0x3fffac6c9540 <unknown>
        function range: 3fffac6c92f8-3fffac6c95a0
0x3fffaca9e338 <unknown>
        function range: 3fffaca9e1f0-3fffaca9e434
0x3fffaca9a964 <unknown>
        function range: 3fffaca9a940-3fffaca9a988
0x3fffaca9aa28 <unknown>
        function range: 3fffaca9aa10-3fffaca9aa38
0x3fffaca9af18 <unknown>
        function range: 3fffaca9aea0-3fffaca9af28
0x12af30a88 <unknown>
        function range: 12af30a38-12af30a98
0x12af30af0 <unknown>
        function range: 12af30a98-12af30b98
0x3fffac6c98c4 <unknown>
        function range: 3fffac6c9770-3fffac6c9a34
0x3fffac6c9ae0 <unknown>
        function range: 3fffac6c9a40-3fffac6c9aec

Now I know that the second frame from the top is the abort; however, none of the addresses match up.

If I debug with gdb, I get this:

[1

I have a few questions:

  1. Why is gdb instead of showing __GI_abort instead of abort as the function name?
  2. How do I get the address of __GI_abort? I tried just swapping out abort with it, but g++ is claiming that it isn't declared.

I'm trying to capture when a child executes an abort.

The following is a MCVE that should give an idea of what I'm trying to do.

#include <iostream>
#include <cstdio>
#include <iomanip> //to make things legible

#include <sys/ptrace.h>
#include <sys/wait.h>
#include <libunwind-ptrace.h>

#include <unistd.h>
#include <sys/types.h>

using namespace std;
int getBacktrace(pid_t pid)
{
  int rv = 0;

  unw_addr_space_t as = unw_create_addr_space(&_UPT_accessors, 0);

  if(!as)
  {
    return rv;
  }

  void *context = _UPT_create(pid);

  unw_cursor_t cursor;

  if(unw_init_remote(&cursor, as, context) == 0)
  {
    cout << "Abort: " << std::hex << (long)*abort << endl;
    do
    {
      unw_proc_info_t pi;
      if(unw_get_proc_info(&cursor, &pi) >= 0)
      {
        if((long)pi.start_ip == (long)abort)
        {
          cout << "abort found!\n";
          //do some recovery stuff here.so WIFEXITED won't work and WIFSIGNALED can give a false alarm
          rv = 1;
          break;
        }

        //Just for fun, let's print the backtrace
        unw_word_t offset, pc;
        char sym[4096];
        if(unw_get_reg(&cursor, UNW_REG_IP, &pc) != 0)
        {
          cout << "Unknown PC\n";
        }
        else
        {
          cout << "0x" << std::hex << pc << " ";
        }

        if(unw_get_proc_name(&cursor, sym, sizeof(sym), &offset) != 0)
        {
          cout << "<unknown>\n";
        }
        else
        {
          cout << sym << "+0x" << std::hex << offset << endl;
        }

        cout << "\tfunction range: " << std::hex << pi.start_ip << "-" << pi.end_ip << endl;
      }
    }while(unw_step(&cursor) > 0);
    cout << endl << endl; //Add spacing to make it easier to read.
  }

  if(context)
  {
    _UPT_destroy(context);
  }
  cout << std::dec;
  return rv;
}

int childFunction()
{
  //This is just an example function maybe it throws maybe it doesn't
  sleep(5);
  throw 42;
}

int main()
{
  pid_t childPid;

  if((childPid = fork()) == 0)
  {
    ptrace(PTRACE_TRACEME, 0, nullptr, nullptr);
    //child
    childFunction();
  }
  else
  {
    while(true)
    {
      waitpid(childPid, nullptr, 0);

      if(getBacktrace(childPid))
      {
        //do some logging or functionality here
        cout << "Child aborted\n";
        break;
      }
      ptrace(PTRACE_CONT, childPid, nullptr, nullptr);
    }
  }
}

However, I get output similar to the following:

Abort: 3fffac87c3b8
0x3fffac6e4bc0 <unknown>
        function range: 3fffac6e4a70-3fffac6e4c30
0x3fffac6c9540 <unknown>
        function range: 3fffac6c92f8-3fffac6c95a0
0x3fffaca9e338 <unknown>
        function range: 3fffaca9e1f0-3fffaca9e434
0x3fffaca9a964 <unknown>
        function range: 3fffaca9a940-3fffaca9a988
0x3fffaca9aa28 <unknown>
        function range: 3fffaca9aa10-3fffaca9aa38
0x3fffaca9af18 <unknown>
        function range: 3fffaca9aea0-3fffaca9af28
0x12af30a88 <unknown>
        function range: 12af30a38-12af30a98
0x12af30af0 <unknown>
        function range: 12af30a98-12af30b98
0x3fffac6c98c4 <unknown>
        function range: 3fffac6c9770-3fffac6c9a34
0x3fffac6c9ae0 <unknown>
        function range: 3fffac6c9a40-3fffac6c9aec

Now I know that the second frame from the top is the abort; however, none of the addresses match up.

If I debug with gdb, I get this:

[1

I have a few questions:

  1. Why is gdb instead of showing __GI_abort instead of abort as the function name?
  2. How do I get the address of __GI_abort? I tried just swapping out abort with it, but g++ is claiming that it isn't declared.
Share Improve this question asked Feb 17 at 17:54 SailorCireSailorCire 5941 gold badge8 silver badges24 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

Why is gdb instead of showing __GI_abort instead of abort as the function name?

These are aliases of each other (note that they are at the same address):

readelf -Ws glibc-build/libc.so | grep 'abort$'

  7155: 0000000000024ec0   116 FUNC    LOCAL  DEFAULT   15 __GI_abort
  7947: 0000000000024ec0   116 FUNC    GLOBAL DEFAULT   15 abort

You can't use the __GI_abort symbol because it is local to libc.so.6.

On my Linux x86_64 system your MCVE works, and I don't see anything immediately wrong with it.

$ ./a.out
terminate called after throwing an instance of 'int'
Abort: 7fb23783f41a
0x7fb2378a53ac pthread_key_delete+0x14c
        function range: 7fb2378a52a0-7fb2378a53ea
0x7fb2378564f2 gsignal+0x12
        function range: 7fb2378564e0-7fb237856511
abort found!


Child aborted
发布评论

评论列表(0)

  1. 暂无评论