Fehler: Erfolg und was dagegen zu tun ist

Bild







Alle unerfahrenen Programmierer werden immer über die Wichtigkeit einer korrekten Fehlerberichterstattung informiert. Sie sagen immer, wenn das Programm etwas nicht getan hat, sollte es klar und eindeutig sagen, warum es passiert ist. Sie sprechen darüber, wie wichtig es ist, den Rückgabewert der aufgerufenen Funktionen zu steuern. Darüber hinaus haben sogar Compiler gelernt, Warnungen auszugeben, wenn der von bestimmten Funktionen zurückgegebene Wert ignoriert wird. Ich muss sagen, dass die Bedeutung der Fehlerbehandlung durch moderne Programmierer akzeptiert wird. Manchmal führt dies zu amüsanten Vorfällen, wie im KDPV ( hier aufgenommen)). Im wirklichen Leben musste ich mich mehrmals mit solch seltsamen Diagnosemeldungen auseinandersetzen. Ich möchte Ihnen über den letzteren Fall und die Methoden zur Überwindung einer solchen Diagnose berichten. Wenn Sie interessiert sind, sind Sie unter Katze willkommen. Erfahrene Programmierer werden sicherlich nichts Neues für sich entdecken, aber sie werden definitiv in der Lage sein, über Softwareentwicklung zu philosophieren.







FĂĽr diejenigen, die "viele Buchstaben" haben
  • Es ist wichtig, die von read () zurĂĽckgegebenen Werte korrekt zu behandeln.
  • ( OpenSource )
  • - . « »


Im Allgemeinen habe ich traurige Neuigkeiten. Es werden keine Bilder mehr angezeigt. Wir werden auf die Ebene der Linux-Systemkonsole gehen und dort leben. In diesem Fall werden wir uns freuen. Für das Projekt, mit dem gearbeitet werden soll, ist ein ziemlich bekannter U-Boot-Loader . Open Source-Projekt, das von DENX Software Engineering unterstützt wird... Daher werden wir froh sein, dass wir eine Konsole und eine Systemumgebung haben und das Leben im Allgemeinen in vollem Gange ist. Denn bei der Arbeit mit diesem Projekt gibt es in der Regel nichts Vergleichbares - kontinuierliche Speicherbereiche, Übertragung von Bytes von einem Ort zum anderen und Warten auf die Bereitschaft der Peripherie. Übrigens ist dieser Teil bereits abgeschlossen und es gibt einen ziemlich funktionierenden Bootloader für die Hardware. Es ist an der Zeit, mit Dekorationen zu beginnen, mit denen Anwendungsprogrammierer den Systemstartprozess irgendwie beeinflussen können. Nichts ist ein gutes Zeichen für Probleme. Das Problem wurde vor langer Zeit gelöst und wird von so beliebten Projekten wie OpenWRT und vielen anderen, etwas weniger bekannten, aktiv genutzt.







. 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.

CodeRushNochmals vielen Dank für die Einladung nach Habr. Und ja, ich möchte immer über etwas Ernstes schreiben - über Compiler, über sicheres Programmieren direkt auf Hardware. Und die Kraft reicht nur für leichtes Lesen am Freitag. Okay, nehmen wir an, dass ein Anfang gemacht wurde. Eine große Reise beginnt immer mit einem kleinen Schritt.








All Articles