public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* Printing a 2D array in a C program
@ 2016-03-04 14:27 Neven Sajko
  2016-03-04 14:42 ` Jan Kratochvil
  0 siblings, 1 reply; 12+ messages in thread
From: Neven Sajko @ 2016-03-04 14:27 UTC (permalink / raw)
  To: gdb

Hello,
I have a newbie question.

GDB version is 7.11, compiler is gcc 5.3.0 (-std=gnu90).

In my C program there is a square matrix implemented as an array
of arrays, which prints nicely in GDB with `info locals`.
But how can that nice output be accomplished if you are not in
the function in which the array was declared, but just have it
passed as a function parameter.

        Thank you,
        Neven

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

* Re: Printing a 2D array in a C program
  2016-03-04 14:27 Printing a 2D array in a C program Neven Sajko
@ 2016-03-04 14:42 ` Jan Kratochvil
  2016-03-04 16:15   ` Neven Sajko
  0 siblings, 1 reply; 12+ messages in thread
From: Jan Kratochvil @ 2016-03-04 14:42 UTC (permalink / raw)
  To: Neven Sajko; +Cc: gdb

On Fri, 04 Mar 2016 15:27:14 +0100, Neven Sajko wrote:
> In my C program there is a square matrix implemented as an array
> of arrays, which prints nicely in GDB with `info locals`.

I do not understand how that can happen.
You should always provide sample code / example.


> But how can that nice output be accomplished if you are not in
> the function in which the array was declared, but just have it
> passed as a function parameter.

If it is a pointer (as you say C, not C++ reference) you should be able to:
	(gdb) print *thatpointername
Then GDB should IMO print it the same as a local variable is printed.


Printing of C++ vectors of vectors (which is BTW wrong data structure for a 2D
matrix anyway) as a matrix was implemented by Chris Moller as a Python Pretty
printer in some versions of Fedora GDB but it was later discontinued.  The
initial implementation was:
	http://pkgs.fedoraproject.org/cgit/rpms/gdb.git/commit/?id=6068e6305ed7d05b4a919c28aa5bcb737e1f163b
(gdb) p test2
$2 =
  {
    {0      1    }
    {2      3    }
    {4      5    }
 }



Jan

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

* Re: Printing a 2D array in a C program
  2016-03-04 14:42 ` Jan Kratochvil
@ 2016-03-04 16:15   ` Neven Sajko
  2016-03-04 17:49     ` Jan Kratochvil
  2016-03-04 18:34     ` Andreas Schwab
  0 siblings, 2 replies; 12+ messages in thread
From: Neven Sajko @ 2016-03-04 16:15 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: gdb

On 4 March 2016 at 15:42, Jan Kratochvil <jan.kratochvil@redhat.com> wrote:
> On Fri, 04 Mar 2016 15:27:14 +0100, Neven Sajko wrote:
>> In my C program there is a square matrix implemented as an array
>> of arrays, which prints nicely in GDB with `info locals`.
>
> I do not understand how that can happen.
> You should always provide sample code / example.
>
>
>> But how can that nice output be accomplished if you are not in
>> the function in which the array was declared, but just have it
>> passed as a function parameter.
>
> If it is a pointer (as you say C, not C++ reference) you should be able to:
>         (gdb) print *thatpointername
> Then GDB should IMO print it the same as a local variable is printed.
>
>
> Printing of C++ vectors of vectors (which is BTW wrong data structure for a 2D
> matrix anyway) as a matrix was implemented by Chris Moller as a Python Pretty
> printer in some versions of Fedora GDB but it was later discontinued.  The
> initial implementation was:
>         http://pkgs.fedoraproject.org/cgit/rpms/gdb.git/commit/?id=6068e6305ed7d05b4a919c28aa5bcb737e1f163b
> (gdb) p test2
> $2 =
>   {
>     {0      1    }
>     {2      3    }
>     {4      5    }
>  }
>
>
>
> Jan
 Thanks for your answer, Jan.

In my question I asked about C (not C++), I even mentioned the
gcc -std=gnu90 option.

My code is thus:

enum {
        sz = 17
};

void p(int m[sz][sz], int n) {
        int i;
        for (i=1; i<n; i++) {
                int j;
                for (j=i-1; 0<=j; j--) {
                        m[i][j] = abs(3*m[i-1][j] +2*m[i][j+1]) % 9340506;
                }
        }
}

void f(int n) {
        int m[sz][sz];

        g(m, n);

        p(m, n);

        r(m, n);
}


So, when I am in f, `info locals` prints it like {{a11, ...,
a1n}, ..., {an1, ..., ann}}.
But in p `print *m` just gets me {a11, ..., a1n}.

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

* Re: Printing a 2D array in a C program
  2016-03-04 16:15   ` Neven Sajko
@ 2016-03-04 17:49     ` Jan Kratochvil
  2016-03-04 18:24       ` Pedro Alves
  2016-03-04 18:34     ` Andreas Schwab
  1 sibling, 1 reply; 12+ messages in thread
From: Jan Kratochvil @ 2016-03-04 17:49 UTC (permalink / raw)
  To: Neven Sajko; +Cc: gdb

[-- Attachment #1: Type: text/plain, Size: 2173 bytes --]

On Fri, 04 Mar 2016 17:15:26 +0100, Neven Sajko wrote:
> But in p `print *m` just gets me {a11, ..., a1n}.

I think it is a bug in GCC.  I haven't found it in GCC Bugzilla.
I haven't filed it anywhere yet.  All these compilers fail the same way:
	gcc-5.3.1-2.fc23.x86_64
	gcc-6.0.0-0.13.fc25.x86_64
	gcc (GCC) 6.0.0 20160213 (experimental)
	clang-3.7.0-4.fc23.x86_64
	clang-3.8.0-0.3.fc25.x86_64

The .s diff is for: gcc -o matrix.s matrix.c -Wall -g -S -dA


Jan


The array variable:
(gdb) s
f (n=1) at matrix2.c:22
(gdb) ptype m
type = int [17][17]
(gdb) p m
$1 = {{-134241616, 32767, -134252848, 32767, -140382932, 32767, 2224, 0, -134252032, 32767, -136422399, 32767, 2224, 0, -140329216,
    32767, -134252112}, {32767, -134252032, 32767, -11384, 32767, -11388, 32767, 1, 0, -136460380, 32767, -140329216, 32767,
[...]
    -10400, 32767, -134225592, 32767, 0, 0, 1, 0, 4195965, 0, 4195328, 0, 0, 0, 4195888}}

The bug with the parameter:
(gdb) s
p (m=0x7fffffffd2a0, n=1) at matrix2.c:9
(gdb) ptype m
type = int (*)[17]
(gdb) p m
$2 = (int (*)[17]) 0x7fffffffd2a0
(gdb) p *m
$3 = {-134241616, 32767, -134252848, 32767, -140382932, 32767, 2224, 0, -134252032, 32767, -136422399, 32767, 2224, 0, -140329216,
  32767, -134252112}

Workaroundable by:
(gdb) p *(int[17][17] *)m
$4 = {{-134241616, 32767, -134252848, 32767, -140382932, 32767, 2224, 0, -134252032, 32767, -136422399, 32767, 2224, 0, -140329216,
    32767, -134252112}, {32767, -134252032, 32767, -11384, 32767, -11388, 32767, 1, 0, -136460380, 32767, -140329216, 32767,
[...]
    -10400, 32767, -134225592, 32767, 0, 0, 1, 0, 4195965, 0, 4195328, 0, 0, 0, 4195888}}

After fixed DWARF without the workaround:
(gdb) s
p (m=0x7fffffffd2a0, n=1) at matrix2.c:9
(gdb) ptype m
type = int (*)[17][17]
(gdb) p m
$1 = (int (*)[17][17]) 0x7fffffffd2a0
(gdb) p *m
$2 = {{-134241616, 32767, -134252848, 32767, -140382932, 32767, 2224, 0, -134252032, 32767, -136422399, 32767, 2224, 0, -140329216,
    32767, -134252112}, {32767, -134252032, 32767, -11384, 32767, -11388, 32767, 1, 0, -136460380, 32767, -140329216, 32767,
[...]
    -10400, 32767, -134225592, 32767, 0, 0, 1, 0, 4195965, 0, 4195328, 0, 0, 0, 4195888}}

[-- Attachment #2: Fix of the DWARF --]
[-- Type: text/plain, Size: 403 bytes --]

--- matrix2.s-orig	2016-03-04 18:30:45.846203946 +0100
+++ matrix2.s	2016-03-04 18:33:33.912409159 +0100
@@ -329,7 +329,7 @@ main:
 	.byte	0	# end of children of DIE 0xf1
 	.uleb128 0xc	# (DIE (0x101) DW_TAG_pointer_type)
 	.byte	0x8	# DW_AT_byte_size
-	.long	0xf1	# DW_AT_type
+	.long	0x13d	# DW_AT_type
 	.uleb128 0xd	# (DIE (0x107) DW_TAG_subprogram)
 			# DW_AT_external
 	.ascii "f\0"	# DW_AT_name

[-- Attachment #3: Effect of the DWARF fix --]
[-- Type: text/plain, Size: 1488 bytes --]

  <2><ae>: Abbrev Number: 7 (DW_TAG_formal_parameter)
     <af>   DW_AT_name        : m
     <b1>   DW_AT_decl_file   : 1
     <b2>   DW_AT_decl_line   : 7
     <b3>   DW_AT_type        : <0x101>
     <b7>   DW_AT_location    : 2 byte block: 91 58 	(DW_OP_fbreg: -40)
  <1><f1>: Abbrev Number: 10 (DW_TAG_array_type)
     <f2>   DW_AT_type        : <0x34>
     <f6>   DW_AT_sibling     : <0x101>
  <2><fa>: Abbrev Number: 11 (DW_TAG_subrange_type)
     <fb>   DW_AT_type        : <0x65>
     <ff>   DW_AT_upper_bound : 16
  <2><100>: Abbrev Number: 0
  <1><101>: Abbrev Number: 12 (DW_TAG_pointer_type)
     <102>   DW_AT_byte_size   : 8
-    <103>   DW_AT_type        : <0xf1>
+    <103>   DW_AT_type        : <0x13d>
  <1><107>: Abbrev Number: 13 (DW_TAG_subprogram)
  <2><12f>: Abbrev Number: 8 (DW_TAG_variable)
     <130>   DW_AT_name        : m
     <132>   DW_AT_decl_file   : 1
     <133>   DW_AT_decl_line   : 18
     <134>   DW_AT_type        : <0x13d>
     <138>   DW_AT_location    : 3 byte block: 91 e0 76 	(DW_OP_fbreg: -1184)
  <2><13c>: Abbrev Number: 0
  <1><13d>: Abbrev Number: 10 (DW_TAG_array_type)
     <13e>   DW_AT_type        : <0x34>
     <142>   DW_AT_sibling     : <0x153>
  <2><146>: Abbrev Number: 11 (DW_TAG_subrange_type)
     <147>   DW_AT_type        : <0x65>
     <14b>   DW_AT_upper_bound : 16
  <2><14c>: Abbrev Number: 11 (DW_TAG_subrange_type)
     <14d>   DW_AT_type        : <0x65>
     <151>   DW_AT_upper_bound : 16
  <2><152>: Abbrev Number: 0

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

* Re: Printing a 2D array in a C program
  2016-03-04 17:49     ` Jan Kratochvil
@ 2016-03-04 18:24       ` Pedro Alves
  2016-03-04 18:59         ` Jan Kratochvil
  0 siblings, 1 reply; 12+ messages in thread
From: Pedro Alves @ 2016-03-04 18:24 UTC (permalink / raw)
  To: Jan Kratochvil, Neven Sajko; +Cc: gdb

On 03/04/2016 05:48 PM, Jan Kratochvil wrote:
> The bug with the parameter:
> (gdb) s
> p (m=0x7fffffffd2a0, n=1) at matrix2.c:9
> (gdb) ptype m
> type = int (*)[17]
> (gdb) p m
> $2 = (int (*)[17]) 0x7fffffffd2a0
> (gdb) p *m
> $3 = {-134241616, 32767, -134252848, 32767, -140382932, 32767, 2224, 0, -134252032, 32767, -136422399, 32767, 2224, 0, -140329216,
>    32767, -134252112}

It's a C gotcha, but I don't think it's a bug.  Essentially, a parameter
declared as an array is really treated as a pointer parameter.

From http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf:

"
6.7.5.3 Function declarators (including prototypes)
Constraints
(...)

7

A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to type’’ (...)
"

So the DWARF describes the type as really what is is.  See:

~~~~~~~~~~~~~~~~
$ cat array-param.c
#include <stdlib.h>
#include <stdio.h>

