public inbox for gdb-prs@sourceware.org
help / color / mirror / Atom feed
* [Bug breakpoints/15729] gdb/MI error inserting new breakpoint
  2013-07-11  3:04 [Bug breakpoints/15729] New: gdb/MI error inserting new breakpoint sirnewton_01 at yahoo dot ca
@ 2013-07-11  3:04 ` sirnewton_01 at yahoo dot ca
  2021-07-01 13:07 ` cvs-commit at gcc dot gnu.org
  2021-07-01 13:12 ` pedro at palves dot net
  2 siblings, 0 replies; 4+ messages in thread
From: sirnewton_01 at yahoo dot ca @ 2013-07-11  3:04 UTC (permalink / raw)
  To: gdb-prs

http://sourceware.org/bugzilla/show_bug.cgi?id=15729

Chris McGee <sirnewton_01 at yahoo dot ca> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |sirnewton_01 at yahoo dot ca

-- 
You are receiving this mail because:
You are on the CC list for the bug.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug breakpoints/15729] New: gdb/MI error inserting new breakpoint
@ 2013-07-11  3:04 sirnewton_01 at yahoo dot ca
  2013-07-11  3:04 ` [Bug breakpoints/15729] " sirnewton_01 at yahoo dot ca
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: sirnewton_01 at yahoo dot ca @ 2013-07-11  3:04 UTC (permalink / raw)
  To: gdb-prs

http://sourceware.org/bugzilla/show_bug.cgi?id=15729

            Bug ID: 15729
           Summary: gdb/MI error inserting new breakpoint
           Product: gdb
           Version: 7.6
            Status: NEW
          Severity: normal
          Priority: P2
         Component: breakpoints
          Assignee: unassigned at sourceware dot org
          Reporter: sirnewton_01 at yahoo dot ca

I am trying to add a breakpoint using gdb/MI on Linux x86_64. Whenever I add it
I get an error message like '^error,msg="Cannot access memory at address
0x400c3d"'

Here's my setup:
1) Launch gdb like the following: "gdb -i=mi <path_to_program>"
2) Set the following option: "-gdb-set target-async 1"
3) Set the following option: "-gdb-set non-stop on"
4) Start the program: "-exec-run"
5) Attempt to set a breakpoint "-break-insert some_func"

Result:
I get the error message above. The same error shows up even if I try the '-f'
option of the "-break-insert" command.

Expected Result:
The breakpoint is added or an error message indicating that break points can't
be added unless the thread is stopped.

After some debugging I discovered that one of the differences between setting
the breakpoint when the thread is stopped versus running is in the following
function: memory_xfer_partial_1 in target.c. In the successful case line 1556
is false and "inf" is set to NULL. In the failure case "inf" is assigned to a
non-NULL value and the error is presented.

Here is the backtrace that leads back to the error:
#0  memory_error (status=5, memaddr=4197437) at corefile.c:200
#1  0x0000000000591729 in read_memory (memaddr=4197437, 
    myaddr=<optimized out>, len=<optimized out>) at corefile.c:223
#2  0x000000000059183d in read_memory_unsigned_integer (
    memaddr=<optimized out>, len=1, byte_order=BFD_ENDIAN_LITTLE)
    at corefile.c:312
#3  0x000000000040a228 in amd64_analyze_prologue (gdbarch=0x20d7cd0, 
    pc=4197437, current_pc=18446744073709551615, cache=0x7fff8b60c460)
    at amd64-tdep.c:2126
#4  0x000000000040ad57 in amd64_skip_prologue (gdbarch=0x20d7cd0, 
    start_pc=4197437) at amd64-tdep.c:2273
#5  0x00000000004f5f8b in skip_prologue_sal (sal=0x7fff8b60c760)
    at symtab.c:2869
#6  0x00000000004f62d7 in find_function_start_sal (sym=0x214ac30, 
    funfirstline=1) at symtab.c:2782
#7  0x000000000050360d in symbol_to_sal (result=0x7fff8b60c880, 
    funfirstline=<optimized out>, sym=0x214ac30) at linespec.c:3622
#8  0x00000000005042c1 in convert_linespec_to_sals (state=0x7fff8b60ccc0, 
    ls=0x7fff8b60cd00) at linespec.c:2028
