Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Using the writeup and gdb to find mistakes

by Aldebaran (Curate)
on Dec 18, 2024 at 01:09 UTC ( [id://11163226]=perlmeditation: print w/replies, xml ) Need Help??

using perl to pull values and files out of virtual spaces

Hello Monks,

I've been using the testing harness of perl to run a download and watermark script, and I've had quite a bit of success with it in testing. As I enter the monastery, I'm getting some false results that I want to explore using perl.

I got back to the literature and used Module::Starter, and now have something that could count as a distro. It's passed 12 rounds of testing, but I've made a big mistake because I backed off of stat'ing the file as an ultimate test of a success. Let me just start with perl as I present Frobnitz.pm:

package Acme::Frobnitz; use strict; use warnings; use IPC::System::Simple qw(capturex); use Cwd qw(abs_path); use File::Spec; use File::stat; use File::Basename; use FindBin; use POSIX qw(strftime); our $VERSION = '0.03';

That stack of modules just makes me happy to look at, like an xmas tree. And already version 3! IPC::System::Simple is a good choice for a grown-up's version of system() according to haukex's canonical treatment.

The methods wrap calls to bash:

sub new { my ($class) = @_; return bless {}, $class; } sub _get_script_path { my ($class, $script_name) = @_; # Resolve base directory dynamical +ly my $base_dir = abs_path("$FindBin::Bin/.."); # One level up from b +in my $script_path = File::Spec->catfile($base_dir, 'bin', $script_na +me); unless (-x $script_path) { die "Script $script_path does not exist or is not executable.\ +n"; } return $script_path; } sub download { my ($class, $hyperlink) = @_; die "No hyperlink provided.\n" unless $hyperlink; my $script_path = $class->_get_script_path("call_download.sh"); my $output; eval { $output = capturex("bash", $script_path, $hyperlink); }; if ($@) { die "Error executing $script_path with hyperlink $hyperlink: $ +@\n"; } return $output; }

I've been jammed up with version control, because I've been unable to reconstitute my gitlab circumstances (totally my fault). I take snapshots with

tar -czvf Acme-Frobnitz-Snapshot.tar.gz Acme-Frobnitz-Snapshot

They mostly look the same, but I port them back and forth from my mini-mac to a linux machine, with an obligatory-named usb as download target. That happens in the bash part. There's also the docker part and a python part. Much of this source deals with calling one from the other and returning values as well as files. I've wanted perl to "pull the cart" for the whole process, so that I could subject it to testing. LanX rightly laments the dearth of this in contemporaneous culture.

I haven't revealed my screw-up yet...this isn't easy...

I thought I passed the 12th round of testing but later came to realize I was firing blanks as to whether files ended up on the usb drive, and it brings me to a weird moment in testing, where I can use perl to figure out why...

Here's the new perl caller...this is what is "pulling the cart," whatever that means...

use strict; use warnings; use Acme::Frobnitz; my $frobnitz = Acme::Frobnitz->new(); # URL of the video to download my $video_url = "https://www.instagram.com/p/DDa_FxsNtTe/"; # Step 1: Download the video my $downloaded_file = $frobnitz->download($video_url); print "Downloaded video to: $downloaded_file\n"; # Step 2: Verify the downloaded file print "Verifying downloaded file...\n"; if ($frobnitz->verify_file($downloaded_file)) { print "File verification successful.\n"; } else { die "File verification failed. Aborting further processing.\n"; } # Step 3: Add watermark to the downloaded video my $final_file = $frobnitz->add_watermark($downloaded_file); print "Final watermarked video is at: $final_file\n";

I want to make a pure perl test here and use perl to figure out my privileges, and I'm using this. You should note that this is untested software from chatgpt today:

sub verify_file { my ($class, $file_path) = @_; die "File path not provided.\n" unless $file_path; my $abs_path = abs_path($file_path) // $file_path; if (-e $abs_path) { print "File exists: $abs_path\n"; # File size my $size = -s $abs_path; print "File size: $size bytes\n"; # File permissions my $permissions = sprintf "%04o", (stat($abs_path)->mode & 077 +77); print "File permissions: $permissions\n"; # Last modified time my $mtime = stat($abs_path)->mtime; print "Last modified: ", strftime("%Y-%m-%d %H:%M:%S", localti +me($mtime)), "\n"; # Owner and group my $uid = stat($abs_path)->uid; my $gid = stat($abs_path)->gid; print "Owner UID: $uid, Group GID: $gid\n"; return 1; # Verification success } else { print "File does not exist: $abs_path\n"; my $dir = dirname($abs_path); # Report directory details print "Inspecting directory: $dir\n"; opendir my $dh, $dir or die "Cannot open directory $dir: $!\n" +; my @files = readdir $dh; closedir $dh; print "Directory contents:\n"; foreach my $file (@files) { next if $file =~ /^\.\.?\$/; # Skip . and .. my $file_abs = File::Spec->catfile($dir, $file); my $type = -d $file_abs ? 'DIR ' : 'FILE'; my $size = -s $file_abs // 'N/A'; print "$type - $file (Size: $size bytes)\n"; } return 0; # Verification failed } }
Adding a new method:

Ok, let's use the toolchain.

(base) fritz@laptop:~/Desktop/Acme-Frobnitz-Snapshot$ ls Acme-Frobnitz-Snapshot.tar.gz Dockerfile Makefile MYMETA.yml + xt bin ignore.txt Makefile.PL README Changes lib MANIFEST requirements.t +xt conf logs MYMETA.json t (base) fritz@laptop:~/Desktop/Acme-Frobnitz-Snapshot$ perl Makefile.PL WARNING: Setting ABSTRACT via file 'lib/Acme/Frobnitz.pm' failed at /usr/share/perl/5.30/ExtUtils/MakeMaker.pm line 754. ...Q1) Why do I get this warning? Generating a Unix-style Makefile Writing Makefile for Acme::Frobnitz Writing MYMETA.yml and MYMETA.json (base) fritz@laptop:~/Desktop/Acme-Frobnitz-Snapshot$ make cp lib/Acme/._Frobnitz.pm.bak blib/lib/Acme/._Frobnitz.pm.bak cp lib/python_utils/watermarker2.py blib/lib/python_utils/watermarker2 +.py cp lib/python_utils/__pycache__/watermarker2.cpython-39.pyc blib/lib/p +ython_utils/__pycache__/watermarker2.cpython-39.pyc cp lib/python_utils/__pycache__/watermarker2.cpython-313.pyc blib/lib/ +python_utils/__pycache__/watermarker2.cpython-313.pyc ...^^^I see all these little barnacle files now... ...in 3 lines we cross into python logging... t/00-load.t ....... 1/? # Testing Acme::Frobnitz 0.03, Perl 5.030000, +/usr/bin/perl t/00-load.t ....... ok t/13.download.t ... 1/? 2024-12-17 06:28:26,320 - __main__ - INFO - At +tempting to create directory: E4B0-3FC22024-12-17/ 2024-12-17 06:28:26,320 - __main__ - INFO - Directory created or alrea +dy exists: E4B0-3FC22024-12-17/ 2024-12-17 06:28:26,321 - __main__ - INFO - Entering function: mask_me +tadata 2024-12-17 06:28:26,321 - downloader5 - INFO - Masking metadata 2024-12-17 06:28:26,321 - downloader5 - INFO - Received parameters for + metadata extraction: 2024-12-17 06:28:26,322 - downloader5 - INFO - download_path: E4B0-3FC +22024-12-17/ ...oh damn, that's the problem right there........................^^^^ +^^^^^^
The python part

Good heck. The progress I make with this is a function of effective logging. Continuing on STDOUT:

2024-12-17 06:28:36,493 - __main__ - INFO - Entering function: create_ +original_filename 2024-12-17 06:28:36,494 - downloader5 - INFO - Generated original file +name: E4B0-3FC22024-12-17/Rick_Astley_20091025.webm 2024-12-17 06:28:36,494 - __main__ - INFO - Entering function: downloa +d_video 2024-12-17 06:28:36,494 - downloader5 - INFO - Received parameters: do +wnload_video: 2024-12-17 06:28:36,494 - downloader5 - INFO - download_path: E4B0-3FC +22024-12-17/ ... again oop +s^^^ ..... 2024-12-17 06:28:36,496 - downloader5 - INFO - video_title: Rick_Astle +y_-_Never_Gonna_Give_You_Up_(Official_Music_Video) 2024-12-17 06:28:36,496 - downloader5 - INFO - video_date: 20091025 ...but here's the false positive: 2024-12-17 06:29:22,739 - downloader5 - INFO - Video download complete +d. 2024-12-17 06:29:22,742 - downloader5 - INFO - Download completed in 4 +6.24 seconds ...this part is one of my favorites: 2024-12-17 06:29:22,742 - __main__ - INFO - Entering function: store_p +arams_as_json 2024-12-17 06:29:22,743 - utilities1 - INFO - Params saved to JSON fil +e: E4B0-3FC22024-12-17/Rick_Astley_20091025.json 2024-12-17 06:29:22,743 - __main__ - INFO - Returning original filenam +e: E4B0-3FC22024-12-17/Rick_Astley_20091025.webm t/13.download.t ... ok ...should have failed... Result: PASS (base) fritz@laptop:~/Desktop/Acme-Frobnitz-Snapshot$ sudo make instal +l [sudo] password for fritz: Installing /usr/local/share/perl/5.30.0/Acme/Frobnitz.pm ...
The Debugger

Let's fire up the debugger, woohoo! This is why I can never leave perl:

(base) fritz@laptop:~/Desktop/Acme-Frobnitz-Snapshot$ perl -d bin/3.d +river.pl Loading DB routines from perl5db.pl version 1.55 Editor support available. Enter h or 'h h' for help, or 'man perldebug' for more help. main::(bin/3.driver.pl:5): my $frobnitz = Acme::Frobnitz->new(); DB<1>

Scout it out once with c, then set a break:

DB<1> R + Warning: some settings and command-line options may be lost! Loading DB routines from perl5db.pl version 1.55 Editor support available. Enter h or 'h h' for help, or 'man perldebug' for more help. main::(bin/3.driver.pl:5): my $frobnitz = Acme::Frobnitz->new(); DB<0> b 16 + DB<1>

Get in there...

2024-12-17 07:10:09,829 - downloader5 - INFO - Video download complete +d. 2024-12-17 07:10:09,832 - downloader5 - INFO - Download completed in 9 +.76 seconds 2024-12-17 07:10:09,832 - __main__ - INFO - Entering function: store_p +arams_as_json ... Verifying downloaded file... main::(bin/3.driver.pl:16): if ($frobnitz->verify_file($downloaded_ +file)) { DB<1> s + Acme::Frobnitz::verify_file(/usr/local/share/perl/5.30.0/Acme/Frobnitz +.pm:65): 65: my ($class, $file_path) = @_; DB<1> v + 62 } 63 64 sub verify_file { 65==> my ($class, $file_path) = @_; 66: die "File path not provided.\n" unless $file_path; 67 68: my $abs_path = abs_path($file_path) // $file_path; 69 70: if (-e $abs_path) { 71: print "File exists: $abs_path\n"; DB<1> s + Acme::Frobnitz::verify_file(/usr/local/share/perl/5.30.0/Acme/Frobnitz +.pm:66): 66: die "File path not provided.\n" unless $file_path; DB<1> s + Acme::Frobnitz::verify_file(/usr/local/share/perl/5.30.0/Acme/Frobnitz +.pm:68): 68: my $abs_path = abs_path($file_path) // $file_path; DB<1> s + Acme::Frobnitz::verify_file(/usr/local/share/perl/5.30.0/Acme/Frobnitz +.pm:70): 70: if (-e $abs_path) { DB<1> s + Unsuccessful stat on filename containing newline at /usr/local/share/p +erl/5.30.0/Acme/Frobnitz.pm line 70. at /usr/local/share/perl/5.30.0/Acme/Frobnitz.pm line 70. Acme::Frobnitz::verify_file(Acme::Frobnitz=HASH(0x5653a1900ad8), " +2024-12-17 00:09:54 - Detected OS: Linux\x{a}2024-12-17 00:09:54 "... +) called at bin/3.driver.pl line 16 Acme::Frobnitz::verify_file(/usr/local/share/perl/5.30.0/Acme/Frobnitz +.pm:92): 92: print "File does not exist: $abs_path\n"; DB<1> p $abs_path + 2024-12-17 00:09:54 - Detected OS: Linux 2024-12-17 00:09:54 - Ensuring Docker is running... 2024-12-17 00:09:54 - Docker is already running. 2024-12-17 00:09:54 - Loading configuration from /home/fritz/Desktop/A +cme-Frobnitz-Snapshot/bin/../conf/app_config.json... 2024-12-17 00:09:54 - Target USB mount name from config: E4B0-3FC2 2024-12-17 00:09:54 - Detected USB mount point: /media/fritz/E4B0-3FC2 2024-12-17 00:09:54 - Attempting to create directory: /media/fritz/E4B +0-3FC2/2024-12-17/ 2024-12-17 00:09:54 - Directory created or already exists: /media/frit +z/E4B0-3FC2/2024-12-17/ 2024-12-17 00:09:54 - Docker image 'my_dl:latest' found. 2024-12-17 00:09:54 - Running Docker with the specified volume and con +fig path... 2024-12-17 00:10:13 - File validation successful: [Instagram] Extracti +ng URL: https://www.instagram.com/p/DDa_FxsNtTe/ Adding lib_path to sys.path: /app/bin/../lib/python_utils [Instagram] DDa_FxsNtTe: Setting up session [Instagram] DDa_FxsNtTe: Downloading JSON metadata [Instagram] Extracting URL: https://www.instagram.com/p/DDa_FxsNtTe/ [Instagram] DDa_FxsNtTe: Setting up session [Instagram] DDa_FxsNtTe: Downloading JSON metadata [info] DDa_FxsNtTe: Downloading 1 format(s): dash-560108753314303v+das +h-1118756702933936ad [download] Destination: E4B0-3FC2/2024-12-17/Tim_Ballard_20241211.fdas +h-560108753314303v.mp4 [download] 100% of 37.69MiB in 00:00:07 at 5.24MiB/s:00 [download] Destination: E4B0-3FC2/2024-12-17/Tim_Ballard_20241211.fdas +h-1118756702933936ad.m4a [download] 100% of 1.14MiB in 00:00:00 at 2.32MiB/s:00 [Merger] Merging formats into "E4B0-3FC2/2024-12-17/Tim_Ballard_202412 +11.mp4" Deleting original file E4B0-3FC2/2024-12-17/Tim_Ballard_20241211.fdash +-1118756702933936ad.m4a (pass -k to keep) Deleting original file E4B0-3FC2/2024-12-17/Tim_Ballard_20241211.fdash +-560108753314303v.mp4 (pass -k to keep) E4B0-3FC2/2024-12-17/Tim_Ballard_20241211.mp4 DB<2>

Q3) What the damn heck is that?

Alright, well I found enough things wrong in there to need to go back and fix. It's funny how you find stuff during the writeup. Without a githost I don't have a means to provide an SSCCE without violating the first S.

For creating the virtual environment with some diagnostics, I've been using this Dockerfile, which has a nice amount of tread on it:

# Start with a base image FROM python:3.10-slim # Set PYTHONPATH to include the python_utils directory ENV PYTHONPATH="/app/lib/python_utils:/app/lib" # Update apt repository and install necessary dependencies, including +ffmpeg RUN apt-get update && \ apt-get install -y --no-install-recommends \ ffmpeg \ python3 \ python3-pip && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* # Set the working directory WORKDIR /app # Copy all files into the Docker image COPY bin /app/bin COPY lib /app/lib COPY conf /app/conf COPY requirements.txt /app/requirements.txt COPY Dockerfile /app/Dockerfile # Install Python dependencies RUN pip3 install --upgrade pip && pip3 install -r requirements.txt --r +oot-user-action=ignore # Debug: List all files in /app and verify the content of lib/python_u +tils RUN ls -la /app && ls -la /app/lib && ls -la /app/lib/python_utils # Debug: Verify requirements.txt is in the container RUN cat /app/requirements.txt # Debug: Verify Python environment and MoviePy installation RUN python3 -c "import sys; print(sys.version)" RUN python3 -c "import site; print(site.getsitepackages())" RUN python3 -c "import moviepy; print('MoviePy is correctly installed' +)"

The image is minimal. Execution is done from within bash:

original_filename=$(docker run --rm \ -e PYTHONPATH="/app/lib/python_utils:/app/lib" \ -v "$Config_Path":/app/conf/app_config.json \ -v "$usb_mount_point":"$usb_mount_point" \ my_dl python3 /app/bin/call_download.py "$1")

Docker isn't the easiest thing to get values out of, and this worked. Glad for any critical comments about the code. I gotta figure out how I threw a monkey wrench into what used to work, and I don't find that wrench without gdb. I'm not aware of a python equivalent.

May your solstice be filled with perl

Replies are listed 'Best First'.
Re: Using the writeup and gdb to find mistakes
by etj (Priest) on Dec 18, 2024 at 09:05 UTC
    You know that perl -d and gdb are utterly different things, and that you didn't actually use gdb at all here - right?
      You know that perl -d and gdb are utterly different things, and that you didn't actually use gdb at all here - right?

      No, etj, I didn't when I wrote it, but now that my debugger memory is engaged I realize I've conflated C and perl. What can I say, when I leak wrongness, it comes out C?

      2024-12-20 19:14:46,846 - Starting watermarking process... 2024-12-20 19:26:50,578 - Watermarked video created successfully: /med +ia/fritz/E4B0-3FC2/2024-12-20/Tim_Ballard_20241211_1_watermarked.mp4 Final watermarked video is at: Moviepy - Building video /media/fritz/E +4B0-3FC2/2024-12-20/Tim_Ballard_20241211_1_watermarked.mp4. MoviePy - Writing audio in Tim_Ballard_20241211_1_watermarkedTEMP_MPY_ +wvf_snd.mp4 MoviePy - Done. Moviepy - Writing video /media/fritz/E4B0-3FC2/2024-12-20/Tim_Ballard_ +20241211_1_watermarked.mp4 Moviepy - Done ! Moviepy - video ready /media/fritz/E4B0-3FC2/2024-12-20/Tim_Ballard_20 +241211_1_watermarked.mp4 /media/fritz/E4B0-3FC2/2024-12-20/Tim_Ballard_20241211_1_watermarked.m +p4 Debugged program terminated. Use q to quit or R to restart, use o inhibit_exit to avoid stopping after program termination, h q, h R or h o to get additional info. DB<1>

      Finally got it wrangled with perl -d....

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://11163226]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (3)
As of 2025-07-13 05:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.