Someone is trying to debug ATS code using DWARF?

128 views
Skip to first unread message

Kiwamu Okabe

unread,
Mar 7, 2015, 4:45:08 AM3/7/15
to ats-lang-users, ats-lang-users
Hi all,

OCaml is able to debug compiled binary using gdb
that reads DWARF in the binary.
Then, I hope ATS2 compiler create binary execution with DWARF.

Someone is trying to debug ATS code using DWARF?

Best regards,
--
Kiwamu Okabe at METASEPI DESIGN

Shea Levy

unread,
Mar 7, 2015, 8:21:57 AM3/7/15
to ats-lan...@googlegroups.com, ats-lang-users
My guess is that the only debugging available in the final binary is what’s put there by the C compiler, not the ats compiler.
> --
> You received this message because you are subscribed to the Google Groups "ats-lang-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to ats-lang-user...@googlegroups.com.
> To post to this group, send email to ats-lan...@googlegroups.com.
> Visit this group at http://groups.google.com/group/ats-lang-users.
> To view this discussion on the web visit https://groups.google.com/d/msgid/ats-lang-users/CAEvX6dmU6A1cC_nmgyv7m5j50gwA8Chf-aR7hPf%2BNB3cnHRdZw%40mail.gmail.com.

Kiwamu Okabe

unread,
Mar 7, 2015, 8:27:22 AM3/7/15
to ats-lang-users, ats-lang-users
Hi Shea,

On Sat, Mar 7, 2015 at 10:21 PM, Shea Levy <sh...@shealevy.com> wrote:
> My guess is that the only debugging available in the final binary is what’s put there by the C compiler, not the ats compiler.

Yes, right.

My idea is replacing the DWARF of C compiler with a DWARF of ATS.
Is it impossible?

Thank's,

gmhwxi

unread,
Mar 7, 2015, 10:26:41 AM3/7/15
to ats-lan...@googlegroups.com, ats-lan...@lists.sourceforge.net, kiw...@debian.or.jp
I have no experience with DWARF.

The C code generated from ATS source contains a lot of location
information on the source code. If you pass --gline to patsopt, then
you can get more.

The biggest hurdle as I see it lies in the handling of templates in ATS.
Due to template instantiation, it can currently be very difficult to know
how exactly the C code gets generated. Regardless using DWARF or not,
this is something that needs to be addressed.

john skaller

unread,
Mar 7, 2015, 7:08:18 PM3/7/15
to gmhwxi, ats-lang-users

On 08/03/2015, at 2:26 AM, gmhwxi wrote:

> I have no experience with DWARF.
>
> The C code generated from ATS source contains a lot of location
> information on the source code. If you pass --gline to patsopt, then
> you can get more.
>
> The biggest hurdle as I see it lies in the handling of templates in ATS.
> Due to template instantiation, it can currently be very difficult to know
> how exactly the C code gets generated. Regardless using DWARF or not,
> this is something that needs to be addressed.

Some debugging ideas:

1. With Felix, I can "just" read the generated C++ code.
Others can't but I can, because of the styalised symbol naming
and comments.

My tool allows me to modify the C++ code with printf() statements
and rebuild without re-running the translator (but preserving all
the linkage instructions etc).

2. ATS should have a way to insert debugging into the ATS
code by the ATS programmer. This includes something like

nop "string"

which does nothing but emits an instruction the compiler THINKS
does something important. A variant

debug "string";

is the same but can turn into a printf (which also tells the location
on both the ATS and C code).

3. A way to automatically instrument functions: add the
debug strings to the start of every function. Slows stuff down
a bit.

4. My current tracing idea is to turn special logging/debugging
commands like those above into writes on a UDP socket.
This allows to connect a real time monitoring tool. That in turn
could be connected to a TCP socket running HTTP so you could
get some idea what's happening using a web browser.

None of these ideas are complete solutions. ATS like Felix
generates code in C/C++ which can crash due to corruption
from invalid pointers. Personally I find reading the code
and logical reasoning far better than debuggers .. debuggers
are a last resort because they really can't help much with
corruption. Valgrind is similar, it tries. I find gdb and valgrind either
find your bug in 10 seconds flat or they're useless.

--
john skaller
ska...@users.sourceforge.net
http://felix-lang.org



Kiwamu Okabe

unread,
Mar 8, 2015, 7:27:56 AM3/8/15
to ats-lang-users, ats-lang-users
Hi Hongwei,

On Sun, Mar 8, 2015 at 12:26 AM, gmhwxi <gmh...@gmail.com> wrote:
> I have no experience with DWARF.

Of course, me too.

> The C code generated from ATS source contains a lot of location
> information on the source code. If you pass --gline to patsopt, then
> you can get more.

Thank's. I know --gline option on your comment.

> The biggest hurdle as I see it lies in the handling of templates in ATS.
> Due to template instantiation, it can currently be very difficult to know
> how exactly the C code gets generated. Regardless using DWARF or not,
> this is something that needs to be addressed.

Using ATS template causes GDB should make break-point for some
addresses at same time.


Totally, I'm happy because I understand DWARF support of ATS compiler
as virgin snow.

Kiwamu Okabe

unread,
Mar 8, 2015, 8:47:13 AM3/8/15
to ats-lang-users
Hi John,

On Sun, Mar 8, 2015 at 9:06 AM, john skaller
<ska...@users.sourceforge.net> wrote:
> Some debugging ideas:
>
> 1. With Felix, I can "just" read the generated C++ code.
> Others can't but I can, because of the styalised symbol naming
> and comments.
>
> My tool allows me to modify the C++ code with printf() statements
> and rebuild without re-running the translator (but preserving all
> the linkage instructions etc).

Umm... However, symbols generated by ATS2 compiler are not
human readable. Should I write de-mangle viewer for the symbols?

> 2. ATS should have a way to insert debugging into the ATS
> code by the ATS programmer. This includes something like
>
> nop "string"
>
> which does nothing but emits an instruction the compiler THINKS
> does something important. A variant
>
> debug "string";
>
> is the same but can turn into a printf (which also tells the location
> on both the ATS and C code).

I think $extfcall is useful for this situation.

> 4. My current tracing idea is to turn special logging/debugging
> commands like those above into writes on a UDP socket.
> This allows to connect a real time monitoring tool. That in turn
> could be connected to a TCP socket running HTTP so you could
> get some idea what's happening using a web browser.

Running log is a good idea, and GHC also use it.
However, I would like to use it on the program running on bare metal hardware.
Kernel such like Linux should run on the bare metal hardware.

> None of these ideas are complete solutions. ATS like Felix
> generates code in C/C++ which can crash due to corruption
> from invalid pointers. Personally I find reading the code
> and logical reasoning far better than debuggers .. debuggers
> are a last resort because they really can't help much with
> corruption. Valgrind is similar, it tries. I find gdb and valgrind either
> find your bug in 10 seconds flat or they're useless.

Yes right.

However, kernel programming sometimes crashes by reason of hardware issue.
We can't debug it logically, need some method of run-time debug.

Kiwamu Okabe

unread,
May 27, 2019, 6:19:01 AM5/27/19
to ats-lang-users
Dear all.

On Sat, Mar 7, 2015 at 6:44 PM Kiwamu Okabe <kiw...@debian.or.jp> wrote:
> Someone is trying to debug ATS code using DWARF?

Fortunately, I found the following simple method, while learning Vala language:

https://gist.github.com/master-q/b8167531a5a0679b9a830ed12a75619f