#9  0x00000000005069fc in parse_linespec (parser=0x7fff8b60cc90, 
    argptr=<optimized out>) at linespec.c:2319
#10 0x00000000005073f5 in decode_line_full (argptr=0x7fff8b60cf48, 
    flags=<optimized out>, default_symtab=<optimized out>, 
    default_line=<optimized out>, canonical=0x7fff8b60cf50, select_mode=0x0, 
    filter=0x0) at linespec.c:2430
#11 0x00000000004b79ea in parse_breakpoint_sals (address=0x7fff8b60cf48, 
    canonical=0x7fff8b60cf50) at breakpoint.c:9323
#12 0x00000000004bfab1 in create_breakpoint (gdbarch=0x2105a00, 
    arg=0x20d4109 "", cond_string=0x0, thread=-1, extra_string=0x0, 
    parse_condition_and_thread=0, tempflag=0, type_wanted=bp_breakpoint, 
    ignore_count=0, pending_break_support=AUTO_BOOLEAN_FALSE, 
    ops=0xae6640 <bkpt_breakpoint_ops>, from_tty=0, enabled=1, internal=0, 
    flags=0) at breakpoint.c:9554
#13 0x000000000047a114 in mi_cmd_break_insert (command=<optimized out>, 
    argv=<optimized out>, argc=<optimized out>) at ./mi/mi-cmd-break.c:186
#14 0x00000000004807fd in mi_cmd_execute (parse=0x2107e70)
    at ./mi/mi-main.c:2133
#15 captured_mi_execute_command (context=0x2107e70, uiout=0x20d11e0)
    at ./mi/mi-main.c:1884
#16 mi_execute_command (cmd=0x20fb9e0 "-break-insert main.main", 
    from_tty=<optimized out>) at ./mi/mi-main.c:2003
#17 0x000000000047bacd in mi_execute_command_wrapper (cmd=<optimized out>)
    at ./mi/mi-interp.c:311
#18 mi_execute_command_input_handler (cmd=<optimized out>)
    at ./mi/mi-interp.c:319
#19 0x000000000052c8b3 in process_event () at event-loop.c:342
    at ./mi/mi-main.c:1884
#16 mi_execute_command (cmd=0x20fb9e0 "-break-insert main.main", 
    from_tty=<optimized out>) at ./mi/mi-main.c:2003
#17 0x000000000047bacd in mi_execute_command_wrapper (cmd=<optimized out>)
    at ./mi/mi-interp.c:311
#18 mi_execute_command_input_handler (cmd=<optimized out>)
    at ./mi/mi-interp.c:319
#19 0x000000000052c8b3 in process_event () at event-loop.c:342
#20 process_event () at event-loop.c:314
#21 0x000000000052cc78 in gdb_do_one_event () at event-loop.c:406
#22 0x000000000052ce15 in start_event_loop () at event-loop.c:431
#23 0x0000000000526293 in captured_command_loop (data=<optimized out>)
    at main.c:258
#24 0x0000000000524e4b in catch_errors (func=0x526280 <captured_command_loop>, 
    func_args=0x0, errstring=0x6e1f93 "", mask=6) at exceptions.c:546
#25 0x0000000000526bf6 in captured_main (data=<optimized out>) at main.c:1041
#26 0x0000000000524e4b in catch_errors (func=0x526590 <captured_main>, 
    func_args=0x7fff8b60d3d0, errstring=0x6e1f93 "", mask=6)
    at exceptions.c:546
#27 0x0000000000527584 in gdb_main (args=<optimized out>) at main.c:1050
#28 0x000000000040769e in main (argc=<optimized out>, argv=<optimized out>)
    at gdb.c:34

Here are the records of my steps through the code in the success and failure
cases:

failure path through memory_xfer_partial_1:
Breakpoint 1, memory_xfer_partial_1 (ops=0x141bac0, 
    object=TARGET_OBJECT_MEMORY, readbuf=0x7fffd028cb90, writebuf=0x0, 
    memaddr=4197437, len=18) at target.c:1434
