GDBのシミュレータでエンディアンを確かめる

インテルのCPUはリトルエンディアン、ルネサスの SH や H8 はビッグエンディアン

 

これをどうやったら確かめられるか考えた。GDBにはシミュレータ機能があることを思い出した。そこで、簡単なソースコードをシミュレータで動かし、メモリの内容を表示させて、バイトオーダーを確認してみた。

 

C言語ソースコード

int main(void){
	int a = 0x5678;
	int b = 0x1234;
	int c = a + b;
	return c;
}    

gdb のシミュレータで実行する。まずインテルCPUの x86

(gdb) list
1
2       int main(void){
3               int a = 0x5678;
4               int b = 0x1234;
5               int c = a + b;
6
7               return c;
8       }
(gdb) b main
Breakpoint 1 at 0x40157d: file sample01.c, line 3.
(gdb) r
Starting program: /e/Projects/MPU/SH/mySamples/x86
[New Thread 7868.0x121c]
[New Thread 7868.0x212c]

Thread 1 hit Breakpoint 1, main () at sample01.c:3
3               int a = 0x5678;
(gdb) n
4               int b = 0x1234;
(gdb) x &a
0x66fe4c:       0x00005678
(gdb) x/4b &a
0x66fe4c:       0x78    0x56    0x00    0x00
(gdb) n
5               int c = a + b;
(gdb) x &b
0x66fe48:       0x34
(gdb) x/4b &b
0x66fe48:       0x34    0x12    0x00    0x00
(gdb) n
7               return c;
(gdb) x &c
0x66fe44:       0xac
(gdb) x/4b &c
0x66fe44:       0xac    0x68    0x00    0x00
(gdb) x/12b &c
0x66fe44:       0xac    0x68    0x00    0x00    0x34    0x12    0x00    0x00
0x66fe4c:       0x78    0x56    0x00    0x00
(gdb)
    

バイトの並びがリトルエンディアンになっていることを確認できた。 次にビッグエンディアンルネサス SH についてみてみる。

  $ sh-elf-gdb sample01
GNU gdb (GDB) 7.5.1
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i386-pc-mingw32msvc --target=sh-elf".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from E:\Projects\MPU\SH\mySamples\sample01...done.
(gdb) target sim
Connected to the simulator.
(gdb) load
Loading section .init, size 0x36 vma 0x1000
Loading section .text, size 0x10d0 vma 0x1038
Loading section .fini, size 0x2a vma 0x2108
Loading section .rodata, size 0x24 vma 0x2134
Loading section .eh_frame, size 0x4 vma 0x2158
Loading section .ctors, size 0x8 vma 0x21dc
Loading section .dtors, size 0x8 vma 0x21e4
Loading section .jcr, size 0x4 vma 0x21ec
Loading section .data, size 0x83c vma 0x21f0
Loading section .got, size 0xc vma 0x2a2c
Loading section .stack, size 0x4 vma 0x300000
Start address 0x1038
Transfer rate: 52672 bits in <1 sec.
(gdb) list
1
2       int main(void){
3               int a = 0x5678;
4               int b = 0x1234;
5               int c = a + b;
6
7               return c;
8       }
(gdb) b 7
Breakpoint 1 at 0x11e6: file sample01.c, line 7.
(gdb) r
Starting program: E:\Projects\MPU\SH\mySamples\sample01

Breakpoint 1, main () at sample01.c:7
7               return c;
(gdb) x &a
0x2fffac:       0x00005678
(gdb) x/4b &a
0x2fffac:       0x00    0x00    0x56    0x78
(gdb) x/w &b
0x2fffa8:       0x00001234
(gdb) x/4b &b
0x2fffa8:       0x00    0x00    0x12    0x34
(gdb) x/w &c
0x2fffa4:       0x000068ac
(gdb) x/4b &c
0x2fffa4:       0x00    0x00    0x68    0xac
(gdb) x/12b &c
0x2fffa4:       0x00    0x00    0x68    0xac    0x00    0x00    0x12    0x34
0x2fffac:       0x00    0x00    0x56    0x78
(gdb)  

こちらは確かにビッグエンディアンになっていることを確認できた。

関数型言語のツール整理

関数型言語の各種ツールについて、整理する

パッケージ管理

対話的実行環境

ビルド

テスト

Web Application Framework

対象言語は

Haskell

Elixir

Scala

Typescript

また、関数型言語の特徴について、比較する。

カリー化

高階関数

部分適用

パターンマッチング

遅延評価

Immutable Lambda

関数型言語のツール整理

関数型言語の各種ツールについて、整理する

パッケージ管理

対話的実行環境

ビルド

テスト

Web Application Framework

対象言語は

Haskell

Elixir

Scala

Typescript

また、関数型言語の特徴について、比較する。

カリー化

高階関数

部分適用

パターンマッチング

遅延評価

PlayFramework, Scala, typescript を触ってみよう

Webなアプリケーションはほとんど作ったことがない。

すこし勉強してみることに。

 

memory leak check by sanitizer

 

#include <iostream>
using namespace std;

class X{
public:
X();
~X();
};


X::X(){
cout << "X()" << endl;
}
X::~X(){
cout << "~X()" << endl;
}

int main(){
X* pX = new X();

//pX->~X();
delete pX;
return 0;
}

 

kzono@rachael:$ g++ -Wall callDestructor.cpp -fsanitize=address -fsanitize=leak
kzono@rachael:$ ./a.out
X()
~X()

=================================================================
==18291==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 1 byte(s) in 1 object(s) allocated from:
#0 0x7f37b9b2a532 in operator new(unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x99532)
#1 0x400cd1 in main (/home/kzono/Projects/cxx_samples/sanitizer_samples/memLeak/a.out+0x400cd1)
#2 0x7f37b914f82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: 1 byte(s) leaked in 1 allocation(s).
kzono@rachael:$

 

 

 

std::chrono::system_clock::time_point と time_t

時刻を秒単位で記録できればよいのであれば、time_t で十分見たい。

system_clock - cpprefjp C++日本語リファレンス

今回は通信用または記録用に時刻をシリアライズしたいわけなので、結局は time_t に変換することになりそう。

 

time_t は long に typedef されており、 long が何バイトになるかは処理系依存

普通のPCならば今時は 64bit なはず。 esp32 だとどうか?

 

あとで sizeof() 演算子で確かめてみよう。

MessagePack と日時(タイムスタンプ)

各種のセンサーから取得した値をサーバへ送る場合、シリアライズする必要がある。MessagePack が良さげ。圧縮率、対応言語の多さ、IDL不要など。

google さんの protocol buffers はIDLが必要。

 

で。センサーの計測データなので、計測日時が必要。C**の場合、どんなクラスを使えば良いのか調べた。

 

std::chrono::system_clockが使えそう。msgpackに渡すときにstd::stringに変換する必要があるのか?