Erreur: succÚs et comment y remédier

image







Tous les programmeurs novices sont toujours informĂ©s de l'importance d'un rapport d'erreur correct. Ils disent toujours que si le programme n'a pas rĂ©ussi Ă  faire quelque chose, il doit expliquer clairement et sans ambiguĂŻtĂ© pourquoi cela s'est produit. Ils parlent de l'importance de contrĂŽler la valeur de retour des fonctions appelĂ©es. De plus, mĂȘme les compilateurs ont appris Ă  Ă©mettre des avertissements si la valeur renvoyĂ©e par certaines fonctions est ignorĂ©e. Je dois dire que l'importance de la gestion des erreurs par les programmeurs modernes est acceptĂ©e. Cela conduit parfois Ă  des incidents amusants, comme dans le KDPV (pris ici). Dans la vraie vie, j'ai dĂ» faire face Ă  des messages de diagnostic aussi Ă©tranges Ă  plusieurs reprises. Je veux vous parler de ce dernier cas et des mĂ©thodes pour surmonter un tel diagnostic. Si vous ĂȘtes intĂ©ressĂ©, vous ĂȘtes les bienvenus sous chat. Les programmeurs expĂ©rimentĂ©s ne dĂ©couvriront certainement rien de nouveau pour eux-mĂȘmes, mais ils pourront certainement philosopher sur le dĂ©veloppement de logiciels.







Pour ceux qui ont "beaucoup de lettres"
  • il est important de gĂ©rer correctement les valeurs renvoyĂ©es par read ()
  • ( OpenSource )
  • - . « »


En gĂ©nĂ©ral, j'ai de tristes nouvelles. Il n'y aura plus de photos. Nous allons descendre au niveau de la console systĂšme Linux et y vivre. Dans ce cas, nous nous rĂ©jouirons. Pour le projet avec lequel travailler est un chargeur U-Boot assez connu . Projet open source soutenu par DENX Software Engineering... Par consĂ©quent, nous serons heureux d'avoir une console, un environnement systĂšme et, en gĂ©nĂ©ral, la vie bat son plein. Parce que lorsque vous travaillez avec ce projet, en rĂšgle gĂ©nĂ©rale, il n'y a rien de tel - des zones de mĂ©moire continues, le transfert d'octets d'un endroit Ă  un autre et l'attente que la pĂ©riphĂ©rie soit prĂȘte. Mais, au fait, cette partie est dĂ©jĂ  terminĂ©e et il existe un chargeur de dĂ©marrage assez fonctionnel pour le matĂ©riel. Il est temps de commencer avec des dĂ©corations qui permettent aux programmeurs d’applications d’influencer en quelque sorte le processus de dĂ©marrage du systĂšme. Rien de bon augure pour les problĂšmes. Le problĂšme a Ă©tĂ© rĂ©solu il y a longtemps et est activement utilisĂ© par des projets populaires comme OpenWRT et bien d'autres, un peu moins connus.







. U-Boot . . fw_printenv fw_setenv Linux. . . « ». ? . «fw_printenv», - .







localhost ~ # fw_printenv
Cannot open /dev/mtd1: No such file or directory
localhost ~ # fw_printenv --help
Usage: fw_printenv [OPTIONS]... [VARIABLE]...
Print variables from U-Boot environment

 -h, --help           print this help.
 -v, --version        display version
 -c, --config         configuration file, default:/etc/fw_env.config
 -n, --noheader       do not repeat variable name in output
 -l, --lock           lock node, default:/var/lock
      
      





. . . « » , . /etc/fw_env.config. . , ( ) U-Boot , . uboot.env , vfat ( FAT-32). . U-Boot , . . Linux. c uboot.env, , , /boot. 11 12 (/dev/mtd1 /dev/mdt2 ) 30 (/boot/uboot.env) .







# VFAT example
/boot/uboot.env 0x0000          0x4000
      
      





. . .







localhost ~ # fw_printenv
Read error on /boot/uboot.env: Success
      
      





, . , Linux’ — . , « » — root’. . , ( ) ? ? U-Boot’ «saveenv»? 








localhost ~ # ls -l /boot/uboot.env
-rwxr-xr-x 1 root root 8192 Dec  2 13:22 /boot/uboot.env
      
      





, . (, ). , ?







localhost ~ # mv /boot/uboot.env /boot/uboot.env.bak
localhost ~ # fw_printenv
Cannot open /boot/uboot.env: No such file or directory
localhost ~ # mv /boot/uboot.env.bak /boot/uboot.env
      
      





. . , 
 , . . , . ? 950 tools/env/fw_env.c:







        lseek(fd, blockstart + block_seek, SEEK_SET);

        rc = read(fd, buf + processed, readlen);
        if (rc == -1) {
            fprintf(stderr, "Read error on %s: %s\n",
                DEVNAME(dev), strerror(errno));
            return -1;
        }
        if (rc != readlen) {
            fprintf(stderr,
                "Read error on %s: Attempted to read %zd bytes but got %d\n",
                DEVNAME(dev), readlen, rc);
            return -1;
        }
      
      





. read(). . , , read() -1, errno . . ? , 
 








, read? , 
 read- -. read() . . ? , — .







localhost ~ # strace fw_printenv
execve("/usr/bin/fw_printenv", ["fw_printenv"], 0x7ebf2400 /* 28 vars */) = 0
brk(NULL)                               = 0x2118000
uname({sysname="Linux", nodename="localhost", ...}) = 0
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=42265, ...}) = 0
mmap2(NULL, 42265, PROT_READ, MAP_PRIVATE, 3, 0) = 0x76f14000
close(3)                                = 0
openat(AT_FDCWD, "/lib/libc.so.6", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\f~\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1286448, ...}) = 0
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76f12000
mmap2(NULL, 1356160, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x76da1000
mprotect(0x76ed7000, 65536, PROT_NONE)  = 0
mmap2(0x76ee7000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x136000) = 0x76ee7000
mmap2(0x76eea000, 8576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x76eea000
close(3)                                = 0
set_tls(0x76f12ca0)                     = 0
mprotect(0x76ee7000, 8192, PROT_READ)   = 0
mprotect(0x4a9000, 4096, PROT_READ)     = 0
mprotect(0x76f1f000, 4096, PROT_READ)   = 0
munmap(0x76f14000, 42265)               = 0
openat(AT_FDCWD, "/var/lock/fw_printenv.lock", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
flock(3, LOCK_EX)                       = 0
brk(NULL)                               = 0x2118000
brk(0x2139000)                          = 0x2139000
openat(AT_FDCWD, "/etc/fw_env.config", O_RDONLY) = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=1342, ...}) = 0
read(4, "# Configuration file for fw_(pri"..., 4096) = 1342
read(4, "", 4096)                       = 0
close(4)                                = 0
openat(AT_FDCWD, "/boot/uboot.env", O_RDONLY) = 4
fstat64(4, {st_mode=S_IFREG|0755, st_size=8192, ...}) = 0
close(4)                                = 0
openat(AT_FDCWD, "/boot/uboot.env", O_RDONLY) = 4
_llseek(4, 0, [0], SEEK_SET)            = 0
read(4, "n.'\202__INF0__=Ravion-V2 I.MX6 CPU"..., 16384) = 8192
write(2, "Read error on /boot/uboot.env: S"..., 39Read error on /boot/uboot.env: Success
) = 39
close(4)                                = 0
flock(3, LOCK_UN)                       = 0
close(3)                                = 0
exit_group(1)                           = ?
+++ exited with 1 +++
localhost ~ #
      
      





Linux. . . , — . -. :







openat(AT_FDCWD, "/boot/uboot.env", O_RDONLY) = 4
_llseek(4, 0, [0], SEEK_SET)            = 0
read(4, "n.'\202__INF0__=Ravion-V2 I.MX6 CPU"..., 16384) = 8192
write(2, "Read error on /boot/uboot.env: S"..., 39Read error on /boot/uboot.env: Success
) = 39
      
      





16384 (16K), 8192 (8K). . . . , 8192 . . 0, 0x4000 16384. 0x2000







# VFAT example
/boot/uboot.env 0x0000          0x2000
      
      





, . U-Boot’ . . . . () . — - . , . , . . .







— U-Boot. . , — . ? ( )? — 16 8. — ? , — .







localhost ~ # fw_printenv
__INF0__=Ravion-V2 I.MX6 CPU Module BSP package
__INF1__=Created: Alex A. Mihaylov AKA MinimumLaw, MinimumLaw@Rambler.Ru
[
]
boot_os=1
localhost ~ #
      
      





. fw_setenv .







localhost ~ # fw_setenv boot_os 0; fw_printenv boot_os
boot_os=0
      
      





? . , . , ?







. , U-Boot, , . . , strace read 8192. ? 8192 -1.







. , — , Das U-Boot . . , . . , . . . .







localhost ~ # fw_printenv --version
Compiled with U-Boot 2019.10
localhost ~ #
      
      





! (2020.10). . OpenSource . .







        lseek(fd, blockstart + block_seek, SEEK_SET);

        rc = read(fd, buf + processed, readlen);
        if (rc != readlen) {
            fprintf(stderr, "Read error on %s: %s\n",
                DEVNAME(dev), strerror(errno));
            return -1;
        }

      
      





. . . . . , . .







. «uboot.env»







localhost ~ # hexdump -C /boot/uboot.env
00000000  0a 43 62 eb 5f 5f 49 4e  46 30 5f 5f 3d 52 61 76  |.Cb.__INF0__=Rav|
00000010  69 6f 6e 2d 56 32 20 49  2e 4d 58 36 20 43 50 55  |ion-V2 I.MX6 CPU|
00000020  20 4d 6f 64 75 6c 65 20  42 53 50 20 70 61 63 6b  | Module BSP pack|
00000030  61 67 65 00 5f 5f 49 4e  46 31 5f 5f 3d 43 72 65  |age.__INF1__=Cre|
[...]
00000720  3d 71 70 00 76 65 6e 64  6f 72 3d 72 61 76 69 6f  |=qp.vendor=ravio|
00000730  6e 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |n...............|
00000740  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00002000
localhost ~ #
      
      





— , , . 1837 (0x7031 – 4) . 4 CRC32, =. . . . ( !) . ?







. . U-Boot . vfat . . OpenWRT . SPI-flash. . . . . , dataflash raw-NAND . .. , . .







. 
 . . . . , . . , . .







. , 
 , . : « , . .» , .







P.S.

CodeRushMerci encore pour l'invitation à Habr. Et oui, je veux toujours écrire sur quelque chose de sérieux - sur les compilateurs, sur la programmation sûre directement sur le matériel. Et la force est suffisante uniquement pour une lecture légÚre du vendredi. D'accord, supposons qu'un début a été fait. Un grand voyage commence toujours par un petit pas.








All Articles