1434      if (readbuf != NULL && overlay_debugging)
(gdb) n
1454      if (readbuf != NULL && trust_readonly)
(gdb) n
1476      if (readbuf != NULL && get_traceframe_number () != -1)
(gdb) n
1527      region = lookup_mem_region (memaddr);
(gdb) n
1529      if (memaddr + len < region->hi || region->hi == 0)
(gdb) n
1530        reg_len = len;
(gdb) n
1534      switch (region->attrib.mode)
(gdb) n
1556      if (!ptid_equal (inferior_ptid, null_ptid))
(gdb) n
1557        inf = find_inferior_pid (ptid_get_pid (inferior_ptid));
(gdb) n
1561      if (inf != NULL
(gdb) n
1565          && get_traceframe_number () == -1
(gdb) n
1566          && (region->attrib.cache
(gdb) n
1567          || (stack_cache_enabled_p && object ==
TARGET_OBJECT_STACK_MEMORY)))
(gdb) n
1597          res = ops->to_xfer_partial (ops, TARGET_OBJECT_MEMORY, NULL,
(gdb) n
1599          if (res > 0)
(gdb) n
1604          if (ops->to_has_all_memory (ops))
(gdb) n
1605        break;
(gdb) n
1615      if (res > 0
(gdb) n
1627      return res;
(gdb) n
1628    }
(gdb) n
memory_xfer_partial (ops=0x141bac0, object=TARGET_OBJECT_MEMORY, 
    readbuf=0x7fffd028cb90, writebuf=0x0, memaddr=4197437, len=18)
    at target.c:1651
1651          if (res > 0 && !show_memory_breakpoints)
(gdb) print res
$1 = 0


successful path through memory_xfer_partial_1:
Breakpoint 1, memory_xfer_partial_1 (ops=0xbf27c0 <exec_ops>, 
    object=TARGET_OBJECT_MEMORY, readbuf=0x7fffd028cb90, writebuf=0x0, 
    memaddr=4197437, len=18) at target.c:1434
1434      if (readbuf != NULL && overlay_debugging)
(gdb) n
1454      if (readbuf != NULL && trust_readonly)
(gdb) n
1476      if (readbuf != NULL && get_traceframe_number () != -1)
(gdb) n
1527      region = lookup_mem_region (memaddr);
(gdb) n
1529      if (memaddr + len < region->hi || region->hi == 0)
(gdb) n
1530        reg_len = len;
(gdb) n
1534      switch (region->attrib.mode)
(gdb) n
1556      if (!ptid_equal (inferior_ptid, null_ptid))
(gdb) n
1559        inf = NULL;
(gdb) n
1561      if (inf != NULL
(gdb) n
1597          res = ops->to_xfer_partial (ops, TARGET_OBJECT_MEMORY, NULL,
(gdb) n
1599          if (res > 0)
(gdb) n
1600        break;
(gdb) n
1615      if (res > 0
(gdb) n
1616          && inf != NULL
(gdb) n
1627      return res;
(gdb) n
1628    }
(gdb) n
memory_xfer_partial (ops=0xbf27c0 <exec_ops>, object=TARGET_OBJECT_MEMORY, 
    readbuf=0x7fffd028cb90, writebuf=0x0, memaddr=4197437, len=18)
    at target.c:1651
1651          if (res > 0 && !show_memory_breakpoints)
(gdb) print res
$3 = 18

-- 
You are receiving this mail because:
You are on the CC list for the bug.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug breakpoints/15729] gdb/MI error inserting new breakpoint
  2013-07-11  3:04 [Bug breakpoints/15729] New: gdb/MI error inserting new breakpoint sirnewton_01 at yahoo dot ca
  2013-07-11  3:04 ` [Bug breakpoints/15729] " sirnewton_01 at yahoo dot ca
@ 2021-07-01 13:07 ` cvs-commit at gcc dot gnu.org
  2021-07-01 13:12 ` pedro at palves dot net
  2 siblings, 0 replies; 4+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2021-07-01 13:07 UTC (permalink / raw)
  To: gdb-prs

https://sourceware.org/bugzilla/show_bug.cgi?id=15729

--- Comment #1 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Pedro Alves <palves@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=05c06f318fd9a112529dfc313e6512b399a645e4

commit 05c06f318fd9a112529dfc313e6512b399a645e4
Author: Pedro Alves <pedro@palves.net>
Date:   Fri Jun 11 17:56:32 2021 +0100

    Linux: Access memory even if threads are running

    Currently, on GNU/Linux, if you try to access memory and you have a
    running thread selected, GDB fails the memory accesses, like:

     (gdb) c&
     Continuing.
     (gdb) p global_var
     Cannot access memory at address 0x555555558010

    Or:

     (gdb) b main
     Breakpoint 2 at 0x55555555524d: file access-mem-running.c, line 59.
     Warning:
     Cannot insert breakpoint 2.
     Cannot access memory at address 0x55555555524d

    This patch removes this limitation.  It teaches the native Linux
    target to read/write memory even if the target is running.  And it
    does this without temporarily stopping threads.  We now get:

     (gdb) c&
     Continuing.
     (gdb) p global_var
     $1 = 123
     (gdb) b main
     Breakpoint 2 at 0x555555555259: file access-mem-running.c, line 62.

    (The scenarios above work correctly with current GDBserver, because
    GDBserver temporarily stops all threads in the process whenever GDB
    wants to access memory (see prepare_to_access_memory /
    done_accessing_memory).  Freezing the whole process makes sense when
    we need to be sure that we have a consistent view of memory and don't
    race with the inferior changing it at the same time as GDB is
    accessing it.  But I think that's a too-heavy hammer for the default
    behavior.  I think that ideally, whether to stop all threads or not
    should be policy decided by gdb core, probably best implemented by
    exposing something like gdbserver's prepare_to_access_memory /
    done_accessing_memory to gdb core.)

    Currently, if we're accessing (reading/writing) just a few bytes, then
    the Linux native backend does not try accessing memory via
    /proc/<pid>/mem and goes straight to ptrace
    PTRACE_PEEKTEXT/PTRACE_POKETEXT.  However, ptrace always fails when
    the ptracee is running.  So the first step is to prefer
    /proc/<pid>/mem even for small accesses.  Without further changes
    however, that may cause a performance regression, due to constantly
    opening and closing /proc/<pid>/mem for each memory access.  So the
    next step is to keep the /proc/<pid>/mem file open across memory
    accesses.  If we have this, then it doesn't make sense anymore to even
    have the ptrace fallback, so the patch disables it.

    I've made it such that GDB only ever has one /proc/<pid>/mem file open
    at any time.  As long as a memory access hits the same inferior
    process as the previous access, then we reuse the previously open
    file.  If however, we access memory of a different process, then we
    close the previous file and open a new one for the new process.

    If we wanted, we could keep one /proc/<pid>/mem file open per
    inferior, and never close them (unless the inferior exits or execs).
    However, having seen bfd patches recently about hitting too many open
    file descriptors, I kept the logic to have only one file open tops.
    Also, we need to handle memory accesses for processes for which we
    don't have an inferior object, for when we need to detach a
    fork-child, and we'd probaly want to handle caching the open file for
    that scenario (no inferior for process) too, which would probably end
    up meaning caching for last non-inferior process, which is very much
    what I'm proposing anyhow.  So always having one file open likely ends
    up a smaller patch.

    The next step is handling the case of GDB reading/writing memory
    through a thread that is running and exits.  The access should not
    result in a user-visible failure if the inferior/process is still
    alive.

    Once we manage to open a /proc/<lwpid>/mem file, then that file is
    usable for memory accesses even if the corresponding lwp exits and is
    reaped.  I double checked that trying to open the same
    /proc/<lwpid>/mem path again fails because the lwp is really gone so
    there's no /proc/<lwpid>/ entry on the filesystem anymore, but the
    previously open file remains usable.  It's only when the whole process
    execs that we need to reopen a new file.

    When the kernel destroys the whole address space, i.e., when the
    process exits or execs, the reads/writes fail with 0 aka EOF, in which
    case there's nothing else to do than returning a memory access
    failure.  Note this means that when we get an exec event, we need to
    reopen the file, to access the process's new address space.

    If we need to open (or reopen) the /proc/<pid>/mem file, and the LWP
    we're opening it for exits before we open it and before we reap the
    LWP (i.e., the LWP is zombie), the open fails with EACCES.  The patch
    handles this by just looking for another thread until it finds one
    that we can open a /proc/<pid>/mem successfully for.

    If we need to open (or reopen) the /proc/<pid>/mem file, and the LWP
    we're opening has exited and we already reaped it, which is the case
    if the selected thread is in THREAD_EXIT state, the open fails with
    ENOENT.  The patch handles this the same way as a zombie race
    (EACCES), instead of checking upfront whether we're accessing a
    known-exited thread, because that would result in more complicated
    code, because we also need to handle accessing lwps that are not
    listed in the core thread list, and it's the core thread list that
    records the THREAD_EXIT state.

    The patch includes two testcases:

    #1 - gdb.base/access-mem-running.exp

      This is the conceptually simplest - it is single-threaded, and has
      GDB read and write memory while the program is running.  It also
      tests setting a breakpoint while the program is running, and checks
      that the breakpoint is hit immediately.

    #2 - gdb.threads/access-mem-running-thread-exit.exp

      This one is more elaborate, as it continuously spawns short-lived
      threads in order to exercise accessing memory just while threads are
      exiting.  It also spawns two different processes and alternates
      accessing memory between the two processes to exercise the reopening
      the /proc file frequently.  This also ends up exercising GDB reading
      from an exited thread frequently.  I confirmed by putting abort()
      calls in the EACCES/ENOENT paths added by the patch that we do hit
      all of them frequently with the testcase.  It also exits the
      process's main thread (i.e., the main thread becomes zombie), to
      make sure accessing memory in such a corner-case scenario works now
      and in the future.

    The tests fail on GNU/Linux native before the code changes, and pass
    after.  They pass against current GDBserver, again because GDBserver
    supports memory access even if all threads are running, by
    transparently pausing the whole process.

    gdb/ChangeLog:
    yyyy-mm-dd  Pedro Alves  <pedro@palves.net>

            PR mi/15729
            PR gdb/13463
            * linux-nat.c (linux_nat_target::detach): Close the
            /proc/<pid>/mem file if it was open for this process.
            (linux_handle_extended_wait) <PTRACE_EVENT_EXEC>: Close the
            /proc/<pid>/mem file if it was open for this process.
            (linux_nat_target::mourn_inferior): Close the /proc/<pid>/mem file
            if it was open for this process.
            (linux_nat_target::xfer_partial): Adjust.  Do not fall back to
            inf_ptrace_target::xfer_partial for memory accesses.
            (last_proc_mem_file): New.
            (maybe_close_proc_mem_file): New.
            (linux_proc_xfer_memory_partial_pid): New, with bits factored out
            from linux_proc_xfer_partial.
            (linux_proc_xfer_partial): Delete.
            (linux_proc_xfer_memory_partial): New.

    gdb/testsuite/ChangeLog
    yyyy-mm-dd  Pedro Alves  <pedro@palves.net>

            PR mi/15729
            PR gdb/13463
            * gdb.base/access-mem-running.c: New.
            * gdb.base/access-mem-running.exp: New.
            * gdb.threads/access-mem-running-thread-exit.c: New.
            * gdb.threads/access-mem-running-thread-exit.exp: New.

    Change-Id: Ib3c082528872662a3fc0ca9b31c34d4876c874c9

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug breakpoints/15729] gdb/MI error inserting new breakpoint
  2013-07-11  3:04 [Bug breakpoints/15729] New: gdb/MI error inserting new breakpoint sirnewton_01 at yahoo dot ca
  2013-07-11  3:04 ` [Bug breakpoints/15729] " sirnewton_01 at yahoo dot ca
  2021-07-01 13:07 ` cvs-commit at gcc dot gnu.org
@ 2021-07-01 13:12 ` pedro at palves dot net
  2 siblings, 0 replies; 4+ messages in thread
From: pedro at palves dot net @ 2021-07-01 13:12 UTC (permalink / raw)
  To: gdb-prs

https://sourceware.org/bugzilla/show_bug.cgi?id=15729

Pedro Alves <pedro at palves dot net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED
                 CC|                            |pedro at palves dot net

--- Comment #2 from Pedro Alves <pedro at palves dot net> ---
I believe this is fixed now.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-07-01 13:12 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-11  3:04 [Bug breakpoints/15729] New: gdb/MI error inserting new breakpoint sirnewton_01 at yahoo dot ca
2013-07-11  3:04 ` [Bug breakpoints/15729] " sirnewton_01 at yahoo dot ca
2021-07-01 13:07 ` cvs-commit at gcc dot gnu.org
2021-07-01 13:12 ` pedro at palves dot net

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).