Skip to content

Instantly share code, notes, and snippets.

@master-q
Created May 27, 2019 09:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save master-q/f17359f8dad7e036a0c658ca00fec399 to your computer and use it in GitHub Desktop.
Save master-q/f17359f8dad7e036a0c658ca00fec399 to your computer and use it in GitHub Desktop.
#Vala はどうやって #DWARF を吐くのか
= ValaはどうやってDWARFを吐くのか
[2019-05-27 16:20]
<<<Vala
<<<DWARF
== 参考
"Projects/Genie/Developing - GNOME Wiki!" https://wiki.gnome.org/Projects/Genie/Developing
"Valaのデバッグ[メモ] | TIPS" http://1204lts.blogspot.com/2014/01/vala.html
"Get Started · thiagoabreu/vala-code Wiki" https://github.com/thiagoabreu/vala-code/wiki/Get-Started
== やってみる
```
$ cat main.vala
class Foo : Object {
public int field;
}
void main() {
Foo? foo = null;
stdout.printf("%d\n", foo.field);
}
$ valac -g --save-temps main.vala
$ gdb main
(gdb) run
Starting program: /home/kiwamu/tmp/vala/main
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x0000555555555333 in _vala_main () at main.vala:7
7 stdout.printf("%d\n", foo.field);
(gdb) bt
#0 0x0000555555555333 in _vala_main () at main.vala:7
#1 0x0000555555555386 in main (argc=1, argv=0x7fffffffd688) at main.vala:5
```
== `valac -g`すると何が起きる?
以下を眺めてみる:
```
$ strace -f -s 100000 valac -g --save-temps main.vala |&lv
```
なんとどうやら以下でシンボルが埋め込まれるらしい。
```
$ valac -g --save-temps main.vala
$ rm -f a.out main
$ vi main.vala
1 class Foo : Object {
2 public int field;
3 }
4
5 void main() {
6 Foo? foo = null;
7 stdout.printf("%d\n", foo.field);
8 }
$ cat main.c
/* main.c generated by valac 0.42.5, the Vala compiler
* generated from main.vala, do not modify */
#include <glib.h>
#include <glib-object.h>
#include <stdio.h>
#define TYPE_FOO (foo_get_type ())
#define FOO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_FOO, Foo))
#define FOO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_FOO, FooClass))
#define IS_FOO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_FOO))
#define IS_FOO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_FOO))
#define FOO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_FOO, FooClass))
typedef struct _Foo Foo;
typedef struct _FooClass FooClass;
typedef struct _FooPrivate FooPrivate;
enum {
FOO_0_PROPERTY,
FOO_NUM_PROPERTIES
};
static GParamSpec* foo_properties[FOO_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
struct _Foo {
GObject parent_instance;
FooPrivate * priv;
gint field;
};
struct _FooClass {
GObjectClass parent_class;
};
static gpointer foo_parent_class = NULL;
GType foo_get_type (void) G_GNUC_CONST;
Foo* foo_new (void);
Foo* foo_construct (GType object_type);
static void foo_finalize (GObject * obj);
void _vala_main (void);
Foo*
foo_construct (GType object_type)
{
Foo * self = NULL;
#line 1 "main.vala"
self = (Foo*) g_object_new (object_type, NULL);
#line 1 "main.vala"
return self;
#line 57 "main.c"
}
Foo*
foo_new (void)
{
#line 1 "main.vala"
return foo_construct (TYPE_FOO);
#line 66 "main.c"
}
static void
foo_class_init (FooClass * klass)
{
#line 1 "main.vala"
foo_parent_class = g_type_class_peek_parent (klass);
#line 1 "main.vala"
G_OBJECT_CLASS (klass)->finalize = foo_finalize;
#line 77 "main.c"
}
static void
foo_instance_init (Foo * self)
{
}
static void
foo_finalize (GObject * obj)
{
Foo * self;
#line 1 "main.vala"
self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_FOO, Foo);
#line 1 "main.vala"
G_OBJECT_CLASS (foo_parent_class)->finalize (obj);
#line 95 "main.c"
}
GType
foo_get_type (void)
{
static volatile gsize foo_type_id__volatile = 0;
if (g_once_init_enter (&foo_type_id__volatile)) {
static const GTypeInfo g_define_type_info = { sizeof (FooClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) foo_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Foo), 0, (GInstanceInitFunc) foo_instance_init, NULL };
GType foo_type_id;
foo_type_id = g_type_register_static (G_TYPE_OBJECT, "Foo", &g_define_type_info, 0);
g_once_init_leave (&foo_type_id__volatile, foo_type_id);
}
return foo_type_id__volatile;
}
void
_vala_main (void)
{
Foo* foo = NULL;
FILE* _tmp0_;
gint _tmp1_;
#line 6 "main.vala"
foo = NULL;
#line 7 "main.vala"
_tmp0_ = stdout;
#line 7 "main.vala"
_tmp1_ = foo->field;
#line 7 "main.vala"
fprintf (_tmp0_, "%d\n", _tmp1_);
#line 5 "main.vala"
_g_object_unref0 (foo);
#line 129 "main.c"
}
int
main (int argc,
char ** argv)
{
#line 5 "main.vala"
_vala_main ();
#line 5 "main.vala"
return 0;
#line 141 "main.c"
}
$ gcc -g `pkg-config --cflags --libs glib-2.0 gobject-2.0` main.c
$ gdb a.out
(gdb) run
Starting program: /home/kiwamu/tmp/vala/a.out
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x0000555555555333 in _vala_main () at main.vala:7
7 stdout.printf("%d\n", foo.field);
(gdb) bt
#0 0x0000555555555333 in _vala_main () at main.vala:7
#1 0x0000555555555386 in main (argc=1, argv=0x7fffffffd678) at main.vala:5
```
ということで単に`#line`を打ち込めばDWARFが適切に吐き出されるらしい。
ちなみにclangも同様の動作。
== ところで
今はGenieという言語の方が最新? / "Projects/Genie - GNOME Wiki!" https://wiki.gnome.org/Projects/Genie
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment