Developers' corner

prpr

Well-Known Member
Why does ldd seemingly not take into account the LD_LIBRARY_PATH variable?
It seems to be using only /usr/lib and /lib, ignoring /mod/lib
 
It's like Jessica Rabbit ("I'm not bad, I'm just drawn that way").

Actually, I managed to reproduce this with some C source pulled from here.

Normally ldd is a script that wraps the loader, which for the CF is /lib/ld-uClibc.so.0. However there are uClibc configuration options that would break that, so they made a separate C program. Unfortunately it's the step where it uses the loader to load the executable and extract its dependencies that fails. I guess it's a bug-like feature of the uClibc loader build in the firmware.

You don't need to use a C program to demonstrate the issue:
Code:
# echo $LD_LIBRARY_PATH -- $PATH
/mod/lib:/lib:/usr/lib -- /mod/bin:/mod/bin/busybox:/bin:/sbin:/usr/bin
## CF package
# ldd /mod/bin/wget
        libuuid.so.1 => /usr/lib/libuuid.so.1 (0x2aab3000)
        libssl.so.1.1 => not found
        libcrypto.so.1.1 => not found
        libz.so.1 => /usr/lib/libz.so.1 (0x2aab8000)
        libpcre.so.1 => not found
        libc.so.0 => /lib/libc.so.0 (0x2aaca000)
        ld-uClibc.so.0 => /lib/ld-uClibc.so.0 (0x2aaa8000)
## just call the linker
# env LD_TRACE_LOADED_OBJECTS=1 ld /mod/bin/wget
        libz.so.1 => /mod/lib/libz.so.1 (0x2aab3000)
        libdl.so.0 => /lib/libdl.so.0 (0x2aadb000)
        libgcc_s.so.1 => /mod/lib/libgcc_s.so.1 (0x2aadf000)
        libc.so.0 => /lib/libc.so.0 (0x2ab1b000)
        ld-uClibc.so.0 => /lib/ld-uClibc.so.0 (0x2aaa8000)
## on-box build
# ./lddx /mod/bin/wget
        libuuid.so.1 => /usr/lib/libuuid.so.1 (0x2aab3000)
        libssl.so.1.1 => not found
        libcrypto.so.1.1 => not found
        libz.so.1 => /usr/lib/libz.so.1 (0x2aab8000)
        libpcre.so.1 => not found
        libc.so.0 => /lib/libc.so.0 (0x2aaca000)
        ld-uClibc.so.0 => /lib/ld-uClibc.so.0 (0x2aaa8000)
#
 
How does most of this work:
Code:
humax# grep -r "queue insert" /mod/webif/*
/mod/webif/html/browse/queue.jim:       set q [queue insert -hold $ts $xact]
/mod/webif/lib/queue.class:proc {queue insert} {args file action} {
/mod/webif/lib/auto/plugin/shrink/auto.hook:    queue insert $ts shrink
/mod/webif/lib/auto/plugin/mp3/auto.hook:       queue insert $ts mp3
/mod/webif/lib/auto/plugin/decrypt/auto.hook:   queue insert $ts decrypt
/mod/webif/lib/auto/plugin/mpg/auto.hook:       queue insert $ts mpg
/mod/webif/plugin/sweeper/auto.hook:            set q [{queue insert} -hold $ts $arg]
/mod/webif/plugin/thumbnails/catchup:   queue insert $ts thumb
/mod/webif/plugin/thumbnails/queue.hook:        queue insert $ts thumb
queue insert takes 3 parameters but only 2 are supplied, apart from those with -hold.
And why does sweeper use {queue insert} ? I guess it makes no difference.
 
proc {queue insert} {args file action} may look like 3 parameters but args is a special thing.

Cases:
  • set q [queue insert -hold $ts $xact] - args is {-hold}, file is $ts, action is $xact
  • queue insert $ts shrink - args is {}, file is $ts, action is shrink
  • queue insert $ts mp3 - args is {}, file is $ts, action is mp3
[etc]

The last bit, yes, as alluded to in the Jim OO doc that I linked elsewhere: if proc {a b} ... is defined and a is a class, the a b ... syntax is valid because the class's name lookup resolves b.

Otherwise you have to say {a b} ..., using the whole name of the proc which is otherwise rendered as "a b".
 
Can anyone suggest a regexp (or otherwise) to split this up properly please (the #1 line that is)?
Code:
Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
# 1  Extended offline    Self-test routine in progress 80%     52035         -
At the moment I believe the WebIf splits on double space, which obviously goes wrong with the percentage figure and the data ends up in the wrong columns, but sometimes the staus message is narrower than this example, so that has to work as well.
Other examples:
Code:
# 1  Selective offline   Completed without error       00%     28297         -
# 2  Selective offline   Completed: read failure       90%     28297         3886271808
# 3  Short offline       Completed without error       00%     28293         -
 
Using Jim regexes:
Code:
. set x "# 1  Extended offline    Self-test routine in progress 80%     52035"
. regexp -inline {\s*#\s*(\d+)\s*((?:[\s-]?\w[:;.,]?)+)\s+((?:[\s-]?\w[:;.,]?)+?)\s+(\d\d?)%\s+(\d+)} $x
{# 1  Extended offline    Self-test routine in progress 80%     52035} 1 {Extended offline} {Self-test routine in progress} 80 52035
So (* = captured):
optional space(s)
#
optional space(s)
digit(s)*
space(s)
string with alphanumerics optionally preceded by space or - and optionally followed by various punctuation :;.,*
space(s)
similar string but non-greedy match*
space(s)
digit(s)* NB matching 1-2 digits only assuming that 100% appears as 00%
%
space(s)
digit(s)*
 
Last edited:
regexp -inline {\s*#\s*(\d+)\s*((?:[\s-]?\w[:;.,]?)+)\s+((?:[\s-]?\w[:;.,]?)+?)\s+(\d\d?)%\s+(\d+)} $x
It blows my mind, but many thanks. I think I even managed to add another bit to pick up the LBA parameter!
regexp -inline {\s*#\s*(\d+)\s*((?:[\s-]?\w[:;.,]?)+)\s+((?:[\s-]?\w[:;.,]?)+?)\s+(\d\d?)%\s+(\d+)\s+([\d-]\d*)} $x
I hope I got it right anyway. It seems to work, but if you could just verify...
 
regexp -inline {\s*#\s*(\d+)\s*
I think that should be "\s+" at the end of this bit, to match your "space(s)" description, as otherwise it seems to be "optional space(s)".
It's these that get me:
Code:
((?:[\s-]?\w[:;.,]?)+)
((?:[\s-]?\w[:;.,]?)+?)
I understand the "[\s-]?\w[:;.,]?" bit, but the outer bit has me foxed (ahem!), particularly the ?: bit.
 
So, proposed version of actual code from /mod/webif/html/diag/disk.jim:
Code:
        if {[regexp -- {\s*#\s*(\d+)\s+((?:[\s-]?\w[:;.,]?)+)\s+((?:[\s-]?\w[:;.,]?)+?)\s+(\d\d?%)\s+(\d+)\s+([\d-]\d*)} \
                $line x id name status remaining when lba] == 0} continue
 
That is decidedly unreadable.

I don't understand what is wrong with simply splitting the string at columns 6, 26, 56, 64, 78.
 
Because things like the regexp have more chance of adapting if/when things change. Fixed offsets never adapt.
 
I think that should be "\s+" at the end of this bit

Yes, I think so.

I understand the "[\s-]?\w[:;.,]?" bit, but the outer bit has me foxed (ahem!), particularly the ?: bit.

The Jim manual says that (depending on build options) REs can be POSIX Extended or conform to a subset of Perl/Python/TCL Advanced REs.

In the latter case (?:pattern) brackets and matches the pattern like (pattern) but without capturing the match for pattern.

The additional tweak is that pattern+ matches the longest substring of 1 or or more pattern s ("greedy") but pattern+? matches the shortest substring ("non-greedy"). This is trivially the same as pattern on its own but not as part of a larger RE. Similarly ...?, ...* vs ...??, ...*?. In the RE that I suggested this is used to avoid matching the %-complete in the test result.

That is decidedly unreadable.

The ARE style of RE lets you put comments inline when the x RE flag is set:
Code:
(?x)
    \s*\#\s*                    # initial # (escaped in this syntax) with optional spaces
    (\d+)                       # capture the index number
    \s+
    ((?:[\s-]?\w[:;.,]?)+)      # capture the test name
    \s+
    ((?:[\s-]?\w[:;.,]?)+?)     # capture the test result (non-greedy)
    \s+
    (\d\d?%)                    # capture the %complete (or "(\d{1,2}%)" if you know how to escape the "{")
    \s+
    (\d+)                       # capture the lifetime
    \s+
    ([\d-]\d*)                  # capture the LBA (or just use "(\d+)?" to get an empty string when there's no number)
In Jim, I suppose you could emulate this by building the whole pattern up from individual strings, s/t like (the \ escapes are needed to avoid interpretation as array references):
Code:
set initial {\s*#\s*}            # initial # with optional spaces
set digits {\d+}
set spaces {\s+}
set text {(?:[\s-]?\w[:;.,]?)+}
set percentage {\d\d?%}
# `#{id} {name} {status} {remaining} {when} {lba}`
set pattern "$initial\($digits)$spaces\($text)$spaces\($text?)$spaces\($percentage)$spaces\($digits)?"
if {[regexp $pattern $line x id name status remaining when lba] == 0} continue

Otherwise:
Some people, when confronted with a problem, think “I know, I'll use regular expressions.” Now they have two problems.
 
Last edited:
Some people, when confronted with a problem, think “I know, I'll use regular expressions.” Now they have two problems.

Trying to understand Regex makes Jim/tcl look simple
 
Speaking of Jim, has anyone got any comments about what's going on here, as $(x) is supposed to be equivalent to [expr {x}]
Code:
. puts $(3-1)
2
. if { 2 == 2 } { puts true }
true
. if { $(3 - 1) == 2 } { puts true }
syntax error in expression: " $(3 - 1) == 2 "
[error] . if { [expr {3 - 1}] == 2 } { puts true }
true
.


. puts $(1)
1
. puts $(1 == 1)
1
. puts $(1 == $(1))
syntax error in expression: "(1 == $(1))"
[error] .  puts $(1 == [expr {1}])
1
 
Agree it doesn't make much sense, but it wouldn't be the first time there's a bug in a compiler/interpreter. Raise a ticket?
 
Back
Top