【问题标题】:Native localtime() segfaults本机 localtime() 段错误
【发布时间】:2018-04-29 14:55:59
【问题描述】:

在尝试在 Perl 6 中公开 localtime 功能时,我似乎做错了:

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

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.

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

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

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

【问题讨论】:

  • 我正在检查几件事,而且都是段错误;我的印象是 Perl 6 time 返回的数字太大而无法保存在 uint32 中。您是否也尝试过使用原生的time

标签: raku nativecall


【解决方案1】:

localtime() 需要一个 time_t* 类型的指针作为参数。假设 time_tuint32_t 在您的特定平台上是兼容的类型,

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

应该这样做(尽管除非你公开你的属性,否则你什么都看不到)。

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

【讨论】:

  • 我在使用这个解决方案时遇到了一个错误,我真的不知道它是如何解决问题的,除了 is rw 似乎修复了分段错误。这会产生错误Native call expected argument that references a native integer, but got P6int in method CALL-ME at /home/jmerelo/.rakudobrew/moar-2018.04/install/share/perl6/sources/24DD121B5B4774C04A7084827BFAD92199756E03 (NativeCall) line 581 in block &lt;unit&gt; at localtime-native.p6 line 23
  • @jjmerelo:出于某种原因,使用匿名内联变量不起作用;如果你添加一个单独的声明,它在这里工作......
  • @jjmerelo:那是因为 liz 已将她的所有属性声明为私有...
  • @jjmerelo: cf 我怀疑最后两个属性被切换了,即$!tm_zone 不会包含有效地址;您可以尝试相反的顺序,或者只公开前几个属性,这样您就可以检查至少这些属性是否包含预期值...
  • MacOS man localtime 文档似乎与现实不符。 Christoph++ 指出痛点。
猜你喜欢
  • 2016-06-02
  • 1970-01-01
  • 1970-01-01
  • 2014-04-26
  • 1970-01-01
  • 2020-07-26
  • 2013-09-11
  • 1970-01-01
  • 2013-11-02
相关资源
最近更新 更多