2016年4月29日 星期五

How To Compiler udev (udevadm)




Linux 初學者, 對這邊核心程式的編譯方式一定會被搞瘋掉
有時間再寫一篇 udevadm 移殖到Eclipse中 Debug的流程

The options used usually look like:


# mkdir udev
# cd udev
# git clone git://git.kernel.org/pub/scm/linux/hotplug/udev.git git





# cd git
# apt-get install gtk-doc-tools
# ./autogen.sh --without-selinux --disable-extras --disable-introspection
# ./configure CFLAGS='-g -O1'  --prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --with-selinux --enable-gtk-doc --with-rootprefix= --with-rootlibdir=/lib --bindir=/sbin --libexecdir=/lib --with-systemdsystemunitdir=/lib/systemd/system 

checking for BLKID... no
configure: error: Package requirements (blkid >= 2.20) were not met:
No package 'blkid' found
No blkid, need install libblkid-dev


# apt-get install libblkid-dev

# ./configure CFLAGS='-g -O1'  --prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --with-selinux --enable-gtk-doc --with-rootprefix= --with-rootlibdir=/lib --bindir=/sbin --libexecdir=/lib --with-systemdsystemunitdir=/lib/systemd/system 
checking for KMOD... no
configure: error: Package requirements (libkmod >= 5) were not met:

No package 'libkmod' found
No 'libkmod', Need install libkmod-dev

# apt-get install libkmod-dev
# apt-get install libselinux-dev

# apt-get install libglib2.0-dev

# apt-get install libgirepository1.0-dev

# apt-get install gperf

# ./configure CFLAGS='-g -O1'  --prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --with-selinux --enable-gtk-doc --with-rootprefix= --with-rootlibdir=/lib --bindir=/sbin --libexecdir=/lib --with-systemdsystemunitdir=/lib/systemd/system 






configure 完成, 會在目錄下發現一個 makefile 檔案! 

可以開始進行 gcc make 動作


# make


編譯出現錯誤, 原來這個 mq_getattr 很久以前的功能,可以直接作廢.

# gedit /root/udev/git/src/sd-daemon.c
comment it out line 394 & 395 
 //        if (mq_getattr(fd, &attr) < 0)
 //              return -errno;

重新作執行一次 gcc make 動作
# make

 




# ./udevadm --version
182

請參考 Ubuntu udevadm用法
# ./udevadm info -q all -n /dev/sda | grep DEVPATH


可以使用 udevadm監控Hot Plug的狀態

# udevadm monitor





2016年4月25日 星期一

HTML with C++ cpp Code


原文來自
How can I show code (specifically C++) in an HTML page?



<head>
  <link href="css/shCore.css" rel="stylesheet" type="text/css" />
  <link href="css/shThemeDefault.css" rel="stylesheet" type="text/css" />
</head>

<body>
  <pre class='brush: cpp'>
  // my first program in C++
  #include <iostream>
  using namespace std;

  int main ()
  {
    cout << "Hello World!";
    return 0;
  }
  </pre>

  <script src="js/shCore.js"></script>
  <script src="js/shBrushCpp.js"></script>
  <script>
    SyntaxHighlighter.all()
  </script>
</body>

Debugging with GDB


因為在 Eclipse中 Debug 多個 pthread 真的有點痛苦
奇怪的是 Altera Eclipse 版本不會這樣

後來查出原來是其他程式段錯誤
卻造成 Debug thread混亂


但 Linux Eclipse CDT 中 switch thread時卻會卡卡的
只好找找看別的方式來試試看

Debugging with GDB學習記錄(一)

Debugging with GDB學習記錄(二)

Debugging with GDB學習記錄(三)


2016年4月21日 星期四

Linux Memory Leak

Linux Tools Project - Valgrind Support
 https://eclipse.org/linuxtools/projectPages/valgrind/


Eclipse 外掛︰ MAT, Memory Analyzer Tool (JAVA Only)
  http://www.eclipse.org/mat/downloads.php
  http://lp43.blogspot.tw/2011/11/mat.html

valgrind:
使用valgrind檢查C語言memory leak
 # apt-get install valgrind
 # valgrind --leak-check=full --show-leak-kinds=all --verbose ./My-Leaky-Program-Filename


mtrace:

在程式中加入兩行
#include <mcheck.h>

static void Main()
{
 ...
  mtrace();
 ...
}

在終端機模式下
# mtrace ./My-Leaky-Program-Filename  Memory_Leak.txt


2016年4月19日 星期二

Linux Physical Block Size

Linux 這個  physical_block_size 是 File System 的 physical block

> 磁區大小 (邏輯/實體):512 位元組 / 4096 位元組
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
File System 以上, 一個 Block Size是 4096Byte
SCSI Direct IO以下, 一個 Sector Size是 512Byte 
(但有一些少見的裝置其 Sector Size是 1024Byte)

/sys/block/sda/queue/physical_block_size
 4096

/sys/block/sdb/queue/physical_block_size
 512

/sys/block/sdc/queue/physical_block_size
 512



Linux SCSI Pass Through Interface

其實不難, 只是專案必需要知道每一個實體 PHY Port 是連結到 Linux 中那一個 /dev/sgn 中
原來是直接用 /dev/sdN , 但發現這對以逅的專案會有影響, 所以就改用/dev/sgN 方式
而且習慣看 SCSI Sense Code, 除錯也比較容易.

過去十幾年來都在 Windows 和 NIOS-II 下對 Device直接下 SCSI Command
終於換到 Linux 平台來.

Some examples of storage device names of the supported operating systems

 //===========================================
方式一:
   一般都是利用 sg3-utils核心
   # apt-get install sg3-utils

   也就是開啟 "/dev/sgN" 方法
   http://sg3-utils.sourcearchive.com/
    sg3_utils-1.32 Example
 

  參考下面這幾篇
   T10 Working Drafts
   這個 T10很多檔案都已經改為付費購買. 其實只要只知道檔案名稱, 還是在Google搜尋下載得到.

   Seagate SCSI Commands Reference Manual
   Seagate SCSI Commands Reference Manual April 2010
   wiki SCSI command


   http://www.tldp.org/HOWTO/SCSI-Generic-HOWTO/
   Appendix C. Programming example

   ioctrl-using-scsi-pass-through

   linux scsi generic howto學習筆記

 
typedef struct sg_io_hdr
{
  int interface_id;           /* [i] 'S' for SCSI generic (required) */
  int dxfer_direction;        /* [i] data transfer direction  */
                                     SG_DXFER_NONE /* e.g. a SCSI Test Unit Ready command */
                                     SG_DXFER_TO_DEV /* e.g. a SCSI WRITE command */
                                     SG_DXFER_FROM_DEV /* e.g. a SCSI READ command */
                                   
                                     TestUnitReady => SG_DXFER_NONE
                                     ReadCapacity10 => SG_DXFER_FROM_DEV
                                     Read10 => SG_DXFER_FROM_DEV
                                     Write10 => SG_DXFER_TO_DEV
 
  unsigned char cmd_len;      /* [i] SCSI command length ( <= 16 bytes) */
                                     ReadCapacity10 => cmd_len = 10
                                     ReadCapacity16 => cmd_len = 16
                                     Read10 => cmd_len = 10
                                     Write10 => cmd_len = 10
                                     Write16 => cmd_len = 16

  ...
} sg_io_hdr_t;
//===========================================

使用 SG_IO 出現 ENOMEM
表示要求傳輸的記憶體太大
經測試只傳輸到 512byte * 9181sector
一呼叫 512byte * 9182sector   就會發生 ENOMEM
經查 Google 這是Linux的核心限制
scsi sg ioctl要求向 blk-mq 取得一塊和要求傳輸大小的記憶體區塊失敗.

對 Storage一次使用大區塊讀取, 並不一定會比較穩定快速
因為不同的 Storage, 其晶片的特性不同
讀取太大塊, 速度反而會變慢, 變錯.
這個數字是多少, 就依賴經驗值, 必竟Storage的種類範圍太廣.


下面只是參考, 別太認真.
void ReadWrite_Test()
{
 int nI, nJ;
 TLBA nReadLba, nWriteLba;
 DWORD nSectorSize, nReadLen, nWriteLen;
 DWORD nReadCrc32, nWriteCrc32, nWriteSectorCrc32;
 DWORD nReadBufLen, nWriteBufLen;
 UCHAR *pReadBuf = new UCHAR[16*1024*1024];
 UCHAR *pWriteBuf = new UCHAR[16*1024*1024];


 nSectorSize = 512;
 nWriteLba = 0;
 nWriteLen = 8192;
 memset( pWriteBuf, 0, 16*1024*1024);
 /* 初始化 Writer Data Buffer */
 for( nI =0; nI < nWriteLen; nI++)
 {
  /* 中間填入 序號Index */
  for( nJ = 4; nJ < nSectorSize-sizeof(DWORD); nJ++)
   pWriteBuf[nI*nSectorSize+nJ] = nJ%255;
  /* 前4個Byte 是 Sector Index */
  pWriteBuf[nI*nSectorSize]   = (UCHAR)((nWriteLba+nI) >> 24); // MSB
  pWriteBuf[nI*nSectorSize+1] = (UCHAR)((nWriteLba+nI) >> 16);
  pWriteBuf[nI*nSectorSize+2] = (UCHAR)((nWriteLba+nI) >> 8);
  pWriteBuf[nI*nSectorSize+3] = (UCHAR)((nWriteLba+nI));            // LSB
  nWriteSectorCrc32 = Get_CRC32( pWriteBuf+(nI*nSectorSize), nSectorSize-sizeof(DWORD));
  /* 後 2個Byte 是 Sector Index */
  pWriteBuf[nI*nSectorSize+nSectorSize-sizeof(DWORD)]    = (UCHAR)(nWriteSectorCrc32 >> 24); // MSB
  pWriteBuf[nI*nSectorSize+nSectorSize-sizeof(DWORD)+1]  = (UCHAR)(nWriteSectorCrc32 >> 16);
  pWriteBuf[nI*nSectorSize+nSectorSize-sizeof(DWORD)+2]  = (UCHAR)(nWriteSectorCrc32 >> 8);
  pWriteBuf[nI*nSectorSize+nSectorSize-sizeof(DWORD)+3]  = (UCHAR)(nWriteSectorCrc32);       // LSB
 }

 nWriteBufLen = nSectorSize*nWriteLen;
 /* 整個 Write Data Buffer 的 CRC-32 */
 nWriteCrc32  = Get_CRC32( pWriteBuf, nWriteBufLen);
 if( Write16( nWriteLba, nSectorSize, nWriteLen, pWriteBuf) == true)
 {
  memset( pReadBuf, 0, 4096);
  memset( pReadBuf, 0, 16*1024*1024);
  nReadLen = nWriteLen;
  nReadLba = nWriteLba;
  nReadBufLen = nSectorSize * nReadLen;
  if( Read16( nReadLba, nSectorSize, nReadLen, pReadBuf))
  {
   /* 驗證讀回來的資料是否正確 */
   nReadCrc32 = Get_CRC32( pReadBuf, nReadBufLen);
   if( nReadCrc32 != nWriteCrc32)
    nprintf( "Read/Write Test CRAC-32 Failed!");
   if( memcmp( pReadBuf, pWriteBuf, nReadBufLen) == 0)
    nprintf( "Read/Write Test Compare Ok!");
   else
    nprintf( "Read/Write Test Compare Failed!");
  }
 }
// Write12( nWriteLba, nSectorSize, nWriteLen, pWriteBuf);
// Write16( nWriteLba, nSectorSize, nWriteLen, pWriteBuf);

if( pReadBuf)
 delete[] pReadBuf;
if( pWriteBuf)
 delete[] pWriteBuf;
}


 //===========================================
# lsscsi
[0:0:0:0]    disk    SEAGATE  ST3500414SS      0006  /dev/sdb
[0:0:1:0]    disk    SEAGATE  ST3500414SS      0006  /dev/sdc
[1:0:0:0]    disk    ATA      ST1000DM003-9YN1 CC4B  /dev/sda

# lsscsi --transport
[6:0:0:0]    disk    sas:0x5000c500418fac39          /dev/sdb
[6:0:1:0]    disk    sas:0x5000c50041ea5265          /dev/sdc

  /sys/class/scsi_generic/sg2/device/block/sdc
  /sys/class/scsi_generic/sg2/device/scsi_device/6:0:1:0
  /sys/class/scsi_generic/sg2/device/scsi_device/6:0:1:0/sas_address

可以交叉驗證, 就可以知道 /dev/sg3 是那一顆HDD
要注意  Hot-Plug 的狀態下, Target 會改變, /sys/class/scsi_generic/sgN的目錄會自動消失, 也會自動出現.

所以用udevadm 來監控 (但監控這幾個目錄也是可以, 而且比較簡單)
How To Compiler udev


 $ apt-get install sg3-utils
 $ sg_scan -i -x

 //===========================================
 sg3_utils-1.32 Example




如果是 SATA HDD交叉驗證, 請看另一篇取得 SATA PHY Port Index 的相關文章

//===========================================
關於超過 2TB 容量的 Device
請使用 ReadCapacity16, Read16, Write16 這幾組指令
ReadCapacity10  有的會直接失敗, 有的 Device會回傳四個 0xFF
這時就轉換為  ReadCapacity16指令

ReadCapacity回傳的 Capacity是最後一個 LBA位置
所以實際容量為 Capacity + 1

還有一種情況是造假的 Capacity, 也就是回傳的 Capacity都是假的
這時要實際的去 Write & Read Last LBA, 進行資料驗證

記得有一次, 遇到一個Device, 一次 Read/Write 16MB, 回傳都是正常
讀寫的資料只有前面 4MB 資料是正確, 後面 12MB資料都是晶片亂編出來.

其實最常見的是, 寫入時, Device回傳 Write OK, 但確沒有真正的寫入.


//===========================================
//===========================================
方式二:
   使用 /dev/bsg/1:0:0:0
http://sg.danny.cz/sg/p/libsgutils2-2_1.42-0.1_i386.deb
http://www.spinics.net/lists/linux-scsi/msg53920.html
sg_tst_context


//===========================================
//===========================================
方式三:
  這方法只適用 LSI  控制卡上的 Device
  Linux LSI SAS 9211-8i Utility
  Source Code中一個 doScsiIo(), doMptCommand()  的函式
  利用 LSI 驅動程式提供的 mpt_ioctl_command
  直接對 LSI CHIP 下達 SCSI Command
  LSI Util 原始程式是一個 SCSI Command就 Open Device Handle一次
  速度會比較慢, 最好要改寫一些程式.

//===========================================
關於 Linux 下直接使用 ATA Command
  Linux ioctl command for bypassing ATA command(Identify) - Sample Code
  這是直接使用 ioctl(device, HDIO_DRIVE_CMD, buf);
  真是方便, 以前在 NIOS 中, 程式寫了一大堆程式才做出來.
  但還是建議使用 Hdparm 的  sgio方式

另一個是請查詢 hdparm 的原始程式
  https://sourceforge.net/projects/hdparm/
  hdparm.c / sgio.c / sgio.h

//===========================================



Linux IPC 進程間通信

Linux 並沒有 Windows下面的 WM_COPYDAT 這個簡單好用的功能
比較像的是 msgget() 這一組

這有一篇參考文章
http://albert-oma.blogspot.tw/2013/06/linux-ipc.html




2016年4月17日 星期日

Ubuntu 14.04 耳機沒有聲音

在幾台新的ASUS 主機版都發生這個情形

一台電腦是使用 Reltak AL1150 還沒解決這問題
另一台電腦是使用 Reltak AL1150 同樣的環境, 卻可以撥放
換個新的 Ubuntu, 重新做一次, 又不行撥放
搞不懂
網路上的解決方式也一堆, 都沒有統一.
( Ubuntu 對於一般使用者, 還有好遠的路要走)

幾個 Unbutu 與音效有關指令
alsamixer
speaker-test -t wav -c 2
aplay -i
aplay -L



請先檢查驅動程式是否是最新版本
# apt-get install alsa-base alsa-utils


修改檔案 /etc/modprobe.d/alsa-base.conf
# gedit /etc/modprobe.d/alsa-base.conf
在檔案內容最尾端增加一行
options snd-hda-intel id=PHC index=1


重新開機
#reboot

登入後
# aplay -L

修改輸出音量大小
# alsamixer
自行測式一下, 就知道每一項的功能

如果有聲音, 但很小聲, 就用 alsamixer 打聲音調大聲
alsamixer



Ubuntu 14.04 關閉"系統錯誤報告"提示

如果直接在終端機下 reboot指令
很多程式在重新登入 Desktop都會出現"系統錯誤報告"

可以直接修改檔案將這功能關閉
檔案名稱:  /etc/default/apport
enabled=0


2016年4月16日 星期六

Ubuntu 系統更新


沒事別亂下更新指令
因為....很多程式會發生相容性問題

apt-get install --install-recommends linux-generic-lts-wilya

Ubuntu 解壓縮程式 7z & rar

7-ZIP
 安裝
  # apt-get install p7zip-full
 指令
  # 7z x PACKAGE.7z


RAR
 安裝
  # apt-get install p7zip-rar
 指令
  # 7z x PACKAGE.rar

 安裝
  # apt-get install rar
 指令: 解壓縮
  # rar e PACKAGE.rar
 指令: 壓縮
  把現在目錄下檔案都壓縮到TargetFileName.rar中
  # rar a TargetFileName.rar

安裝好後, Ubuntu的 Desktop 檔案管理就可以直接用右鍵"在此解壓縮"解開了.

2016年4月14日 星期四

Ubuntu 15.04 如何找到 pthread.h 的原始程式

1:
 先到 /user/lib 目錄, 尋找檔案, 關鍵字  pthread

 會顯示一個檔案 libpthread.so

2:
# dpkg -S /usr/lib/x86_64-linux-gnu/libpthread.so
會顯示
libc6-dev:amd64: /usr/lib/x86_64-linux-gnu/libpthread.so

3:
# apt-cache show libc6-dev

會顯示
Filename: pool/main/e/eglibc/libc6-dev_2.19-0ubuntu6_amd64.deb



4:
google 找  libc6-dev_2.19-0ubuntu6_amd64.deb


5: 右邊有一個 eglibc - 2.19-0ubuntu6 的連結就是
Build details 
Source:
eglibc - 2.19-0ubuntu6




如果要 GNU版本
則在這頁面的下方 選一個需要的







linux 工程計算機-galculator

個人覺得這套 galculator 比較類似Windows 上的計算機
# apt-get install galculator
# galculator

點紅黃色區域下方那一排, 可以直接轉換為 DEC/HEX/BIN
7 除以 3
 就點選 7 ->  /   -> 3
要取得7 除以 3 的餘數
 就點選  7 -> "餘數" -> 3


之前都是 Google 的搜尋器
要取得7 除以 3 的餘數
 就在Google 的搜尋器輸入   7 mod 3



Ubuntu 原的是
# gnome-calculator


2, 8, 10, 16 進位換算怎是用 gbase

# apt-get install gbase
# gbase

 gbase要自行手動加到桌面
 /usr/bin/gbase


printf 列印 64bit int


//======================================
一個另我快瘋掉的型別
因有一組程式會共用
同時在 Windows x86(32bit)/NIOS(32bit)/Linux(32bit)/Linux(64bit)
下共同執行
所以...型別就出現問題了
(還好沒有想要另弄到 Win64下...)
那 printf 要怎搭配?

Windows(32bit)
 int  是 4個 byte
 long 是 4個 byte <== 注意
 long long 是 8個 byte
 DWORD 是 4個 byte =>  unsigned long
 wchar_t 是 2個 byte

Linux(64bit)
 int 是 4個 byte
 long 是 8個 byte  <== 注意
 long long 是 8個 byte
 DWORD 必需也是 4個 byte =>  unsigned int  


 wchar_t 是 4個 byte

for Linux x64 gc++


_T("%x")    // => INT32   int                 4byte
_T("%X")    // => INT32   int                 4byte
_T("%lx")   // => void *, INT64, unsigned long      8byte
_T("%lX")   // => void *, INT64, unsigned long      8byte
_T("%llx")  // => unsigned long long, long long     8byte
_T("%llX")  // => unsigned long long, long long     8byte
_T("%d")    // => INT32   int                 4byte
_T("%u")    // => UINT32  unsigned int        4byte
_T("%ld")   // => INT64   long                8byte
_T("%lu")   // => UINT64  unsigned long       8byte
_T("%lld")  // => UINT64  long long           8byte
_T("%llu")  // => UINT64  unsigned long long  8byte


  char *pargv = (char *)0xEFFFFFFFFFFFFFFE;
  printf( "   p=>  %p \n", pargv);
  printf( "  lx=>  %lx \n", (unsigned long)pargv);
  printf( "  lX=>  %lX \n", (unsigned long)pargv);
  printf( "  lu=>  %lu \n", (unsigned long)pargv);
   p=>  0xeffffffffffffffe 
  lx=>  effffffffffffffe 
  lX=>  EFFFFFFFFFFFFFFE 
  lu=>  17293822569102704638 
 
//======================================
 unsigned int nX = 123;
 printf( "   p=>  %p \n", &nX);
 printf( "   p=>  %08p \n", &nX);
 printf( "   p=>  %016p \n", &nX);

 printf( "   p=>  %p \n", nX);
 printf( "   p=>  %08p \n", nX);
 printf( "   p=>  %016p \n", nX);
 printf( "   p=>  %010p \n", nX);
 printf( "   p=>  %018p \n", nX);
p=> 0x7fffffffdef0 p=> 0x7fffffffdef0 p=> 0x007fffffffdef0 p=> 0x7b p=> 0x00007b p=> 0x0000000000007b
   p=>  0x0000007b 
   p=>  0x000000000000007b 


//======================================
請參考這一篇
一個長整數各自表述 (Size of long integer may vary in 64-bit systems)

其實當在做跨平台的軟體時,
本來就要先自行檢查一次
看各種型別的 sizeof
尤其是在寫通訊程式或硬體相關程式
都要特別注意

//======================================
unsigned long nBufData = 123456; 

printf("lu  %lu\n", nBufData);

//====================================== "%lli" for int64_t
"%llu" for uint64_t
"%llx" for hex
"%llX" for HEX

UINT64 nBuffer = 140737320412160;  // 0x7FFFF5FD6400


printf("lli  %lli\n", nBuffer);
printf("llu  %llu\n", nBuffer);
printf("lld  %lld\n", nBuffer);
printf("llx  %llx\n", nBuffer);
printf("llX  %llX\n", nBuffer);
printf("0x%x%x\n", *(((int*)(&nBuffer))+1), nBuffer);

printf("lli  %016lli\n", nBuffer);
printf("llu  %016llu\n", nBuffer);
printf("lld  %016lld\n", nBuffer);
printf("llx  %016llx\n", nBuffer);
printf("llX  %016llX\n", nBuffer);

printf("lli  %016lli\n", nBuffer);
printf("llu  %016llu\n", nBuffer);
printf("lld  %016lld\n", nBuffer);
printf("llx  %016llx\n", nBuffer);
printf("llX  %016llX\n", nBuffer);

//-----------------------------------------------------------
 // for Linux x64 gc++
  char *pargv = (char *)0xEFFFFFFFFFFFFFFE;
  printf( "   p=>  %p \n", pargv);
  printf( "  lx=>  %lx \n", (unsigned long)pargv);
  printf( "  lX=>  %lX \n", (unsigned long)pargv);

  printf( "  lu=>  %lu \n", (unsigned long)pargv);
   p=>  0xeffffffffffffffe 
  lx=>  effffffffffffffe 
  lX=>  EFFFFFFFFFFFFFFE 
  lu=>  17293822569102704638 

//-----------------------------------------------------------
  void *pargv = (void *)0xEFFFFFFFFFFFFFFE;
  printf( "   p=>  %p \n", pargv);
  printf( "   x=>  %x \n", pargv);
  printf( "  lx=>  %lx \n", pargv);
  printf( " llx=>  %llx \n", pargv);
  printf( "   X=>  %X \n", pargv);
  printf( "  lX=>  %lX \n", pargv);
  printf( " llX=>  %llX \n", pargv);
  printf( "  lu=>  %lu \n", (unsigned long)pargv);

  printf( " llu=>  %llu \n", (unsigned long)pargv);

   p=>  0xeffffffffffffffe 
   x=>  fffffffe 
  lx=>  effffffffffffffe 
 llx=>  effffffffffffffe 
   X=>  FFFFFFFE 
  lX=>  EFFFFFFFFFFFFFFE 
 llX=>  EFFFFFFFFFFFFFFE 
  lu=>  17293822569102704638 

 llu=>  17293822569102704638 

//-----------------------------------------------------------
// argv char ** 0x7fffffffe028

int main(int argc,char *argv[])
{
 printf( "   p=>  %p \n", argv);
 printf( "   x=>  %x \n", argv);
 printf( "  lx=>  %lx \n", argv);
 printf( " llx=>  %llx \n", argv);
 printf( "   X=>  %X \n", argv);
 printf( "  lX=>  %lX \n", argv);
 printf( " llX=>  %llX \n", argv);
 printf( "  lu=>  %lu \n", (unsigned long)argv);
 printf( " llu=>  %llu \n", (unsigned long)argv);
}

   p=>  0x7fffffffe028 
   x=>  ffffe028 
  lx=>  7fffffffe028 
 llx=>  7fffffffe028 
   X=>  FFFFE028 
  lX=>  7FFFFFFFE028 
 llX=>  7FFFFFFFE028 
  lu=>  140737488347176 
 llu=>  140737488347176 

//-----------------------------------------------------------