Created
May 27, 2019 09:10
-
-
Save master-q/f17359f8dad7e036a0c658ca00fec399 to your computer and use it in GitHub Desktop.
#Vala はどうやって #DWARF を吐くのか
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
= 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