)]}'
{
  "commit": "8b87fe90e81f933b7c88e1ea25b02426ee3f58eb",
  "tree": "14b2c58d91a55257c36ecb44adfa10cad0ba46d0",
  "parents": [
    "a163e2015a4e2f9b6701832d3c40f848524e4793"
  ],
  "author": {
    "name": "Kevin Buettner",
    "email": "kevinb@redhat.com",
    "time": "Wed Apr 23 21:39:28 2025 -0700"
  },
  "committer": {
    "name": "Kevin Buettner",
    "email": "kevinb@redhat.com",
    "time": "Thu Apr 24 09:54:42 2025 -0700"
  },
  "message": "Don\u0027t attempt to find TLS address when target has no registers\n\nThis commit fixes two bugs, one of which is Bug 25807, which occurs\nwhen target_translate_tls_address() is called from\nlanguage_defn::read_var_value in findvar.c.  I found it while testing on\naarch64; it turned a KFAIL for gdb.threads/tls.exp: print a_thread_local\ninto a FAIL due to a GDB internal error.  Now, with this commit in place,\nthe KFAIL/FAIL turns into a PASS.\n\nIn addition to the existing test just noted, I\u0027ve also added a test to\nthe new test case gdb.base/tls-nothreads.exp.  It\u0027ll be tested, using\ndifferent scenarios, up to 8 times:\n\nPASS: gdb.base/tls-nothreads.exp: default: force_internal_tls\u003dfalse: after exit: print tls_tbss_1\nPASS: gdb.base/tls-nothreads.exp: default: force_internal_tls\u003dtrue: after exit: print tls_tbss_1\nPASS: gdb.base/tls-nothreads.exp: static: force_internal_tls\u003dfalse: after exit: print tls_tbss_1\nPASS: gdb.base/tls-nothreads.exp: static: force_internal_tls\u003dtrue: after exit: print tls_tbss_1\nPASS: gdb.base/tls-nothreads.exp: pthreads: force_internal_tls\u003dfalse: after exit: print tls_tbss_1\nPASS: gdb.base/tls-nothreads.exp: pthreads: force_internal_tls\u003dtrue: after exit: print tls_tbss_1\nPASS: gdb.base/tls-nothreads.exp: pthreads-static: force_internal_tls\u003dfalse: after exit: print tls_tbss_1\nPASS: gdb.base/tls-nothreads.exp: pthreads-static: force_internal_tls\u003dtrue: after exit: print tls_tbss_1\n\nThere is a related problem that occurs when target_translate_tls_address\nis called from find_minsym_type_and_address() in minsyms.c.  It can be\nobserved when debugging a program without debugging symbols when the\nprogram is not executing.  I\u0027ve written a new test for this, but it\u0027s\n(also) included in the new test case gdb.base/tls-nothreads.exp, found\nlater in this series.  Depending on the target, it can run up to 8\ntimes using different scenarios.  E.g., on aarch64, I\u0027m seeing these\nPASSes, all of which test this change:\n\nPASS: gdb.base/tls-nothreads.exp: default: force_internal_tls\u003dfalse: stripped: after exit: print (int) tls_tbss_1\nPASS: gdb.base/tls-nothreads.exp: default: force_internal_tls\u003dtrue: stripped: after exit: print (int) tls_tbss_1\nPASS: gdb.base/tls-nothreads.exp: static: force_internal_tls\u003dfalse: stripped: after exit: print (int) tls_tbss_1\nPASS: gdb.base/tls-nothreads.exp: static: force_internal_tls\u003dtrue: stripped: after exit: print (int) tls_tbss_1\nPASS: gdb.base/tls-nothreads.exp: pthreads: force_internal_tls\u003dfalse: stripped: after exit: print (int) tls_tbss_1\nPASS: gdb.base/tls-nothreads.exp: pthreads: force_internal_tls\u003dtrue: stripped: after exit: print (int) tls_tbss_1\nPASS: gdb.base/tls-nothreads.exp: pthreads-static: force_internal_tls\u003dfalse: stripped: after exit: print (int) tls_tbss_1\nPASS: gdb.base/tls-nothreads.exp: pthreads-static: force_internal_tls\u003dtrue: stripped: after exit: print (int) tls_tbss_1\n\nIn an earlier version of this commit (v4), I was checking whether the\ntarget has registers in language_defn::read_var_value in findvar.c and\nin find_minsym_type_and_address in minsyms.c, printing suitable error\nmessages in each case.  In his review of this commit for the v4\nseries, Tom Tromey asked whether it would be better to do this check\nin target_translate_tls_address.  I had considered doing that for the\nv4 (and earlier) series, but I wanted to print slightly different\nmessages at each check.  Also, read_var_value in findvar.c was already\nprinting a message in some cases and I had arranged for the later\ncheck in that function to match the original message.\n\nHowever, while I had added a target-has-registers check at two of the\ncall sites for target_translate_tls_address, I hadn\u0027t added it at the\nthird call site which is in dwarf_expr_context::execute_stack_op() in\ndwarf2/expr.c.  I believe that in most cases, this is handled by the\nearly check in language_defn::read_var_value...\n\n  else if (sym_need \u003d\u003d SYMBOL_NEEDS_REGISTERS \u0026\u0026 !target_has_registers ())\n    error (_(\"Cannot read `%s\u0027 without registers\"), var-\u003eprint_name ());\n\n...but it\u0027s entirely possible that dwarf_expr_context::execute_stack_op()\nmight get called in some other context.  So it makes sense to do the\ntarget-has-registers check for that case too.  And rather than add yet\nanother check at that call site, I decided that moving the check and\nerror message to target_translate_tls_address makes sense.\n\nI had to make the error messages that it prints somewhat more generic.\nIn particular, when called from language_defn::read_var_value, the\nmessage printed by target_translate_tls_address no longer matches the\nearlier message that could be printed (as shown above).  That meant\nthat the test cases which check for this message, gdb.threads/tls.exp,\nand gdb.base/tls-nothreads.exp had to be adjusted to account for the\nnew message.  Also, I think it\u0027s valuable to the user to know (if\npossible) the name of the variable that caused the error, so I\u0027ve\nadded an optional parameter to target_translate_tls_address, providing\nthe name of the variable, if it\u0027s known.  Therefore, the message\nthat\u0027s printed when the target-has-registers test fails is one of the\nfollowing:\n\nWhen the TLS variable isn\u0027t known (due to being called from\ndwarf_expr_context::execute_stack_op):\n\n    \"Cannot translate TLS address without registers\"\n\nWhen the TLS variable is known (from either of the other two call sites\nfor target_translate_tls_address):\n\n    \"Cannot find address of TLS symbol `%s\u0027 without registers\"\n\nBug: https://sourceware.org/bugzilla/show_bug.cgi?id\u003d25807\nTested-By: Luis Machado \u003cluis.machado@arm.com\u003e\nApproved-By: Luis Machado \u003cluis.machado@arm.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "29389313f943daac6ff00c0c6d8a974551744f72",
      "old_mode": 33188,
      "old_path": "gdb/findvar.c",
      "new_id": "9da5c4831a6ffe23b5f75507efc6f0f673712e2f",
      "new_mode": 33188,
      "new_path": "gdb/findvar.c"
    },
    {
      "type": "modify",
      "old_id": "649a9f17c3e0ed70869fe6ea680ac09dea41375a",
      "old_mode": 33188,
      "old_path": "gdb/minsyms.c",
      "new_id": "9ac3145cb629de27ecc1e3021466f7fc47c0e4e7",
      "new_mode": 33188,
      "new_path": "gdb/minsyms.c"
    },
    {
      "type": "modify",
      "old_id": "4a1964e664b3b34b36d4787d6ddf8f16c2f91bab",
      "old_mode": 33188,
      "old_path": "gdb/target.c",
      "new_id": "522bed8e939cc6bc098b3607b117017ee48540d2",
      "new_mode": 33188,
      "new_path": "gdb/target.c"
    },
    {
      "type": "modify",
      "old_id": "004494dc3c484a2ba46f65206e21e1687098ddbb",
      "old_mode": 33188,
      "old_path": "gdb/target.h",
      "new_id": "2d3bac77bd2af53b689c785a66da15c01692b43a",
      "new_mode": 33188,
      "new_path": "gdb/target.h"
    },
    {
      "type": "modify",
      "old_id": "1bc5df26233cf554eee2d77dce401654a43c15c4",
      "old_mode": 33188,
      "old_path": "gdb/testsuite/gdb.threads/tls.exp",
      "new_id": "73fada7bcd18617472cb4ee235fe187ecd76b564",
      "new_mode": 33188,
      "new_path": "gdb/testsuite/gdb.threads/tls.exp"
    }
  ]
}
