簡體   English   中英

time()和gettimeofday()之間的差異以及為什么會導致seg錯誤

[英]difference between time() and gettimeofday() and why does one cause seg fault

我正在嘗試測量系統調用的時間,我嘗試在這個程序中使用time(0)gettimeofday() ,但每當我使用gettimeofday()它就會出現錯誤。 我想我可以使用time(0)但我想知道為什么會這樣。 我知道你們可以看看它並看到問題所在。 請不要對我大喊大叫!

我想得到時間,但不能保存在任何地方。

我已經嘗試了我能想到的每種代碼組合,但是我在這里粘貼了最簡單的版本。 我是C和Linux的新手。 我看一下.stackdump文件,但這對我來說毫無意義。

GetRDTSC位於util.h中,它可以像人們所期望的那樣執行rdtsc() 現在它設置為10次迭代但后來循環將運行1000次,沒有printf

#include <stdio.h>
#include <time.h>
#include "util.h"

int main() {

    int i;
    uint64_t cycles[10];

    for (i = 0; i < 10; ++i) {

         // get initial cycles
         uint64_t init = GetRDTSC();

         gettimeofday(); // <== time(0) will work here without a seg fault.

         // get cycles after
         uint64_t after = GetRDTSC();   

         // save cycles for each operation in an array
         cycles[i] = after - init;

         printf("%i\n", (int)(cycles[i]));
    }  
}

簡短的版本

gettimeofday()需要一個指向struct timeval的指針來填充時間數據。

所以,例如,你會做這樣的事情:

#include <sys/time.h>
#include <stdio.h>
int main() {  
    struct timeval tv;
    gettimeofday(&tv, NULL); // timezone should be NULL
    printf("%d seconds\n", tv.tv_secs);
    return 0;
}

長版

真正的問題是gcc會在你的系統上自動包含vdso ,其中包含一個syscall gettimeofday的符號。 考慮這個程序(整個文件):

int main() {
  gettimeofday();
  return 0;
}

默認情況下,gcc會在沒有警告的情況下編譯它。 如果你檢查它鏈接的符號,你會看到:

ternus@event-horizon ~> gcc -o foo foo.c
ternus@event-horizon ~> ldd foo
        linux-vdso.so.1 =>  (0x00007ffff33fe000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f56a5255000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f56a562b000)

您恰好正在使用具有已定義符號的函數,但如果沒有原型,則無法確定它應該具有多少命令行參數。

如果你用-Wall編譯它,你會看到:

ternus@event-horizon ~> gcc -Wall -o foo foo.c
foo.c: In function ‘main’:
foo.c:2:3: warning: implicit declaration of function ‘gettimeofday’ [-Wimplicit-function-declaration]

當然,當你嘗試運行它時會出現段錯誤。 有趣的是,它在內核空間中會出現段錯誤(這是在MacOS上):

cternus@astarael ~/foo> gcc -o foo -g foo.c
cternus@astarael ~/foo> gdb foo
GNU gdb 6.3.50-20050815 (Apple version gdb-1822) (Sun Aug  5 03:00:42 UTC 2012)
[etc]

(gdb) run
Starting program: /Users/cternus/foo/foo
Reading symbols for shared libraries +.............................. done

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000001
0x00007fff87eeab73 in __commpage_gettimeofday ()

現在考慮這個程序(再次,沒有頭文件):

typedef struct {
  long tv_sec;
  long tv_usec;
} timeval;

int main() {
  timeval tv;
  gettimeofday(&tv, 0);
  return 0;
}

這將編譯並運行得很好 - 沒有段錯誤。 你已經為它提供了它所期望的內存位置,即使仍然沒有提供gettimeofday原型。

更多信息:

任何人都能理解gettimeofday的工作原理嗎?

是否有更快的gettimeofday相當於?

POSIX gettimeofday規范

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM