Re: [PATCH 13/13] Document "no debug info debugging" improvements

Pedro Alves
2017-07-13T13:54:09Z

On 07/13/2017 02:51 PM, Pedro Alves wrote:
> On 07/13/2017 12:09 PM, Pedro Alves wrote:
>
>> I woke up thinking that mapping to unprototyped is the wrong
>> equivalence -- that it'd be better to assume the function is
>> prototyped, since that's how most C functions are written as
>> nowadays. Also, there's no such thing as an unprototyped
>> function in C++.
>>
>> Assuming prototyped would allow this, for example:
>>
>> float mult (float v1, float v2) { return v1 * v2; }
>>
>> (gdb) p (float) mult (2.0f, 3.0f)
>> $1 = 6
>> (gdb) p (float) mult ((float) 2, (float) 3)
>> $2 = 6
>> (gdb) p ((float (*) (float, float)) mult) (2, 3)
>> $3 = 6
>>
>> (gdb) ptype 2.0f
>> type = float
>> (gdb) ptype 2.0
>> type = double
>>
>> If the function really is unprototyped, then you'd still be
>> able to call it correctly via the function pointer cast syntax:
>>
>> float mult_noproto (v1, v2)
>> float v1, v2;
>> { return v1 * v2; }
>>
>> (gdb) p ((float (*) ()) mult_noproto) (2.0f, 3.0f)
>> $1 = 6
>> (gdb) p ((float (*) ()) mult_noproto) (2.0, 3.0)
>> $2 = 6
>> (gdb) p ((float (*) ()) mult_noproto) ((float) 2, (float) 3)
>> $3 = 6
>>
>> I'll give this a try, and add those as tests to gdb.base/nodebug.exp.
>
> This worked nicely, see below.
>
> I'll tweak the docs, and send an updated patch.
>

Err, now with patch.

From 3bdd3f159fa7b3a24f31f779da28e3d699447d1d Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Thu, 13 Jul 2017 11:20:43 +0100
Subject: [PATCH] assume prototyped

---
gdb/infcall.c | 15 +++++++++++++++
gdb/testsuite/gdb.base/nodebug.c | 39 ++++++++++++++++++++++++++++++++++++++
gdb/testsuite/gdb.base/nodebug.exp | 25 ++++++++++++++++++++++++
3 files changed, 79 insertions(+)

diff --git a/gdb/infcall.c b/gdb/infcall.c
index 9593875..b09dc8f 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -981,6 +981,21 @@ call_function_by_hand_dummy (struct value *function,
prototyped. Can we respect TYPE_VARARGS? Probably not. */
if (TYPE_CODE (ftype) == TYPE_CODE_METHOD)
prototyped = 1;
+ if (TYPE_TARGET_TYPE (ftype) == NULL && TYPE_NFIELDS (ftype) == 0
+ && default_return_type != NULL)
+ {
+ /* Calling a no-debug function with the return type
+ explicitly cast. Assume the function is prototyped,
+ with a prototype matching the types of the arguments.
+ E.g., with:
+ float mult (float v1, float v2) { return v1 * v2; }
+ This:
+ (gdb) p (float) mult (2.0f, 3.0f)
+ Is a simpler alternative to:
+ (gdb) p ((float (*) (float, float)) mult) (2.0f, 3.0f)
+ */
+ prototyped = 1;
+ }
else if (i < TYPE_NFIELDS (ftype))
prototyped = TYPE_PROTOTYPED (ftype);
else
diff --git a/gdb/testsuite/gdb.base/nodebug.c b/gdb/testsuite/gdb.base/nodebug.c
index 5cb763b..29cd3f7 100644
--- a/gdb/testsuite/gdb.base/nodebug.c
+++ b/gdb/testsuite/gdb.base/nodebug.c
@@ -15,6 +15,45 @@ uint32_t dataglobal32_2 = 0x000000ff;
uint64_t dataglobal64_1 = 0x7fffffffffffffff;
uint64_t dataglobal64_2 = 0x00000000000000ff;

+float
+multf (float v1, float v2)
+{
+ return v1 * v2;
+}
+
+float
+multf_noproto (v1, v2)
+ float v1, v2;
+{
+ return v1 * v2;
+}
+
+double
+mult (double v1, double v2)
+{
+ return v1 * v2;
+}
+
+double
+mult_noproto (v1, v2)
+ double v1, v2;
+{
+ return v1 * v2;
+}
+
+uint8_t
+add8 (uint8_t v1, uint8_t v2)
+{
+ return v1 + v2;
+}
+
+uint8_t
+add8_noproto (v1, v2)
+ uint8_t v1, v2;
+{
+ return v1 + v2;
+}
+
int
inner (int x)
{
diff --git a/gdb/testsuite/gdb.base/nodebug.exp b/gdb/testsuite/gdb.base/nodebug.exp
index c6e78e2..858d9d9 100644
--- a/gdb/testsuite/gdb.base/nodebug.exp
+++ b/gdb/testsuite/gdb.base/nodebug.exp
@@ -210,6 +210,31 @@ if [runto inner] then {

gdb_test "ptype bsslocal" $data_var_type

+ # Call prototyped function with float parameters via both
+ # return-type cast and function-pointer cast. This checks that
+ # GDB doesn't do float->double coercion.
+ gdb_test "p (float) multf (2.0f, 3.0f)" " = 6"
+ gdb_test "p ((float (*) (float, float)) multf) (2, 3)" " = 6"
+ gdb_test "p ((float (*) (float, float)) multf) (2.0f, 3.0f)" " = 6"
+
+ # Call unprototyped function with float parameters via
+ # function-pointer cast, only. return-type cast assumes
+ # protototyped. Check that GDB does float->double coercion.
+ gdb_test "p ((float (*) ()) multf_noproto) (2.0f, 3.0f)" " = 6"
+ gdb_test "p ((float (*) ()) multf_noproto) (2.0, 3.0)" " = 6"
+
+ # Same, but for double.
+ gdb_test "p (double) mult (2.0, 3.0)" " = 6"
+ gdb_test "p ((double (*) (double, double)) mult) (2.0f, 3.0f)" " = 6"
+ gdb_test "p ((double (*) (double, double)) mult) (2, 3)" " = 6"
+ gdb_test "p ((double (*) ()) mult_noproto) (2.0f, 3.0f)" " = 6"
+ gdb_test "p ((double (*) ()) mult_noproto) (2.0, 3.0)" " = 6"
+
+ # Check that GDB promotes char->int correctly.
+ gdb_test "p /d (uint8) add8 ((uint8) 2, (uint8) 3)" " = 5"
+ gdb_test "p /d ((uint8 (*) (uint8, uint8)) add8) (2, 3)" " = 5"
+ gdb_test "p /d ((uint8 (*) ()) add8_noproto) (2, 3)" " = 5"
+
gdb_test "backtrace 10" "#0.*inner.*#1.*middle.*#2.*top.*#3.*main.*" \
"backtrace from inner in nodebug.exp"
# Or if that doesn't work, at least hope for the external symbols
--
2.5.5