本地localtime()段错误

Eli*_*sen 10 perl6 nativecall raku

在尝试公开localtimePerl 6中的功能时,我似乎做错了什么:

use NativeCall;
my class TimeStruct is repr<CStruct> {
    has int32 $!tm_sec;
    has int32 $!tm_min;
    has int32 $!tm_hour;
    has int32 $!tm_mday;
    has int32 $!tm_mon;
    has int32 $!tm_year;
    has int32 $!tm_wday;
    has int32 $!tm_yday;
    has int32 $!tm_isdst;
    has Str   $!tm_zone;
    has long  $!tm_gmtoff;
}

sub localtime(uint32 $epoch --> TimeStruct) is native {*}
dd localtime(time);  # segfault
Run Code Online (Sandbox Code Playgroud)

跑下perl6-lldb-m,我得到:

Process 82758 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x5ae5dda1)
    frame #0: 0x00007fffe852efb4 libsystem_c.dylib`_st_localsub + 13
libsystem_c.dylib`_st_localsub:
->  0x7fffe852efb4 <+13>: movq   (%rdi), %rax
    0x7fffe852efb7 <+16>: movq   %rax, -0x20(%rbp)
    0x7fffe852efbb <+20>: movq   0x8e71d3e(%rip), %rbx     ; lclptr
    0x7fffe852efc2 <+27>: testq  %rbx, %rbx
Target 0: (moar) stopped.
Run Code Online (Sandbox Code Playgroud)

我在这里做错了什么明显的事情?

更新:最终的工作解决方案:

class TimeStruct is repr<CStruct> {
    has int32 $.tm_sec;    # *must* be public attributes
    has int32 $.tm_min;
    has int32 $.tm_hour;
    has int32 $.tm_mday;
    has int32 $.tm_mon;
    has int32 $.tm_year;
    has int32 $.tm_wday;
    has int32 $.tm_yday;
    has int32 $.tm_isdst;
    has long  $.tm_gmtoff; # these two were
    has Str   $.time_zone; # in the wrong order
}

sub localtime(int64 $epoch is rw --> TimeStruct) is native {*}

my int64 $epoch = time;  # needs a separate definition somehow
dd localtime($epoch);
Run Code Online (Sandbox Code Playgroud)

Chr*_*oph 8

localtime()期望一个类型time_t*为指针的指针.假设time_t并且uint32_t是您特定平台上的兼容类型,

sub localtime(uint32 $epoch is rw --> TimeStruct) is native {*}
my uint32 $t = time;
dd localtime($t);
Run Code Online (Sandbox Code Playgroud)

应该这样做(虽然你不会看到任何东西,除非你公开你的属性).

我有点惊讶你time_t的不是64位类型,并且刚刚使用Google搜索apple time.h,我还怀疑你的struct声明中的最后两个属性是错误的顺序...

  • @jjmerelo:我怀疑最后两个属性是否被切换,即`$!tm_zone`将不包含有效地址; 你可以尝试相反的顺序,或只是公开前几个属性,这样你就可以检查至少那些将包含预期值... (2认同)
  • 看起来MacOS`man localtime`文档与现实不符.Christoph ++用于指出疼痛部位. (2认同)