enum
{
  sz = 17
};

void
p (int m[sz][sz])
{
  printf ("m: sizeof m = %d\n", (int) sizeof (m));
}

void
f (void)
{
  int m[sz][sz];

  printf ("f: sizeof m = %d\n", (int) sizeof (m));

  p (m);
}

int
main ()
{
  f ();
  return 0;
}

$ gcc -v
gcc version 6.0.0 20160301 (experimental) (GCC)
$ gcc array-param.c -o array-param -Wall -Wextra -O2
array-param.c: In function ‘p’:
array-param.c:12:46: warning: ‘sizeof’ on array function parameter ‘m’ will return size of ‘int (*)[17]’ [-Wsizeof-array-argument]
   printf ("m: sizeof m = %d\n", (int) sizeof (m));
                                              ^
array-param.c:10:8: note: declared here
 p (int m[sz][sz])
        ^
$ ./array-param 
f: sizeof m = 1156
m: sizeof m = 8
~~~~~~~~~~~~~~~~

Thanks,
Pedro Alves

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

* Re: Printing a 2D array in a C program
  2016-03-04 16:15   ` Neven Sajko
  2016-03-04 17:49     ` Jan Kratochvil
@ 2016-03-04 18:34     ` Andreas Schwab
  2016-03-04 21:48       ` Neven Sajko
  1 sibling, 1 reply; 12+ messages in thread
From: Andreas Schwab @ 2016-03-04 18:34 UTC (permalink / raw)
  To: Neven Sajko; +Cc: Jan Kratochvil, gdb

Neven Sajko <nsajko@gmail.com> writes:

> In my question I asked about C (not C++), I even mentioned the
> gcc -std=gnu90 option.
>
> My code is thus:
>
> enum {
>         sz = 17
> };
>
> void p(int m[sz][sz], int n) {
>         int i;
>         for (i=1; i<n; i++) {
>                 int j;
>                 for (j=i-1; 0<=j; j--) {
>                         m[i][j] = abs(3*m[i-1][j] +2*m[i][j+1]) % 9340506;
>                 }
>         }
> }
>
> void f(int n) {
>         int m[sz][sz];
>
>         g(m, n);
>
>         p(m, n);
>
>         r(m, n);
> }
>
>
> So, when I am in f, `info locals` prints it like {{a11, ...,
> a1n}, ..., {an1, ..., ann}}.
> But in p `print *m` just gets me {a11, ..., a1n}.

This is correct, *m has the type int[sz].  If you want to print all
elements pointed to by m you need to use `print *m@sz'.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

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

* Re: Printing a 2D array in a C program
  2016-03-04 18:24       ` Pedro Alves
@ 2016-03-04 18:59         ` Jan Kratochvil
  2016-03-04 19:16           ` Pedro Alves
  0 siblings, 1 reply; 12+ messages in thread
From: Jan Kratochvil @ 2016-03-04 18:59 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Neven Sajko, gdb

On Fri, 04 Mar 2016 19:24:19 +0100, Pedro Alves wrote:
> It's a C gotcha, but I don't think it's a bug.  Essentially, a parameter
> declared as an array is really treated as a pointer parameter.

I did not look it up but I expected the standard probably says something like
that, this is also why clang matches the gcc behavior.  But GDB could try to
be more helpful displaying the data.  For example DWARF could have the pointer
there at its type for sizeof and similar but additionally there could be some
new GNU attribute for printing the data.

Just I did not file it as I think C++ is more appropriate for such (or all)
cases where it already just works.


Jan

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

* Re: Printing a 2D array in a C program
  2016-03-04 18:59         ` Jan Kratochvil
@ 2016-03-04 19:16           ` Pedro Alves
  0 siblings, 0 replies; 12+ messages in thread
From: Pedro Alves @ 2016-03-04 19:16 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Neven Sajko, gdb

On 03/04/2016 06:59 PM, Jan Kratochvil wrote:
> On Fri, 04 Mar 2016 19:24:19 +0100, Pedro Alves wrote:
>> It's a C gotcha, but I don't think it's a bug.  Essentially, a parameter
>> declared as an array is really treated as a pointer parameter.
> 
> I did not look it up but I expected the standard probably says something like
> that, 

It's in the url/paste I showed.  C99, 6.7.5.3, point 7.

> For example DWARF could have the pointer
> there at its type for sizeof and similar but additionally there could be some
> new GNU attribute for printing the data.

Yeah, might be a good idea.

Thanks,
Pedro Alves

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

* Re: Printing a 2D array in a C program
  2016-03-04 18:34     ` Andreas Schwab
@ 2016-03-04 21:48       ` Neven Sajko
  2016-03-04 22:16         ` Andreas Schwab
  0 siblings, 1 reply; 12+ messages in thread
From: Neven Sajko @ 2016-03-04 21:48 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Jan Kratochvil, gdb

On 4 March 2016 at 19:34, Andreas Schwab <schwab@linux-m68k.org> wrote:
> This is correct, *m has the type int[sz].  If you want to print all
> elements pointed to by m you need to use `print *m@sz'.
>
> Andreas.
>
> --
> Andreas Schwab, schwab@linux-m68k.org
> GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
> "And now for something completely different."

Thank you :)

But it seems `print *m@(int)sz' is needed because enum aren't integral types?

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

* Re: Printing a 2D array in a C program
  2016-03-04 21:48       ` Neven Sajko
@ 2016-03-04 22:16         ` Andreas Schwab
  2016-03-05  0:59           ` Neven Sajko
  0 siblings, 1 reply; 12+ messages in thread
From: Andreas Schwab @ 2016-03-04 22:16 UTC (permalink / raw)
  To: Neven Sajko; +Cc: Jan Kratochvil, gdb

Neven Sajko <nsajko@gmail.com> writes:

> But it seems `print *m@(int)sz' is needed because enum aren't integral types?

An enum constant has type int.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

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

* Re: Printing a 2D array in a C program
  2016-03-04 22:16         ` Andreas Schwab
@ 2016-03-05  0:59           ` Neven Sajko
  2016-03-05  8:23             ` Andreas Schwab
  0 siblings, 1 reply; 12+ messages in thread
From: Neven Sajko @ 2016-03-05  0:59 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Jan Kratochvil, gdb

On 4 March 2016 at 23:16, Andreas Schwab <schwab@linux-m68k.org> wrote:
> Neven Sajko <nsajko@gmail.com> writes:
>
>> But it seems `print *m@(int)sz' is needed because enum aren't integral types?
>
> An enum constant has type int.
>
> Andreas.
>
> --
> Andreas Schwab, schwab@linux-m68k.org
> GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
> "And now for something completely different."

I know but if I try to do it without the cast, GDB complains
that the right operand to the artificial array operator is not
an integral type.

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

* Re: Printing a 2D array in a C program
  2016-03-05  0:59           ` Neven Sajko
@ 2016-03-05  8:23             ` Andreas Schwab
  0 siblings, 0 replies; 12+ messages in thread
From: Andreas Schwab @ 2016-03-05  8:23 UTC (permalink / raw)
  To: Neven Sajko; +Cc: Jan Kratochvil, gdb

Neven Sajko <nsajko@gmail.com> writes:

> I know but if I try to do it without the cast, GDB complains
> that the right operand to the artificial array operator is not
> an integral type.

That looks like a bug.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

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

end of thread, other threads:[~2016-03-05  8:23 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-04 14:27 Printing a 2D array in a C program Neven Sajko
2016-03-04 14:42 ` Jan Kratochvil
2016-03-04 16:15   ` Neven Sajko
2016-03-04 17:49     ` Jan Kratochvil
2016-03-04 18:24       ` Pedro Alves
2016-03-04 18:59         ` Jan Kratochvil
2016-03-04 19:16           ` Pedro Alves
2016-03-04 18:34     ` Andreas Schwab
2016-03-04 21:48       ` Neven Sajko
2016-03-04 22:16         ` Andreas Schwab
2016-03-05  0:59           ` Neven Sajko
2016-03-05  8:23             ` Andreas Schwab

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).