```
$ gcc -g -I /home/kiwamu/src/ATS-Postiats/ccomp/runtime/ -I
/home/kiwamu/src/ATS-Postiats/ main_dats.c
$ gdb a.out
(gdb) b main.dats:atspre_g0int_add_int
Breakpoint 1 at 0x120a: file
/home/kiwamu/src/ATS-Postiats/prelude/CATS/integer.cats, line 157.
(gdb) run
Starting program: /home/kiwamu/src/idiomaticca/regress/noinc/arithmetic_op/a.out

Breakpoint 1, atspre_g0int_add_int (x1=1, x2=2) at
/home/kiwamu/src/ATS-Postiats/prelude/CATS/integer.cats:157
157 (atstype_int x1, atstype_int x2) { return (x1 + x2) ; }
(gdb) bt
#0 atspre_g0int_add_int (x1=1, x2=2) at
/home/kiwamu/src/ATS-Postiats/prelude/CATS/integer.cats:157
#1 0x000055555555529c in mainats_1_void () at main.dats:4
#2 0x0000555555555635 in main (argc=1, argv=0x7fffffffd5d8,
envp=0x7fffffffd5e8) at main.dats:3
(gdb) l
152 (atstype_int x) { return (x / 2) ; }
153 // end of [atspre_g0int_half_int]
154 ATSinline()
155 atstype_int
156 atspre_g0int_add_int
157 (atstype_int x1, atstype_int x2) { return (x1 + x2) ; }
158 // end of [atspre_g0int_add_int]
159 ATSinline()
160 atstype_int
161 atspre_g0int_sub_int
(gdb) up
#1 0x000055555555529c in mainats_1_void () at main.dats:4
4 1 + 2 - 3 * 4 / 4
(gdb) l
1 #include "share/atspre_staload.hats"
2
3 implement main () =
4 1 + 2 - 3 * 4 / 4
5
```

I'll try to write some patch to inject such `#line` code onto output of patsopt.

I'm so happy, if you advice me some comment on ATS compiler internal.

Kiwamu Okabe

unread,
May 27, 2019, 7:43:43 AM5/27/19
to ats-lang-users
Dear Hongwei,

On Mon, May 27, 2019 at 7:18 PM Kiwamu Okabe <kiw...@debian.or.jp> wrote:
> Fortunately, I found the following simple method, while learning Vala language:
>
> https://gist.github.com/master-q/b8167531a5a0679b9a830ed12a75619f
--snip--
> I'll try to write some patch to inject such `#line` code onto output of patsopt.

I think you have already implement it on `--gline` option.
May I use it to debug ELF file compiled by ATS2?

```
$ cp /home/kiwamu/src/ATS-Postiats/doc/BOOK/INT2PROGINATS/CODE/CHAP_DATAVTYPE/rbtree.dats
./
$ patsopt --gline -o rbtree_dats.c -d rbtree.dats
$ grep "^#line" rbtree_dats.c | wc -l
1924
$ gcc -g -DATS_MEMALLOC_LIBC -I
/home/kiwamu/src/ATS-Postiats/ccomp/runtime/ -I
/home/kiwamu/src/ATS-Postiats/ rbtree_dats.c
$ gdb a.out
(gdb) b 235
Breakpoint 1 at 0x15ee: /home/kiwamu/tmp/ats/rbtree/rbtree.dats:235.
(10 locations)
(gdb) run
Starting program: /home/kiwamu/tmp/ats/rbtree/a.out

Breakpoint 1, _057_home_057_kiwamu_057_tmp_057_ats_057_rbtree_057_rbtree_056_dats__rbtree_insert__2__1
(arg0=0x0, arg1=0x7fffffffd4e4, arg2=0x0) at
/home/kiwamu/tmp/ats/rbtree/rbtree.dats:235
235 val t = ins (t, x0)
(gdb) bt
#0 _057_home_057_kiwamu_057_tmp_057_ats_057_rbtree_057_rbtree_056_dats__rbtree_insert__2__1
(arg0=0x0, arg1=0x7fffffffd4e4, arg2=0x0) at
/home/kiwamu/tmp/ats/rbtree/rbtree.dats:235
#1 0x000055555555540b in mainats_0_void () at
/home/kiwamu/tmp/ats/rbtree/rbtree.dats:311
#2 0x000055555555940b in main (argc=1, argv=0x7fffffffd668,
envp=0x7fffffffd678) at /home/kiwamu/tmp/ats/rbtree/rbtree.dats:322
(gdb) l
230 end else (fold@{a}{..}{..}{0} (t); t)
231 end // end of [cons]
232 | ~nil () => cons{a}{..}{..}{0}(R, nil, x0, nil)
233 ) (* end of [ins] *)
234 //
235 val t = ins (t, x0)
236 //
237 in
238 //
239 case+ t of @cons(c as R, _, _, _) => (c := B; fold@ (t); t) | _ =>> t
```

Hongwei Xi

unread,
May 27, 2019, 10:33:19 AM5/27/19
to ats-lan...@googlegroups.com
Yes, I think you can use the gline flag in that way.

If your ATS2 program makes extensive use of templates, the traditional way of debugging
may not work very well. Unfortunately, I don't know a better way :(

--Hongwei

--
You received this message because you are subscribed to the Google Groups "ats-lang-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ats-lang-user...@googlegroups.com.
To post to this group, send email to ats-lan...@googlegroups.com.

Kiwamu Okabe

unread,
May 28, 2019, 1:15:49 AM5/28/19
to ats-lang-users
Dear Hongwei,

On Mon, May 27, 2019 at 11:33 PM Hongwei Xi <gmh...@gmail.com> wrote:
> Yes, I think you can use the gline flag in that way.

It's great news for me.

> If your ATS2 program makes extensive use of templates, the traditional way of debugging
> may not work very well. Unfortunately, I don't know a better way :(

Yes, templates make bad impact for break points.
Following means that there are 20 `#line` directives, but gdb only
found 10 of them.
Do you know how to find all of the multiple breakpoints?

```
$ gcc -E -DATS_MEMALLOC_LIBC -I
/home/kiwamu/src/ATS-Postiats/ccomp/runtime/ -I
/home/kiwamu/src/ATS-Postiats/ rbtree_dats.c > rbtree_dats_E.c
$ grep 235 rbtree_dats_E.c | wc -l
20
$ gcc -g rbtree_dats_E.c
$ gdb a.out
(gdb) b 235
Breakpoint 1 at 0x15ee: /home/kiwamu/tmp/ats/rbtree/rbtree.dats:235.
(10 locations)
```

Carefully reading C code generated by patsopt, there are 10 instances
for `rbtree_insert<T>`.
And one of them can break as following:

```
(gdb) b _057_home_057_kiwamu_057_tmp_057_ats_057_rbtree_057_rbtree_056_dats__rbtree_insert__2__1
Breakpoint 1 at 0x15ee: file /home/kiwamu/tmp/ats/rbtree/rbtree.dats, line 235.
(gdb) run
Starting program: /home/kiwamu/tmp/ats/rbtree/a.out

Breakpoint 1, _057_home_057_kiwamu_057_tmp_057_ats_057_rbtree_057_rbtree_056_dats__rbtree_insert__2__1
(arg0=0x0, arg1=0x7fffffffd4a4, arg2=0x0) at
/home/kiwamu/tmp/ats/rbtree/rbtree.dats:235
235 val t = ins (t, x0)
(gdb) bt
#0 _057_home_057_kiwamu_057_tmp_057_ats_057_rbtree_057_rbtree_056_dats__rbtree_insert__2__1
(arg0=0x0, arg1=0x7fffffffd4a4, arg2=0x0) at
/home/kiwamu/tmp/ats/rbtree/rbtree.dats:235
#1 0x000055555555540b in mainats_0_void () at
/home/kiwamu/tmp/ats/rbtree/rbtree.dats:311
#2 0x000055555555940b in main (argc=1, argv=0x7fffffffd628,
envp=0x7fffffffd638) at /home/kiwamu/tmp/ats/rbtree/rbtree.dats:314
```

Do you have some pointer how to inject name mangling for breaking at
following template instances?

```
casper$ grep global: rbtree_dats.c | sort | uniq
global:
global: cmp$4777(1)(HSEfun(FUN; HSErefarg(1;
HSEs2exp(S2Eapp(S2Ecst(g0int_t0ype); S2Eextkind(atstype_int)))),
HSErefarg(1; HSEs2exp(S2Eapp(S2Ecst(g0int_t0ype);
S2Eextkind(atstype_int)))); HSEapp(HSEcst(atstkind_t0ype);
HSEs2exp(S2Eextkind(atstype_int)))))
global: cmp$4777(1)(HSEfun(FUN; HSErefarg(1; HSEtyvar(a(8564))),
HSErefarg(1; HSEtyvar(a(8564))); HSEapp(HSEcst(atstkind_t0ype);
HSEs2exp(S2Eextkind(atstype_int)))))
global: compare$7$0(level=1)
global: compare$7$10(level=3)
global: compare$7$1(level=3)
global: compare$7$2(level=3)
global: compare$7$3(level=3)
global: compare$7$4(level=3)
global: compare$7$5(level=3)
global: compare$7$6(level=3)
global: compare$7$7(level=3)
global: compare$7$8(level=3)
global: compare$7$9(level=3)
global: eq_g1int_int$16$0(level=0)
global: eq_g1int_int$16$10(level=3)
global: eq_g1int_int$16$11(level=3)
global: eq_g1int_int$16$12(level=3)
global: eq_g1int_int$16$13(level=3)
global: eq_g1int_int$16$14(level=3)
global: eq_g1int_int$16$15(level=3)
global: eq_g1int_int$16$16(level=3)
global: eq_g1int_int$16$17(level=3)
global: eq_g1int_int$16$18(level=3)
global: eq_g1int_int$16$19(level=3)
global: eq_g1int_int$16$1(level=3)
global: eq_g1int_int$16$20(level=3)
global: eq_g1int_int$16$21(level=2)
global: eq_g1int_int$16$2(level=3)
global: eq_g1int_int$16$3(level=3)
global: eq_g1int_int$16$4(level=3)
global: eq_g1int_int$16$5(level=3)
global: eq_g1int_int$16$6(level=3)
global: eq_g1int_int$16$7(level=3)
global: eq_g1int_int$16$8(level=3)
global: eq_g1int_int$16$9(level=3)
global: fprint_val$109$0(level=0)
global: fprint_val$109$1(level=2)
global: gt_g0int_int$21$0(level=0)
global: gt_g0int_int$21$10(level=3)
global: gt_g0int_int$21$1(level=3)
global: gt_g0int_int$21$2(level=3)
global: gt_g0int_int$21$3(level=3)
global: gt_g0int_int$21$4(level=3)
global: gt_g0int_int$21$5(level=3)
global: gt_g0int_int$21$6(level=3)
global: gt_g0int_int$21$7(level=3)
global: gt_g0int_int$21$8(level=3)
global: gt_g0int_int$21$9(level=3)
global: ins_3$0(level=1)
global: ins_3$10(level=2)
global: ins_3$1(level=2)
global: ins_3$2(level=2)
global: ins_3$3(level=2)
global: ins_3$4(level=2)
global: ins_3$5(level=2)
global: ins_3$6(level=2)
global: ins_3$7(level=2)
global: ins_3$8(level=2)
global: ins_3$9(level=2)
global: insfix_l_0$0(level=0)
global: insfix_l_0$10(level=3)
global: insfix_l_0$1(level=3)
global: insfix_l_0$2(level=3)
global: insfix_l_0$3(level=3)
global: insfix_l_0$4(level=3)
global: insfix_l_0$5(level=3)
global: insfix_l_0$6(level=3)
global: insfix_l_0$7(level=3)
global: insfix_l_0$8(level=3)
global: insfix_l_0$9(level=3)
global: insfix_r_1$0(level=0)
global: insfix_r_1$10(level=3)
global: insfix_r_1$1(level=3)
global: insfix_r_1$2(level=3)
global: insfix_r_1$3(level=3)
global: insfix_r_1$4(level=3)
global: insfix_r_1$5(level=3)
global: insfix_r_1$6(level=3)
global: insfix_r_1$7(level=3)
global: insfix_r_1$8(level=3)
global: insfix_r_1$9(level=3)
global: lt_g0int_int$12$0(level=0)
global: lt_g0int_int$12$10(level=3)
global: lt_g0int_int$12$1(level=3)
global: lt_g0int_int$12$2(level=3)
global: lt_g0int_int$12$3(level=3)
global: lt_g0int_int$12$4(level=3)
global: lt_g0int_int$12$5(level=3)
global: lt_g0int_int$12$6(level=3)
global: lt_g0int_int$12$7(level=3)
global: lt_g0int_int$12$8(level=3)
global: lt_g0int_int$12$9(level=3)
global: mainats_0_void$6$0(level=0)
global: print_rbtree_5$0(level=0)
global: print_rbtree_5$1(level=1)
global: rbtree_free_4$0(level=0)
global: rbtree_free_4$1(level=1)
global: rbtree_insert$2$0(level=0)
global: rbtree_insert$2$10(level=1)
global: rbtree_insert$2$1(level=1)
global: rbtree_insert$2$2(level=1)
global: rbtree_insert$2$3(level=1)
global: rbtree_insert$2$4(level=1)
global: rbtree_insert$2$5(level=1)
global: rbtree_insert$2$6(level=1)
global: rbtree_insert$2$7(level=1)
global: rbtree_insert$2$8(level=1)
global: rbtree_insert$2$9(level=1)
```

Kiwamu Okabe

unread,
May 28, 2019, 1:22:13 AM5/28/19
to ats-lang-users
Ah! It's useful!!!

```
(gdb) i b
Num Type Disp Enb Address What
1 breakpoint keep y <MULTIPLE>
1.1 y 0x00000000000015ee in
_057_home_057_kiwamu_057_tmp_057_ats_057_rbtree_057_rbtree_056_dats__rbtree_insert__2__1
at /home/kiwamu/tmp/ats/rbtree/rbtree.dats:235
1.2 y 0x0000000000001b97 in
_057_home_057_kiwamu_057_tmp_057_ats_057_rbtree_057_rbtree_056_dats__rbtree_insert__2__2
at /home/kiwamu/tmp/ats/rbtree/rbtree.dats:235
1.3 y 0x0000000000002140 in
_057_home_057_kiwamu_057_tmp_057_ats_057_rbtree_057_rbtree_056_dats__rbtree_insert__2__3
at /home/kiwamu/tmp/ats/rbtree/rbtree.dats:235
1.4 y 0x00000000000026e9 in
_057_home_057_kiwamu_057_tmp_057_ats_057_rbtree_057_rbtree_056_dats__rbtree_insert__2__4
at /home/kiwamu/tmp/ats/rbtree/rbtree.dats:235
1.5 y 0x0000000000002c92 in
_057_home_057_kiwamu_057_tmp_057_ats_057_rbtree_057_rbtree_056_dats__rbtree_insert__2__5
at /home/kiwamu/tmp/ats/rbtree/rbtree.dats:235
1.6 y 0x000000000000323b in
_057_home_057_kiwamu_057_tmp_057_ats_057_rbtree_057_rbtree_056_dats__rbtree_insert__2__6
at /home/kiwamu/tmp/ats/rbtree/rbtree.dats:235
1.7 y 0x00000000000037e4 in
_057_home_057_kiwamu_057_tmp_057_ats_057_rbtree_057_rbtree_056_dats__rbtree_insert__2__7
at /home/kiwamu/tmp/ats/rbtree/rbtree.dats:235
1.8 y 0x0000000000003d8d in
_057_home_057_kiwamu_057_tmp_057_ats_057_rbtree_057_rbtree_056_dats__rbtree_insert__2__8
at /home/kiwamu/tmp/ats/rbtree/rbtree.dats:235
1.9 y 0x0000000000004336 in
_057_home_057_kiwamu_057_tmp_057_ats_057_rbtree_057_rbtree_056_dats__rbtree_insert__2__9
at /home/kiwamu/tmp/ats/rbtree/rbtree.dats:235
1.10 y 0x00000000000048df in
_057_home_057_kiwamu_057_tmp_057_ats_057_rbtree_057_rbtree_056_dats__rbtree_insert__2__10
at /home/kiwamu/tmp/ats/rbtree/rbtree.dats:235
```

Kiwamu Okabe

unread,
May 28, 2019, 1:51:53 AM5/28/19
to ats-lang-users
Dear Hongwei,

On Tue, May 28, 2019 at 2:15 PM Kiwamu Okabe <kiw...@debian.or.jp> wrote:
> Following means that there are 20 `#line` directives, but gdb only
> found 10 of them.
> Do you know how to find all of the multiple breakpoints?

Sorry. I miss understood it.
There are 20 `#line`s, but every instance has 2 `#line`s.
Then gdb found top of then as break point.

Kiwamu Okabe

unread,
May 28, 2019, 2:19:54 AM5/28/19
to ats-lang-users
Dear all,

I added a Wiki page to explain this post:

https://github.com/githwxi/ATS-Postiats/wiki/GDB

Thanks,
--
Kiwamu Okabe

Timmy Jose

unread,
Sep 20, 2021, 9:16:31 AM9/20/21
to ats-lang-users
This is very useful. Thanks for the wiki page, Kiwamu!
Reply all
Reply to author
Forward
0 new messages