100% found this document useful (1 vote)
25 views

Python Debugging For Ai Machine Learning And Cloud Computing A Patternoriented Approach Dmitry Vostokov download

The document is a comprehensive guide on Python debugging specifically tailored for AI, machine learning, and cloud computing, authored by Dmitry Vostokov. It covers fundamental vocabulary, pattern-oriented debugging techniques, and various debugging patterns including diagnostics, analysis, implementation, and architecture. The book also includes case studies and practical examples to enhance understanding and application of debugging in Python.

Uploaded by

chullidetsy
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
25 views

Python Debugging For Ai Machine Learning And Cloud Computing A Patternoriented Approach Dmitry Vostokov download

The document is a comprehensive guide on Python debugging specifically tailored for AI, machine learning, and cloud computing, authored by Dmitry Vostokov. It covers fundamental vocabulary, pattern-oriented debugging techniques, and various debugging patterns including diagnostics, analysis, implementation, and architecture. The book also includes case studies and practical examples to enhance understanding and application of debugging in Python.

Uploaded by

chullidetsy
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 77

Python Debugging For Ai Machine Learning And

Cloud Computing A Patternoriented Approach


Dmitry Vostokov download

https://ebookbell.com/product/python-debugging-for-ai-machine-
learning-and-cloud-computing-a-patternoriented-approach-dmitry-
vostokov-54291598

Explore and download more ebooks at ebookbell.com


Here are some recommended products that we believe you will be
interested in. You can click the link to download.

Python Debugging Handbook Zimmerman Rl

https://ebookbell.com/product/python-debugging-handbook-zimmerman-
rl-10920670

Pro Python Best Practices Debugging Testing And Maintenance 1st


Edition Kristian Rother

https://ebookbell.com/product/pro-python-best-practices-debugging-
testing-and-maintenance-1st-edition-kristian-rother-53582336

Python Logging Auditing And Debugging Through Driscoll Michael

https://ebookbell.com/product/python-logging-auditing-and-debugging-
through-driscoll-michael-57677574

Debugging Machine Learning Models With Python Develop Highperformance


Lowbias And Explainable Machine Learning And Deep Learning Models
Teamira Ali Madani

https://ebookbell.com/product/debugging-machine-learning-models-with-
python-develop-highperformance-lowbias-and-explainable-machine-
learning-and-deep-learning-models-teamira-ali-madani-52016060
Debugging Machine Learning Models With Python Develop Highperformance
Lowbias And Explainable Machine Learning And Deep Learning Models
Madani

https://ebookbell.com/product/debugging-machine-learning-models-with-
python-develop-highperformance-lowbias-and-explainable-machine-
learning-and-deep-learning-models-madani-56422740

Debugging Machine Learning Models With Python Madani Alimackinnon

https://ebookbell.com/product/debugging-machine-learning-models-with-
python-madani-alimackinnon-58948008

Advanced Apple Debugging Reverse Engineering Exploring Apple Code


Through Llbd Python And Dtrace 3rd Edition Raywenderlich Tutorial Team

https://ebookbell.com/product/advanced-apple-debugging-reverse-
engineering-exploring-apple-code-through-llbd-python-and-dtrace-3rd-
edition-raywenderlich-tutorial-team-38464028

Advanced Apple Debugging Reverse Engineering Fourth Edition Exploring


Apple Code Through Lldb Python Dtrace Kodeco Team

https://ebookbell.com/product/advanced-apple-debugging-reverse-
engineering-fourth-edition-exploring-apple-code-through-lldb-python-
dtrace-kodeco-team-51197028

Debunking Seven Terrorism Myths Using Statistics 1st Edition Andre


Python

https://ebookbell.com/product/debunking-seven-terrorism-myths-using-
statistics-1st-edition-andre-python-12059464
Python Debugging for AI,
Machine Learning, and
Cloud Computing
A Pattern-Oriented Approach

Dmitry Vostokov
Python Debugging for AI, Machine Learning, and Cloud Computing:
A Pattern-Oriented Approach
Dmitry Vostokov
Dalkey, Dublin, Ireland

ISBN-13 (pbk): 978-1-4842-9744-5 ISBN-13 (electronic): 978-1-4842-9745-2


https://doi.org/10.1007/978-1-4842-9745-2

Copyright © 2024 by Dmitry Vostokov


This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the
material is concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation,
broadcasting, reproduction on microfilms or in any other physical way, and transmission or information
storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar methodology now
known or hereafter developed.
Trademarked names, logos, and images may appear in this book. Rather than use a trademark symbol with
every occurrence of a trademarked name, logo, or image we use the names, logos, and images only in an
editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the
trademark.
The use in this publication of trade names, trademarks, service marks, and similar terms, even if they are not
identified as such, is not to be taken as an expression of opinion as to whether or not they are subject to
proprietary rights.
While the advice and information in this book are believed to be true and accurate at the date of publication,
neither the authors nor the editors nor the publisher can accept any legal responsibility for any errors or
omissions that may be made. The publisher makes no warranty, express or implied, with respect to the
material contained herein.
Managing Director, Apress Media LLC: Welmoed Spahr
Acquisitions Editor: Celestin Suresh John
Development Editor: James Markham
Editorial Assistant: Gryffin Winkler
Copy Editor: Mary Behr
Cover designed by eStudioCalamar
Cover image designed by Igor Mamaev on pixabay
Distributed to the book trade worldwide by Springer Science+Business Media New York, 1 New York Plaza,
Suite 4600, New York, NY 10004-1562, USA. Phone 1-800-SPRINGER, fax (201) 348-4505, e-mail orders-ny@
springer-sbm.com, or visit www.springeronline.com. Apress Media, LLC is a California LLC and the sole
member (owner) is Springer Science + Business Media Finance Inc (SSBM Finance Inc). SSBM Finance Inc
is a Delaware corporation.
For information on translations, please e-mail booktranslations@springernature.com; for reprint,
paperback, or audio rights, please e-mail bookpermissions@springernature.com.
Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook versions and
licenses are also available for most titles. For more information, reference our Print and eBook Bulk Sales
web page at www.apress.com/bulk-sales.
Any source code or other supplementary material referenced by the author in this book is available to
readers on GitHub. For more detailed information, please visit https://www.apress.com/gp/services/
source-code.
Paper in this product is recyclable
To Ekaterina, Alexandra, Kirill, and Maria
Table of Contents
About the Author���������������������������������������������������������������������������������������������������xvii

About the Technical Reviewer��������������������������������������������������������������������������������xix

Introduction������������������������������������������������������������������������������������������������������������xxi

Chapter 1: Fundamental Vocabulary������������������������������������������������������������������������ 1


Process����������������������������������������������������������������������������������������������������������������������������������������� 1
Thread������������������������������������������������������������������������������������������������������������������������������������������� 4
Stack Trace (Backtrace, Traceback)���������������������������������������������������������������������������������������������� 6
Symbol Files�������������������������������������������������������������������������������������������������������������������������������� 12
Module���������������������������������������������������������������������������������������������������������������������������������������� 14
Memory Dump���������������������������������������������������������������������������������������������������������������������������� 16
Crash������������������������������������������������������������������������������������������������������������������������������������������� 17
Hang�������������������������������������������������������������������������������������������������������������������������������������������� 18
Summary������������������������������������������������������������������������������������������������������������������������������������ 20

Chapter 2: Pattern-Oriented Debugging����������������������������������������������������������������� 21


The History of the Idea���������������������������������������������������������������������������������������������������������������� 21
Patterns and Analysis Patterns��������������������������������������������������������������������������������������������������� 22
Development Process����������������������������������������������������������������������������������������������������������������� 22
Development Patterns����������������������������������������������������������������������������������������������������������������� 23
Debugging Process and Patterns������������������������������������������������������������������������������������������������ 24
Elementary Diagnostics Patterns������������������������������������������������������������������������������������������ 25
Debugging Analysis Patterns������������������������������������������������������������������������������������������������� 26
Debugging Architecture Patterns������������������������������������������������������������������������������������������ 26
Debugging Design Patterns��������������������������������������������������������������������������������������������������� 26

v
Table of Contents

Debugging Implementation Patterns������������������������������������������������������������������������������������� 27


Debugging Usage Patterns���������������������������������������������������������������������������������������������������� 27
Debugging Presentation Patterns������������������������������������������������������������������������������������������ 27
Summary������������������������������������������������������������������������������������������������������������������������������������ 28

Chapter 3: Elementary Diagnostics Patterns���������������������������������������������������������� 29


Functional Patterns��������������������������������������������������������������������������������������������������������������������� 30
Use-Case Deviation��������������������������������������������������������������������������������������������������������������� 30
Non-Functional Patterns������������������������������������������������������������������������������������������������������������� 30
Crash������������������������������������������������������������������������������������������������������������������������������������� 30
Hang�������������������������������������������������������������������������������������������������������������������������������������� 31
Counter Value������������������������������������������������������������������������������������������������������������������������ 33
Error Message����������������������������������������������������������������������������������������������������������������������� 34
Summary������������������������������������������������������������������������������������������������������������������������������������ 34

Chapter 4: Debugging Analysis Patterns���������������������������������������������������������������� 35


Paratext��������������������������������������������������������������������������������������������������������������������������������������� 36
State Dump��������������������������������������������������������������������������������������������������������������������������������� 37
Counter Value������������������������������������������������������������������������������������������������������������������������������ 37
Stack Trace Patterns������������������������������������������������������������������������������������������������������������������� 37
Stack Trace���������������������������������������������������������������������������������������������������������������������������� 38
Runtime Thread��������������������������������������������������������������������������������������������������������������������� 38
Managed Stack Trace������������������������������������������������������������������������������������������������������������ 38
Source Stack Trace���������������������������������������������������������������������������������������������������������������� 41
Stack Trace Collection����������������������������������������������������������������������������������������������������������� 41
Stack Trace Set���������������������������������������������������������������������������������������������������������������������� 41
Exception Patterns���������������������������������������������������������������������������������������������������������������������� 41
Managed Code Exception������������������������������������������������������������������������������������������������������ 42
Nested Exception������������������������������������������������������������������������������������������������������������������� 42
Exception Stack Trace����������������������������������������������������������������������������������������������������������� 43
Software Exception��������������������������������������������������������������������������������������������������������������� 43

vi
Table of Contents

Module Patterns�������������������������������������������������������������������������������������������������������������������������� 43
Module Collection������������������������������������������������������������������������������������������������������������������ 44
Not My Version���������������������������������������������������������������������������������������������������������������������� 47
Exception Module������������������������������������������������������������������������������������������������������������������ 47
Origin Module������������������������������������������������������������������������������������������������������������������������ 47
Thread Patterns�������������������������������������������������������������������������������������������������������������������������� 47
Spiking Thread����������������������������������������������������������������������������������������������������������������������� 48
Active Thread������������������������������������������������������������������������������������������������������������������������� 48
Blocked Thread���������������������������������������������������������������������������������������������������������������������� 48
Blocking Module�������������������������������������������������������������������������������������������������������������������� 48
Synchronization Patterns������������������������������������������������������������������������������������������������������������ 48
Wait Chain����������������������������������������������������������������������������������������������������������������������������� 49
Deadlock�������������������������������������������������������������������������������������������������������������������������������� 49
Livelock��������������������������������������������������������������������������������������������������������������������������������� 49
Memory Consumption Patterns�������������������������������������������������������������������������������������������������� 49
Memory Leak������������������������������������������������������������������������������������������������������������������������� 49
Handle Leak��������������������������������������������������������������������������������������������������������������������������� 49
Case Study���������������������������������������������������������������������������������������������������������������������������������� 50
Summary������������������������������������������������������������������������������������������������������������������������������������ 64

Chapter 5: Debugging Implementation Patterns���������������������������������������������������� 65


Overview of Patterns������������������������������������������������������������������������������������������������������������������� 66
Break-Ins������������������������������������������������������������������������������������������������������������������������������� 66
Code Breakpoint�������������������������������������������������������������������������������������������������������������������� 70
Code Trace����������������������������������������������������������������������������������������������������������������������������� 71
Scope������������������������������������������������������������������������������������������������������������������������������������� 73
Variable Value������������������������������������������������������������������������������������������������������������������������ 75
Type Structure����������������������������������������������������������������������������������������������������������������������� 76
Breakpoint Action������������������������������������������������������������������������������������������������������������������ 78
Usage Trace��������������������������������������������������������������������������������������������������������������������������� 81

vii
Table of Contents

Case Study���������������������������������������������������������������������������������������������������������������������������������� 81
Elementary Diagnostics Patterns������������������������������������������������������������������������������������������ 81
Debugging Analysis Patterns������������������������������������������������������������������������������������������������� 81
Debugging Implementation Patterns������������������������������������������������������������������������������������� 82
Summary������������������������������������������������������������������������������������������������������������������������������������ 89

Chapter 6: IDE Debugging in the Cloud������������������������������������������������������������������� 91


Visual Studio Code���������������������������������������������������������������������������������������������������������������������� 91
WSL Setup����������������������������������������������������������������������������������������������������������������������������� 91
Cloud SSH Setup������������������������������������������������������������������������������������������������������������������� 92
Case Study����������������������������������������������������������������������������������������������������������������������������� 96
Summary���������������������������������������������������������������������������������������������������������������������������������� 109

Chapter 7: Debugging Presentation Patterns������������������������������������������������������� 111


Python Debugging Engines������������������������������������������������������������������������������������������������������� 111
Case Study�������������������������������������������������������������������������������������������������������������������������������� 112
Suggested Presentation Patterns��������������������������������������������������������������������������������������������� 125
Summary���������������������������������������������������������������������������������������������������������������������������������� 125

Chapter 8: Debugging Architecture Patterns�������������������������������������������������������� 127


The Where? Category���������������������������������������������������������������������������������������������������������������� 128
In Papyro����������������������������������������������������������������������������������������������������������������������������� 129
In Vivo���������������������������������������������������������������������������������������������������������������������������������� 129
In Vitro��������������������������������������������������������������������������������������������������������������������������������� 129
In Silico�������������������������������������������������������������������������������������������������������������������������������� 129
In Situ���������������������������������������������������������������������������������������������������������������������������������� 130
Ex Situ��������������������������������������������������������������������������������������������������������������������������������� 130
The When? Category����������������������������������������������������������������������������������������������������������������� 130
Live�������������������������������������������������������������������������������������������������������������������������������������� 130
JIT���������������������������������������������������������������������������������������������������������������������������������������� 131
Postmortem������������������������������������������������������������������������������������������������������������������������� 131
The What? Category������������������������������������������������������������������������������������������������������������������ 131
Code������������������������������������������������������������������������������������������������������������������������������������ 131

viii
Table of Contents

Data������������������������������������������������������������������������������������������������������������������������������������� 132
Interaction��������������������������������������������������������������������������������������������������������������������������� 132
The How? Category������������������������������������������������������������������������������������������������������������������� 132
Software Narrative�������������������������������������������������������������������������������������������������������������� 132
Software State��������������������������������������������������������������������������������������������������������������������� 132
Summary���������������������������������������������������������������������������������������������������������������������������������� 133

Chapter 9: Debugging Design Patterns����������������������������������������������������������������� 135


CI Build Case Study������������������������������������������������������������������������������������������������������������������� 137
Elementary Diagnostics������������������������������������������������������������������������������������������������������� 137
Analysis������������������������������������������������������������������������������������������������������������������������������� 138
Architecture������������������������������������������������������������������������������������������������������������������������� 138
Design��������������������������������������������������������������������������������������������������������������������������������� 138
Implementation������������������������������������������������������������������������������������������������������������������� 138
Data Processing Case Study����������������������������������������������������������������������������������������������������� 138
Elementary Diagnostics������������������������������������������������������������������������������������������������������� 139
Analysis������������������������������������������������������������������������������������������������������������������������������� 139
Architecture������������������������������������������������������������������������������������������������������������������������� 146
Design��������������������������������������������������������������������������������������������������������������������������������� 147
Implementation������������������������������������������������������������������������������������������������������������������� 147
Summary���������������������������������������������������������������������������������������������������������������������������������� 147

Chapter 10: Debugging Usage Patterns���������������������������������������������������������������� 149


Exact Sequence������������������������������������������������������������������������������������������������������������������������ 150
Scripting������������������������������������������������������������������������������������������������������������������������������������ 150
Debugger Extension������������������������������������������������������������������������������������������������������������������ 151
Abstract Command������������������������������������������������������������������������������������������������������������������� 152
Space Translation���������������������������������������������������������������������������������������������������������������������� 152
Lifting���������������������������������������������������������������������������������������������������������������������������������������� 152
Gestures������������������������������������������������������������������������������������������������������������������������������������ 153
Summary���������������������������������������������������������������������������������������������������������������������������������� 154

ix
Table of Contents

Chapter 11: Case Study: Resource Leaks������������������������������������������������������������� 155


Elementary Diagnostics������������������������������������������������������������������������������������������������������������ 155
Debugging Analysis������������������������������������������������������������������������������������������������������������������� 156
Debugging Architecture������������������������������������������������������������������������������������������������������������ 160
Debugging Implementation������������������������������������������������������������������������������������������������������� 161
Summary���������������������������������������������������������������������������������������������������������������������������������� 166

Chapter 12: Case Study: Deadlock������������������������������������������������������������������������ 167


Elementary Diagnostics������������������������������������������������������������������������������������������������������������ 167
Debugging Analysis������������������������������������������������������������������������������������������������������������������� 168
Debugging Architecture������������������������������������������������������������������������������������������������������������ 171
Exceptions and Deadlocks�������������������������������������������������������������������������������������������������������� 173
Summary���������������������������������������������������������������������������������������������������������������������������������� 174

Chapter 13: Challenges of Python Debugging in Cloud Computing���������������������� 175


Complex Distributed Systems��������������������������������������������������������������������������������������������������� 175
Granularity of Services�������������������������������������������������������������������������������������������������������� 176
Communication Channels Overhead����������������������������������������������������������������������������������� 176
Inter-Service Dependencies������������������������������������������������������������������������������������������������ 177
Layers of Abstraction���������������������������������������������������������������������������������������������������������������� 178
Opaque Managed Services�������������������������������������������������������������������������������������������������� 178
Serverless and Function as a Service��������������������������������������������������������������������������������� 178
Container Orchestration Platforms�������������������������������������������������������������������������������������� 179
Continuous Integration/Continuous Deployment����������������������������������������������������������������������� 179
Pipeline Failures������������������������������������������������������������������������������������������������������������������ 179
Rollbacks and Versioning���������������������������������������������������������������������������������������������������� 180
Immutable Infrastructure����������������������������������������������������������������������������������������������������� 181
Diversity of Cloud Service Models�������������������������������������������������������������������������������������������� 181
Infrastructure as a Service�������������������������������������������������������������������������������������������������� 181
Platform as a Service���������������������������������������������������������������������������������������������������������� 182
Software as a Service��������������������������������������������������������������������������������������������������������� 182

x
Table of Contents

Evolving Cloud Platforms���������������������������������������������������������������������������������������������������������� 182


Adapting to Changes����������������������������������������������������������������������������������������������������������� 183
Staying Updated������������������������������������������������������������������������������������������������������������������ 183
Environment Parity�������������������������������������������������������������������������������������������������������������������� 184
Library and Dependency Disparities������������������������������������������������������������������������������������ 184
Configuration Differences���������������������������������������������������������������������������������������������������� 184
Underlying Infrastructure Differences��������������������������������������������������������������������������������� 185
Service Variabilities������������������������������������������������������������������������������������������������������������� 185
Limited Visibility������������������������������������������������������������������������������������������������������������������������ 185
Transient Resources������������������������������������������������������������������������������������������������������������ 185
Log Management����������������������������������������������������������������������������������������������������������������� 186
Monitoring and Alerting������������������������������������������������������������������������������������������������������� 187
Latency and Network Issues����������������������������������������������������������������������������������������������������� 187
Network Instabilities������������������������������������������������������������������������������������������������������������ 188
Service-to-Service Communication������������������������������������������������������������������������������������ 188
Resource Leaks and Performance��������������������������������������������������������������������������������������� 188
Resource Starvation������������������������������������������������������������������������������������������������������������ 189
Concurrency Issues������������������������������������������������������������������������������������������������������������������� 189
Race Conditions������������������������������������������������������������������������������������������������������������������� 190
Deadlocks���������������������������������������������������������������������������������������������������������������������������� 190
Security and Confidentiality������������������������������������������������������������������������������������������������������ 190
Debugger Access Control Restrictions�������������������������������������������������������������������������������� 190
Sensitive Data Exposure������������������������������������������������������������������������������������������������������ 191
Limited Access�������������������������������������������������������������������������������������������������������������������� 192
Cost Implications���������������������������������������������������������������������������������������������������������������������� 192
Extended Sessions�������������������������������������������������������������������������������������������������������������� 192
Resource Provisioning and Deprovisioning������������������������������������������������������������������������� 192
Data Transfer and Storage Fees������������������������������������������������������������������������������������������ 192
State Management�������������������������������������������������������������������������������������������������������������������� 193
Stateful Services����������������������������������������������������������������������������������������������������������������� 193
Data Volume������������������������������������������������������������������������������������������������������������������������ 193

xi
Table of Contents

Limited Tooling Compatibility���������������������������������������������������������������������������������������������������� 193


Versioning Issues���������������������������������������������������������������������������������������������������������������������� 193
Deprecations and Changes�������������������������������������������������������������������������������������������������� 193
SDK and Library Updates����������������������������������������������������������������������������������������������������� 194
Real-time Debugging and User Experience������������������������������������������������������������������������������ 194
External Service Dependencies������������������������������������������������������������������������������������������������ 194
Dependency Failures����������������������������������������������������������������������������������������������������������� 194
Rate Limiting and Quotas���������������������������������������������������������������������������������������������������� 194
Asynchronous Operations��������������������������������������������������������������������������������������������������������� 194
Flow Tracking���������������������������������������������������������������������������������������������������������������������� 195
Error Propagation���������������������������������������������������������������������������������������������������������������� 195
Scaling and Load Challenges���������������������������������������������������������������������������������������������������� 195
Load-Based Issues�������������������������������������������������������������������������������������������������������������� 195
Resource Contention����������������������������������������������������������������������������������������������������������� 195
Multi-Tenancy Issues���������������������������������������������������������������������������������������������������������������� 196
Resource Contention����������������������������������������������������������������������������������������������������������� 196
Data Security����������������������������������������������������������������������������������������������������������������������� 196
Reliability and Redundancy Issues������������������������������������������������������������������������������������������� 196
Service Failures������������������������������������������������������������������������������������������������������������������� 196
Data Durability��������������������������������������������������������������������������������������������������������������������� 197
Summary���������������������������������������������������������������������������������������������������������������������������������� 197

Chapter 14: Challenges of Python Debugging in AI and Machine Learning���������� 199


The Nature of Defects in AI/ML������������������������������������������������������������������������������������������������� 199
Complexity and Abstraction Layers������������������������������������������������������������������������������������� 200
Non-Determinism and Reproducibility�������������������������������������������������������������������������������� 200
Large Datasets�������������������������������������������������������������������������������������������������������������������� 200
High-Dimensional Data�������������������������������������������������������������������������������������������������������� 200
Long Training Times������������������������������������������������������������������������������������������������������������� 201
Real-Time Operation������������������������������������������������������������������������������������������������������������ 201
Model Interpretability���������������������������������������������������������������������������������������������������������� 201

xii
Table of Contents

Hardware Challenges���������������������������������������������������������������������������������������������������������� 201


Version Compatibility and Dependency Hell������������������������������������������������������������������������ 201
Data Defects����������������������������������������������������������������������������������������������������������������������������� 202
Inconsistent and Noisy Data������������������������������������������������������������������������������������������������ 202
Data Leakage����������������������������������������������������������������������������������������������������������������������� 202
Imbalanced Data����������������������������������������������������������������������������������������������������������������� 202
Data Quality������������������������������������������������������������������������������������������������������������������������� 202
Feature Engineering Flaws�������������������������������������������������������������������������������������������������� 202
Algorithmic and Model-Specific Defects����������������������������������������������������������������������������������� 203
Gradients, Backpropagation, and Automatic Differentiation������������������������������������������������ 203
Hyperparameter Tuning������������������������������������������������������������������������������������������������������� 203
Overfitting and Underfitting������������������������������������������������������������������������������������������������� 203
Algorithm Choice����������������������������������������������������������������������������������������������������������������� 204
Deep Learning Defects�������������������������������������������������������������������������������������������������������������� 204
Activation and Loss Choices������������������������������������������������������������������������������������������������ 204
Learning Rate���������������������������������������������������������������������������������������������������������������������� 204
Implementation Defects������������������������������������������������������������������������������������������������������������ 204
Tensor Shapes��������������������������������������������������������������������������������������������������������������������� 204
Hardware Limitations and Memory������������������������������������������������������������������������������������� 204
Custom Code����������������������������������������������������������������������������������������������������������������������� 205
Performance Bottlenecks���������������������������������������������������������������������������������������������������� 205
Testing and Validation��������������������������������������������������������������������������������������������������������������� 205
Unit Testing�������������������������������������������������������������������������������������������������������������������������� 205
Model Validation������������������������������������������������������������������������������������������������������������������ 205
Cross-Validation������������������������������������������������������������������������������������������������������������������ 205
Metrics Monitoring�������������������������������������������������������������������������������������������������������������� 206
Visualization for Debugging������������������������������������������������������������������������������������������������������ 206
TensorBoard������������������������������������������������������������������������������������������������������������������������ 206
Matplotlib and Seaborn������������������������������������������������������������������������������������������������������� 206
Model Interpretability���������������������������������������������������������������������������������������������������������� 206

xiii
Table of Contents

Logging and Monitoring������������������������������������������������������������������������������������������������������������ 206


Checkpoints������������������������������������������������������������������������������������������������������������������������� 206
Logging�������������������������������������������������������������������������������������������������������������������������������� 207
Alerts����������������������������������������������������������������������������������������������������������������������������������� 207
Error Tracking Platforms������������������������������������������������������������������������������������������������������ 207
Collaborative Debugging����������������������������������������������������������������������������������������������������������� 207
Forums and Communities��������������������������������������������������������������������������������������������������� 207
Peer Review������������������������������������������������������������������������������������������������������������������������� 207
Documentation, Continuous Learning, and Updates����������������������������������������������������������������� 208
Maintaining Documentation������������������������������������������������������������������������������������������������ 208
Library Updates������������������������������������������������������������������������������������������������������������������� 208
Continuous Learning������������������������������������������������������������������������������������������������������������ 208
Case Study�������������������������������������������������������������������������������������������������������������������������������� 208
Summary���������������������������������������������������������������������������������������������������������������������������������� 212

Chapter 15: What AI and Machine Learning Can Do for Python Debugging��������� 213
Automated Error Detection������������������������������������������������������������������������������������������������������� 213
Intelligent Code Fix Suggestions����������������������������������������������������������������������������������������������� 213
Interaction Through Natural Language Queries������������������������������������������������������������������������ 214
Visual Debugging Insights��������������������������������������������������������������������������������������������������������� 214
Diagnostics and Anomaly Detection������������������������������������������������������������������������������������������ 214
Augmenting Code Reviews������������������������������������������������������������������������������������������������������� 215
Historical Information Analysis and Prognostics����������������������������������������������������������������������� 215
Adaptive Learning and Personalized Debugging Experience���������������������������������������������������� 216
Test Suite Integration and Optimization������������������������������������������������������������������������������������ 216
Enhanced Documentation and Resource Suggestions������������������������������������������������������������� 216
Problem Modeling��������������������������������������������������������������������������������������������������������������������� 217
Generative Debugging Strategy������������������������������������������������������������������������������������������������ 217
Help with In Papyro Debugging������������������������������������������������������������������������������������������������� 217
Summary���������������������������������������������������������������������������������������������������������������������������������� 218

xiv
Table of Contents

Chapter 16: The List of Debugging Patterns��������������������������������������������������������� 219


Elementary Diagnostics Patterns���������������������������������������������������������������������������������������������� 219
Debugging Analysis Patterns���������������������������������������������������������������������������������������������������� 219
Debugging Architecture Patterns���������������������������������������������������������������������������������������������� 221
Debugging Design Patterns������������������������������������������������������������������������������������������������������ 222
Debugging Implementation Patterns���������������������������������������������������������������������������������������� 222
Debugging Usage Patterns������������������������������������������������������������������������������������������������������� 222
Debugging Presentation Patterns��������������������������������������������������������������������������������������������� 223

Index��������������������������������������������������������������������������������������������������������������������� 225

xv
About the Author
Dmitry Vostokov is an internationally recognized expert,
speaker, educator, scientist, inventor, and author. He founded
the pattern-oriented software diagnostics, forensics, and
prognostics discipline (Systematic Software Diagnostics)
and Software Diagnostics Institute (DA+TA: DumpAnalysis.
org + TraceAnalysis.org). Vostokov has also authored
multiple books on software diagnostics, anomaly detection
and analysis, software, and memory forensics, root cause
analysis and problem-solving, memory dump analysis,
debugging, software trace and log analysis, reverse engineering, and malware analysis.
He has over thirty years of experience in software architecture, design, development,
and maintenance in various industries, including leadership, technical, and people
management roles. In his spare time, he presents multiple topics on Debugging.TV and
explores software narratology and its further development as narratology of things and
diagnostics of things (DoT), software pathology, and quantum software diagnostics.
His current interest areas are theoretical software diagnostics and its mathematical
and computer science foundations, application of formal logic, artificial intelligence,
machine learning, and data mining to diagnostics and anomaly detection, software
diagnostics engineering and diagnostics-driven development, diagnostics workflow,
and interaction. Recent interest areas also include cloud native computing, security,
automation, functional programming, applications of category theory to software
development and big data, and artificial intelligence diagnostics.

xvii
About the Technical Reviewer
Krishnendu Dasgupta is currently the Head of Machine
Learning at Mondosano GmbH, leading data science
initiatives focused on clinical trial recommendations and
advanced patient health profiling through disease and drug
data. Prior to this role, he co-founded DOCONVID AI, a
startup that leveraged applied AI and medical imaging to
detect lung abnormalities and neurological disorders.
With a strong background in computer science
engineering, Krishnendu has more than a decade of
experience in developing solutions and platforms using applied machine learning. His
professional trajectory includes key positions at prestigious organizations such as NTT
DATA, PwC, and Thoucentric.
Krishnendu’s primary research interests include applied AI for graph machine
learning, medical imaging, and decentralized privacy-preserving machine learning in
healthcare. He also had the opportunity to participate in the esteemed Entrepreneurship
and Innovation Bootcamp at the Massachusetts Institute of Technology, cohort of
2018 batch.
Beyond his professional endeavors, Krishnendu actively dedicates his time to
research, collaborating with various research NGOs and universities worldwide. His
focus is on applied AI and ML.

xix
Introduction
Python is the dominant language used in AI and machine learning with data and
pipelines in cloud environments. Besides debugging Python code in popular IDEs,
notebooks, and command-line debuggers, this book also includes coverage of native
OS interfacing (Windows and Linux) necessary to understand, diagnose, and debug
complex software issues.
The book begins with an introduction to pattern-oriented software diagnostics and
debugging processes that, before doing Python debugging, diagnose problems in various
software artifacts such as memory dumps, traces, and logs. Next, it teaches various
debugging patterns using Python case studies that model abnormal software behavior.
Further, it covers Python debugging specifics in cloud native and machine learning
environments. It concludes with how recent advances in AI/ML can help in Python
debugging. The book also goes deep for case studies when there are environmental
problems, crashes, hangs, resource spikes, leaks, and performance degradation. It
includes tracing and logging besides memory dumps and their analysis using native
WinDbg and GDB debuggers.
This book is for those who wish to understand how Python debugging is and can
be used to develop robust and reliable AI, machine learning, and cloud computing
software. It uses a novel pattern-oriented approach to diagnosing and debugging
abnormal software structure and behavior. Software developers, AI/ML engineers,
researchers, data engineers, MLOps, DevOps, and anyone who uses Python will benefit
from this book.
Source Code: All source code used in this book can be downloaded from g­ ithub.
com/Apress/Python-Debugging-for-AI-Machine-Learning-and-Cloud-Computing.

xxi
CHAPTER 1

Fundamental Vocabulary
Debugging complex software issues in machine learning and cloud computing
environments requires not only the knowledge of the Python language and its interpreter
(or compiler), plus standard and external libraries, but also necessary and relevant
execution environment and operating system internals. In this chapter, you will review
some necessary fundamentals from software diagnostics and debugging languages to
have the same base level of understanding for the following chapters. In this book, I
assume that you are familiar with the Python language and its runtime environment.

Process
A Python script is interpreted by compiling it into bytecode and then executing it, or it
can even be precompiled into an application program. In both cases, this interpreter file
or the compiled application is an executable program (in Windows, it may have a .exe
extension) that references some operating system libraries (.dll in Windows and .so in
Linux). This application can be loaded into computer memory several times; each time,
a separate process is created with its own resources and unique process ID (PID, also
TGID), as shown in Figure 1-1. The process may also have a parent process that created
it, with a parent process ID (PPID).

1
© Dmitry Vostokov 2024
D. Vostokov, Python Debugging for AI, Machine Learning, and Cloud Computing,
https://doi.org/10.1007/978-1-4842-9745-2_1
Chapter 1 Fundamental Vocabulary

Figure 1-1. Two python3 processes with two different PIDs

To illustrate, I executed the code in Listing 1-1 on both Windows and Linux twice.

Listing 1-1. A Simple Script to Model Running Python Code

import time

def main():
    foo()

def foo():
    bar()

def bar():
    while True:
        time.sleep(1)

if __name__ == "__main__":
    main()

Figure 1-2 shows two processes on Windows.

2
Chapter 1 Fundamental Vocabulary

Figure 1-2. Two running python3.11.exe processes on Windows

On Linux, you can also see two processes when you execute the same script in two
separate terminals:

~/Chapter1$ which python3


/usr/bin/python3

~/Chapter1$ ps -a
  PID TTY          TIME CMD
   17 pts/0    00:00:00 mc
   60 pts/2    00:00:00 python3
   61 pts/1    00:00:00 python3
   80 pts/3    00:00:00 ps

Note The operating system controls hardware and processes/threads. From a


high level, it is just a collection of processes with the operating system kernel as a
process too.

3
Chapter 1 Fundamental Vocabulary

Thread
From an operating system perspective, a process is just a memory container for a
Python interpreter, its code, and data. But the interpreter code needs to be executed,
for example, to interpret the Python bytecode. This unit of execution is called a thread.
A process may have several such units of execution (several threads, the so-called
multithreaded application). Each thread has its own unique thread ID (TID, also LWP
or SPID), as shown in Figure 1-3. For example, one thread may process user interface
events and others may do complex calculations in response to UI requests, thus making
the UI responsive. On Windows, thread IDs are usually different from process IDs, but
in Linux, the thread ID of the main thread is the same as the process ID for a single-
threaded process.

Figure 1-3. Two python3 processes with different numbers of threads

4
Chapter 1 Fundamental Vocabulary

To model multithreading, I executed the code in Listing 1-2 on both Windows


and Linux.

Listing 1-2. A Simple Script to Model Multiple Threads

import time
import threading

def thread_func():
    foo()

def main():
    t1 = threading.Thread(target=thread_func)
    t1.start()
    t2 = threading.Thread(target=thread_func)
    t2.start()
    t1.join()
    t2.join()

def foo():
    bar()

def bar():
    while True:
        time.sleep(1)

if __name__ == "__main__":
    main()

Figure 1-4 shows that in Windows, you can see 11 threads at the beginning (this
number later changes to 7 and then to 5). You see that the number of threads may be
greater than expected.

5
Chapter 1 Fundamental Vocabulary

Figure 1-4. The number of threads in the running python3.11.exe process


on Windows

In Linux, you can see the expected number of threads – 3:

~/Chapter1$ ps -aT
  PID  SPID TTY          TIME CMD
   17    17 pts/0    00:00:00 mc
   45    45 pts/2    00:00:00 python3
   45    46 pts/2    00:00:00 python3
   45    47 pts/2    00:00:00 python3
   54    54 pts/1    00:00:00 ps

Stack Trace (Backtrace, Traceback)


I should distinguish Python source code tracebacks (which we call managed stack traces)
and unmanaged (native) ones from the Python compiler and interpreter that compiles to
and executes Python byte code. You will see this distinction in some chapters for several
case studies and how to get both traces. But, for now, I will just show the difference.

6
Chapter 1 Fundamental Vocabulary

Listing 1-3 shows managed stack trace. Listing 1-4 shows the corresponding unmanaged
Linux stack trace with debugging symbols (the most recent call first). Listing 1-5 shows
the corresponding unmanaged Windows stack trace without debugging symbols (the
most recent call first).

Listing 1-3. Managed Stack Trace from the Execution of the Python Script from
Listing 1-1

Traceback (most recent call last):


  File "process.py", line 14, in <module>
    main()
  File "process.py", line 4, in main
    foo()
  File "process.py", line 7, in foo
    bar()
  File "process.py", line 11, in bar
    time.sleep(1)

Listing 1-4. Unmanaged Linux Backtrace from the Execution of the Python
Script from Listing 1-1 with Debugging Symbols

#0  0x00007f6bc84e6b97 in __GI___select (nfds=0, readfds=0x0, writefds=0x0,


exceptfds=0x0, timeout=0x7ffc60288fe0)
    at ../sysdeps/unix/sysv/linux/select.c:41
#1  0x00000000004e8965 in pysleep (secs=<optimized out>) at ../Modules/
timemodule.c:1829
#2  time_sleep (self=<optimized out>, obj=<optimized out>, self=<optimized
out>, obj=<optimized out>)
    at ../Modules/timemodule.c:371
#3  0x00000000005d8711 in _PyMethodDef_RawFastCallKeywords (method=0x82dbe0
<time_methods+288>,
    self=<module at remote 0x7f6bc800dc78>, args=0x7f6bc80c4550,
nargs=<optimized out>, kwnames=<optimized out>)
    at ../Objects/call.c:644
#4  0x000000000054b330 in _PyCFunction_FastCallKeywords (kwnames=<optimized
out>, nargs=<optimized out>,

7
Chapter 1 Fundamental Vocabulary

    args=0x7f6bc80c4550, func=<built-in method sleep of module object at


remote 0x7f6bc800dc78>)
    at ../Objects/call.c:730
#5  call_function (pp_stack=0x7ffc60289150, oparg=<optimized out>,
kwnames=<optimized out>) at ../Python/ceval.c:4568
#6  0x00000000005524cd in _PyEval_EvalFrameDefault (f=<optimized out>,
throwflag=<optimized out>)
    at ../Python/ceval.c:3093
#7  0x00000000005d91fc in PyEval_EvalFrameEx (throwflag=0,
    f=Frame 0x7f6bc80c43d8, for file process.py, line 11, in bar ()) at ../
Python/ceval.c:547
#8  function_code_fastcall (globals=<optimized out>, nargs=<optimized out>,
args=<optimized out>, co=<optimized out>)
    at ../Objects/call.c:283
#9  _PyFunction_FastCallKeywords (func=<optimized out>, stack=<optimized
out>, nargs=<optimized out>,
    kwnames=<optimized out>) at ../Objects/call.c:408
#10 0x000000000054e5ac in call_function (kwnames=0x0, oparg=<optimized
out>, pp_stack=<synthetic pointer>)
    at ../Python/ceval.c:4616
#11 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
at ../Python/ceval.c:3124
#12 0x00000000005d91fc in PyEval_EvalFrameEx (throwflag=0,
    f=Frame 0x7f6bc80105e8, for file process.py, line 7, in foo ()) at ../
Python/ceval.c:547
#13 function_code_fastcall (globals=<optimized out>, nargs=<optimized out>,
args=<optimized out>, co=<optimized out>)
    at ../Objects/call.c:283
#14 _PyFunction_FastCallKeywords (func=<optimized out>, stack=<optimized
out>, nargs=<optimized out>,
    kwnames=<optimized out>) at ../Objects/call.c:408
--Type <RET> for more, q to quit, c to continue without paging--
#15 0x000000000054e5ac in call_function (kwnames=0x0, oparg=<optimized
out>, pp_stack=<synthetic pointer>)
    at ../Python/ceval.c:4616

8
Chapter 1 Fundamental Vocabulary

#16 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)


at ../Python/ceval.c:3124
#17 0x00000000005d91fc in PyEval_EvalFrameEx (throwflag=0, f=Frame
0x205ade8, for file process.py, line 4, in main ())
    at ../Python/ceval.c:547
#18 function_code_fastcall (globals=<optimized out>, nargs=<optimized out>,
args=<optimized out>, co=<optimized out>)
    at ../Objects/call.c:283
#19 _PyFunction_FastCallKeywords (func=<optimized out>, stack=<optimized
out>, nargs=<optimized out>,
    kwnames=<optimized out>) at ../Objects/call.c:408
#20 0x000000000054e5ac in call_function (kwnames=0x0, oparg=<optimized
out>, pp_stack=<synthetic pointer>)
    at ../Python/ceval.c:4616
#21 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
at ../Python/ceval.c:3124
#22 0x000000000054bcc2 in PyEval_EvalFrameEx (throwflag=0,
    f=Frame 0x7f6bc80ab9f8, for file process.py, line 14, in <module> ())
at ../Python/ceval.c:547
#23 _PyEval_EvalCodeWithName (_co=<optimized out>, globals=<optimized out>,
locals=<optimized out>,
    args=<optimized out>, argcount=<optimized out>, kwnames=0x0,
kwargs=0x0, kwcount=<optimized out>, kwstep=2,
    defs=0x0, defcount=0, kwdefs=0x0, closure=0x0, name=0x0, qualname=0x0)
at ../Python/ceval.c:3930
#24 0x000000000054e0a3 in PyEval_EvalCodeEx (closure=0x0, kwdefs=0x0,
defcount=0, defs=0x0, kwcount=0, kws=0x0,
    argcount=0, args=0x0, locals=<optimized out>, globals=<optimized out>,
_co=<optimized out>)
    at ../Python/ceval.c:3959
#25 PyEval_EvalCode (co=<optimized out>, globals=<optimized out>,
locals=<optimized out>) at ../Python/ceval.c:524
#26 0x0000000000630ce2 in run_mod (mod=<optimized out>,
filename=<optimized out>,

9
Chapter 1 Fundamental Vocabulary

    globals={'__name__': '__main__', '__doc__': None, '__package__': None,


'__loader__': <SourceFileLoader(name='__main__', path='process.py') at
remote 0x7f6bc803dfd0>, '__spec__': None, '__annotations__': {}, '__
builtins__': <module at remote 0x7f6bc8102c28>, '__file__': 'process.
py', '__cached__': None, 'time': <module at remote 0x7f6bc800dc78>,
'main': <function at remote 0x7f6bc80791e0>, 'foo': <function at remote
0x7f6bc7f69c80>, 'bar': <function at remote 0x7f6bc7f69d08>},
    locals={'__name__': '__main__', '__doc__': None, '__package__': None,
'__loader__': <SourceFileLoader(name='__main__', path='process.py')
at remote 0x7f6bc803dfd0>, '__spec__': None, '__annotations__': {},
'__builtins__': <module at rem--Type <RET> for more, q to quit, c to
continue without paging--
ote 0x7f6bc8102c28>, '__file__': 'process.py', '__cached__': None,
'time': <module at remote 0x7f6bc800dc78>, 'main': <function at
remote 0x7f6bc80791e0>, 'foo': <function at remote 0x7f6bc7f69c80>,
'bar': <function at remote 0x7f6bc7f69d08>}, flags=<optimized out>,
arena=<optimized out>) at ../Python/pythonrun.c:1035
#27 0x0000000000630d97 in PyRun_FileExFlags (fp=0x2062390, filename_
str=<optimized out>, start=<optimized out>,
    globals={'__name__': '__main__', '__doc__': None, '__package__': None,
'__loader__': <SourceFileLoader(name='__main__', path='process.py') at
remote 0x7f6bc803dfd0>, '__spec__': None, '__annotations__': {}, '__
builtins__': <module at remote 0x7f6bc8102c28>, '__file__': 'process.
py', '__cached__': None, 'time': <module at remote 0x7f6bc800dc78>,
'main': <function at remote 0x7f6bc80791e0>, 'foo': <function at remote
0x7f6bc7f69c80>, 'bar': <function at remote 0x7f6bc7f69d08>},
    locals={'__name__': '__main__', '__doc__': None, '__package__': None,
'__loader__': <SourceFileLoader(name='__main__', path='process.py') at
remote 0x7f6bc803dfd0>, '__spec__': None, '__annotations__': {}, '__
builtins__': <module at remote 0x7f6bc8102c28>, '__file__': 'process.
py', '__cached__': None, 'time': <module at remote 0x7f6bc800dc78>,
'main': <function at remote 0x7f6bc80791e0>, 'foo': <function at
remote 0x7f6bc7f69c80>, 'bar': <function at remote 0x7f6bc7f69d08>},
closeit=1, flags=0x7ffc6028989c) at ../Python/pythonrun.c:988

10
Chapter 1 Fundamental Vocabulary

#28 0x00000000006319ff in PyRun_SimpleFileExFlags (fp=0x2062390,


filename=<optimized out>, closeit=1,
    flags=0x7ffc6028989c) at ../Python/pythonrun.c:429
#29 0x000000000065432e in pymain_run_file (p_cf=0x7ffc6028989c,
filename=<optimized out>, fp=0x2062390)
    at ../Modules/main.c:427
#30 pymain_run_filename (cf=0x7ffc6028989c, pymain=0x7ffc60289970) at ../
Modules/main.c:1627
#31 pymain_run_python (pymain=0x7ffc60289970) at ../Modules/main.c:2877
#32 pymain_main (pymain=<optimized out>, pymain=<optimized out>) at ../
Modules/main.c:3038
#33 0x000000000065468e in _Py_UnixMain (argc=<optimized out>,
argv=<optimized out>) at ../Modules/main.c:3073
#34 0x00007f6bc841a09b in __libc_start_main (main=0x4bc560 <main>, argc=2,
argv=0x7ffc60289ab8, init=<optimized out>,
    fini=<optimized out>, rtld_fini=<optimized out>, stack_
end=0x7ffc60289aa8) at ../csu/libc-start.c:308
#35 0x00000000005e0e8a in _start () at ../Modules/main.c:797

Listing 1-5. Unmanaged Windows Stack Trace from the Execution of the Python
Script from Listing 1-1 Without Debugging Symbols

00 00000090`7e1ef0a8 00007ff9`8c44fcf9     ntdll!NtWaitForMultipleObjects+
0x14
01 00000090`7e1ef0b0 00007ff9`8c44fbfe     KERNELBASE!WaitForMultipleObject
sEx+0xe9
02 00000090`7e1ef390 00007ff8`ef943986     KERNELBASE!WaitForMultipleObject
s+0xe
03 00000090`7e1ef3d0 00007ff8`ef94383d     python311!PyTraceBack_Print_
Indented+0x35a
04 00000090`7e1ef430 00007ff8`ef81a6b2     ­python311!PyTraceBack_Print_
Indented+0x211
05 00000090`7e1ef460 00007ff8`ef82fa77     python311!PyEval_
EvalFrameDefault+0x8f2
06 00000090`7e1ef670 00007ff8`ef82f137     python311!PyMapping_Check+0x1eb
07 00000090`7e1ef6b0 00007ff8`ef82d80a     python311!PyEval_EvalCode+0x97

11
Chapter 1 Fundamental Vocabulary

08 00000090`7e1ef730 00007ff8`ef82d786     python311!PyMapping_Items+0x11e
09 00000090`7e1ef760 00007ff8`ef97a17e     python311!PyMapping_Items+0x9a
0a 00000090`7e1ef7a0 00007ff8`ef7e33a5     python311!PyThread_tss_is_
created+0x53ce
0b 00000090`7e1ef810 00007ff8`ef8da620     python311!PyRun_
SimpleFileObject+0x11d
0c 00000090`7e1ef880 00007ff8`ef8daaef     python311!PyRun_
AnyFileObject+0x54
0d 00000090`7e1ef8b0 00007ff8`ef8dab5f     python311!Py_
MakePendingCalls+0x38f
0e 00000090`7e1ef980 00007ff8`ef8db964     python311!Py_
MakePendingCalls+0x3ff
0f 00000090`7e1ef9b0 00007ff8`ef8db7f5     python311!Py_RunMain+0x184
10 00000090`7e1efa20 00007ff8`ef8260d9     python311!Py_RunMain+0x15
11 00000090`7e1efa50 00007ff6`aefe1230     python311!Py_Main+0x25
12 00000090`7e1efaa0 00007ff9`8e1c26ad     python+0x1230
13 00000090`7e1efae0 00007ff9`8ef6a9f8     KERNEL32!BaseThreadInitThunk+0x
1d
14 00000090`7e1efb10 00000000`00000000     ntdll!RtlUserThreadStart+0x28

Note Each thread has its own stack trace (backtrace).

S
 ymbol Files
Symbol files allow a debugger to map memory addresses to symbolic information such
as function and variable names. For example, if you download and apply symbol files to
the Windows example above, you get a much better and more accurate stack trace, as
shown in Listing 1-6.

12
Chapter 1 Fundamental Vocabulary

Listing 1-6. Unmanaged Windows Stack Trace from the Execution of the Python
Script from Listing 1-1 with Debugging Symbols

00 00000090`7e1ef0a8 00007ff9`8c44fcf9     ntdll!NtWaitForMultipleObjects+
0x14
01 00000090`7e1ef0b0 00007ff9`8c44fbfe     KERNELBASE!WaitForMultipleObject
sEx+0xe9
02 00000090`7e1ef390 00007ff8`ef943986     KERNELBASE!WaitForMultipleObject
s+0xe
03 00000090`7e1ef3d0 00007ff8`ef94383d     python311!pysleep+0x11a
04 00000090`7e1ef430 00007ff8`ef81a6b2     python311!time_sleep+0x2d
05 00000090`7e1ef460 00007ff8`ef82fa77     python311!_PyEval_
EvalFrameDefault+0x8f2
06 (Inline Function) --------`--------     python311!_PyEval_EvalFrame+0x1e
07 00000090`7e1ef670 00007ff8`ef82f137     python311!_PyEval_Vector+0x77
08 00000090`7e1ef6b0 00007ff8`ef82d80a     python311!PyEval_EvalCode+0x97
09 00000090`7e1ef730 00007ff8`ef82d786     python311!run_eval_code_obj+0x52
0a 00000090`7e1ef760 00007ff8`ef97a17e     python311!run_mod+0x72
0b 00000090`7e1ef7a0 00007ff8`ef7e33a5     python311!pyrun_file+0x196b66
0c 00000090`7e1ef810 00007ff8`ef8da620     python311!_PyRun_
SimpleFileObject+0x11d
0d 00000090`7e1ef880 00007ff8`ef8daaef     python311!_PyRun_
AnyFileObject+0x54
0e 00000090`7e1ef8b0 00007ff8`ef8dab5f     python311!pymain_run_file_
obj+0x10b
0f 00000090`7e1ef980 00007ff8`ef8db964     python311!pymain_run_file+0x63
10 00000090`7e1ef9b0 00007ff8`ef8db7f5     python311!pymain_run_
python+0x140
11 00000090`7e1efa20 00007ff8`ef8260d9     python311!Py_RunMain+0x15
12 00000090`7e1efa50 00007ff6`aefe1230     python311!Py_Main+0x25
13 (Inline Function) --------`--------     python!invoke_main+0x22
14 00000090`7e1efaa0 00007ff9`8e1c26ad     python!__scrt_common_main_
seh+0x10c
15 00000090`7e1efae0
00007ff9`8ef6a9f8     ­KERNEL32!BaseThreadInitThunk+0x1d
16 00000090`7e1efb10 00000000`00000000     ntdll!RtlUserThreadStart+0x28

13
Chapter 1 Fundamental Vocabulary

M
 odule
Like the distinction between managed and unmanaged stack traces, there is a difference
between Python modules (which may correspond to files in traceback) and native
modules such as DLLs in Windows and .so files in Linux, which are loaded into memory
when you execute the Python compiler/interpreter. For example, the following shared
libraries are loaded in Linux for the simple multithreaded example from Listing 1-2:

~/Chapter1$ pmap 60
60:   python3 process.py
0000000000400000    132K r---- python3.7
0000000000421000   2256K r-x-- python3.7
0000000000655000   1712K r---- python3.7
0000000000801000      4K r---- python3.7
0000000000802000    664K rw--- python3.7
00000000008a8000    140K rw---   [ anon ]
0000000001fff000    660K rw---   [ anon ]
00007f6bc7f69000   1684K rw---   [ anon ]
00007f6bc810e000   2964K r---- locale-archive
00007f6bc83f3000     12K rw---   [ anon ]
00007f6bc83f6000    136K r---- libc-2.28.so
00007f6bc8418000   1308K r-x-- libc-2.28.so
00007f6bc855f000    304K r---- libc-2.28.so
00007f6bc85ab000      4K ----- libc-2.28.so
00007f6bc85ac000     16K r---- libc-2.28.so
00007f6bc85b0000      8K rw--- libc-2.28.so
00007f6bc85b2000     16K rw---   [ anon ]
00007f6bc85b6000     52K r---- libm-2.28.so
00007f6bc85c3000    636K r-x-- libm-2.28.so
00007f6bc8662000    852K r---- libm-2.28.so
00007f6bc8737000      4K r---- libm-2.28.so
00007f6bc8738000      4K rw--- libm-2.28.so
00007f6bc8739000      8K rw---   [ anon ]
00007f6bc873b000     12K r---- libz.so.1.2.11
00007f6bc873e000     72K r-x-- libz.so.1.2.11
00007f6bc8750000     24K r---- libz.so.1.2.11

14
Chapter 1 Fundamental Vocabulary

00007f6bc8756000      4K ----- libz.so.1.2.11


00007f6bc8757000      4K r---- libz.so.1.2.11
00007f6bc8758000      4K rw--- libz.so.1.2.11
00007f6bc8759000     16K r---- libexpat.so.1.6.8
00007f6bc875d000    132K r-x-- libexpat.so.1.6.8
00007f6bc877e000     80K r---- libexpat.so.1.6.8
00007f6bc8792000      4K ----- libexpat.so.1.6.8
00007f6bc8793000      8K r---- libexpat.so.1.6.8
00007f6bc8795000      4K rw--- libexpat.so.1.6.8
00007f6bc8796000      4K r---- libutil-2.28.so
00007f6bc8797000      4K r-x-- libutil-2.28.so
00007f6bc8798000      4K r---- libutil-2.28.so
00007f6bc8799000      4K r---- libutil-2.28.so
00007f6bc879a000      4K rw--- libutil-2.28.so
00007f6bc879b000      4K r---- libdl-2.28.so
00007f6bc879c000      4K r-x-- libdl-2.28.so
00007f6bc879d000      4K r---- libdl-2.28.so
00007f6bc879e000      4K r---- libdl-2.28.so
00007f6bc879f000      4K rw--- libdl-2.28.so
00007f6bc87a0000     24K r---- libpthread-2.28.so
00007f6bc87a6000     60K r-x-- libpthread-2.28.so
00007f6bc87b5000     24K r---- libpthread-2.28.so
00007f6bc87bb000      4K r---- libpthread-2.28.so
00007f6bc87bc000      4K rw--- libpthread-2.28.so
00007f6bc87bd000     16K rw---   [ anon ]
00007f6bc87c1000      4K r---- libcrypt-2.28.so
00007f6bc87c2000     24K r-x-- libcrypt-2.28.so
00007f6bc87c8000      8K r---- libcrypt-2.28.so
00007f6bc87ca000      4K ----- libcrypt-2.28.so
00007f6bc87cb000      4K r---- libcrypt-2.28.so
00007f6bc87cc000      4K rw--- libcrypt-2.28.so
00007f6bc87cd000    192K rw---   [ anon ]
00007f6bc8801000     28K r--s- gconv-modules.cache
00007f6bc8808000      4K r---- ld-2.28.so
00007f6bc8809000    120K r-x-- ld-2.28.so

15
Chapter 1 Fundamental Vocabulary

00007f6bc8827000     32K r---- ld-2.28.so


00007f6bc882f000      4K r---- ld-2.28.so
00007f6bc8830000      4K rw--- ld-2.28.so
00007f6bc8831000      4K rw---   [ anon ]
00007ffc6026a000    132K rw---   [ stack ]
00007ffc60356000     16K r----   [ anon ]
00007ffc6035a000      4K r-x--   [ anon ]
total            14700K

The Windows version has the following loaded modules:

00007ff6`aefe0000 00007ff6`aeffa000   python   python.exe
00007ff8`ef7e0000 00007ff8`efdad000   python311 python311.dll
00007ff9`62950000 00007ff9`6296b000   VCRUNTIME140 VCRUNTIME140.dll
00007ff9`7f1e0000 00007ff9`7f1ea000   VERSION  VERSION.dll
00007ff9`8bce0000 00007ff9`8bd08000   bcrypt   bcrypt.dll
00007ff9`8c3f0000 00007ff9`8c793000   KERNELBASE KERNELBASE.dll
00007ff9`8c840000 00007ff9`8c951000   ucrtbase ucrtbase.dll
00007ff9`8c960000 00007ff9`8c9db000   bcryptprimitives bcryptprimitives.dll
00007ff9`8d150000 00007ff9`8d1c1000   WS2_32   WS2_32.dll
00007ff9`8d1d0000 00007ff9`8d2e7000   RPCRT4   RPCRT4.dll
00007ff9`8dd50000 00007ff9`8ddf7000   msvcrt   msvcrt.dll
00007ff9`8ded0000 00007ff9`8df7e000   ADVAPI32 ADVAPI32.dll
00007ff9`8e1b0000 00007ff9`8e272000   KERNEL32 KERNEL32.DLL
00007ff9`8e280000 00007ff9`8e324000   sechost  sechost.dll
00007ff9`8ef10000 00007ff9`8f124000   ntdll    ntdll.dll

M
 emory Dump
A process memory can be saved in a memory dump file.

An undigested and voluminous mass of information about a problem or


the state of a system and most especially one consisting of hex runes describ-
ing the byte-by-byte state of memory.
Eric S. Raymond, The New Hacker’s Dictionary, Third Edition

16
Chapter 1 Fundamental Vocabulary

These memory dumps are also called core dumps in Linux. It is also possible to get a
kernel memory dump and a dump of physical memory (also called a complete memory
dump in Windows). Figure 1-5 shows different memory dump types.

Figure 1-5. Memory dump types

Memory dumps may be useful for debugging hard-to-reproduce intermittent


problems. This approach is called postmortem debugging. You will see some case
studies in the following chapters.

Crash
To fail suddenly. “Has the system just crashed?” “Something crashed the
OS!” Also used transitively to indicate the cause of the crash (usually a
­person or a program, or both). “Those idiots playing SPACEWAR crashed
the system.”
Eric S. Raymond, The New Hacker’s Dictionary, Third Edition.

17
Chapter 1 Fundamental Vocabulary

When something illegal happens inside a process thread, such as when memory
outside its available range is accessed or you write to read-only memory, the operating
system reports the error and terminates the process. It may also save the process
memory into a memory dump file. The process then disappears from the list of available
processes.

Hang
1. To wait for an event that will never occur. “The system is hanging because
it can’t read from the crashed drive.”
2. To wait for an event to occur. “The program displays a menu and then
hangs until you type a character.”

Eric S. Raymond, The New Hacker’s Dictionary, Third Edition

Threads interact with other threads, including other processes’ threads. These
interactions can be viewed as sending messages and waiting for the responses. Some
processes may be critical because their threads process messages from many other
threads from other processes. If threads from such a critical process stop sending
responses, all other waiting threads are blocked. A deadlock is when two threads are
waiting for each other. When hanging, the process continues to be present in the list
of available processes. There are also processes (critical components) that, when their
threads hang, block threads from many other processes (noncritical components).
Figure 1-6 depicts such components and their interaction abstracted via messages in
the normal scenario, and Figure 1-7 shows the abnormal scenario when noncritical
components are blocked and waiting for responses because the critical components are
deadlocked.

18
Chapter 1 Fundamental Vocabulary

Figure 1-6. Request and response interaction between critical and noncritical
system components

19
Chapter 1 Fundamental Vocabulary

Figure 1-7. Blocked and deadlocked components

Summary
In this chapter, you learned the fundamental vocabulary you will use in subsequent
chapters. The next chapter introduces a pattern-oriented debugging approach.

20
CHAPTER 2

Pattern-Oriented
Debugging
This chapter introduces the pattern-oriented debugging process approach and the
pattern languages you will use in subsequent chapters.

The History of the Idea


The idea of using patterns in debugging is not new1. Earlier, such patterns came in two
types: bug patterns2 and debug patterns3. Before 2000, only a few debugging-related
patterns could be found, such as the Debug Printing Method4.
Bug patterns are usually specific patterns for specific languages and platforms. By
bugs, we mean software defects. Usually, these are related to the source code but can
also be related to configuration and data models.
Using source code as a starting point for debugging is only possible for a limited
number of scenarios, such as when you have a Python stack trace. However, there are
many cases when the starting point for source code investigation is unknown. Here, a
well-defined process may benefit. A number of debugging processes were proposed in
the past, including multidisciplinary approaches5.

1
Mehdi Amoui et al., “A Pattern Language for Software Debugging,” International Journal
of Computer Science, vol. 1, no. 3, pp. 218-224, 2006. https://stargroup.uwaterloo.
ca/~mamouika/papers/pdf/IJCS.2006.pdf
2
Eric Allen, Bug Patterns in Java, 2002 (ISBN-13: 978-1590590614)
3
https://en.wikipedia.org/wiki/Debugging_pattern
4
Linda Rising, The Pattern Almanac 2000, p. 154 (ISBN-13: 978-0201615678)
5
Robert Charles Metzger, Debugging by Thinking: A Multidisciplinary Approach, 2003 (ISBN-13:
978-1555583071)

21
© Dmitry Vostokov 2024
D. Vostokov, Python Debugging for AI, Machine Learning, and Cloud Computing,
https://doi.org/10.1007/978-1-4842-9745-2_2
Chapter 2 Pattern-Oriented Debugging

The phrase “pattern-oriented debugging” appeared around 1987-1988 in the context


of patterns of process interaction6. It is not the same as the “pattern-oriented debugging
process” proposed in 20147 as further development of unified debugging patterns that
were introduced in 20108. Since then, these patterns have been used for successfully
teaching Windows debugging of unmanaged (native, Win64, C, C++) and managed
(.NET, C#) code9 for almost a decade, starting in 2013. Overall, this pattern-oriented
approach can be traced to our earlier presentation published as a book in 201110. In it,
we apply the same pattern-oriented process to Python debugging in cloud and machine
learning environments.

Patterns and Analysis Patterns


Before looking at the debugging process, a few words about patterns in the context of
diagnostics and debugging. By a pattern, we mean a common recurrent identifiable set
of indicators (symptoms, signs). By an analysis pattern, we mean a common recurrent
analysis technique and method of pattern identification in a specific context. By
pattern language, we mean common names of patterns and analysis patterns used for
communication.

Development Process
Let’s first look at the traditional software development process stages. Figure 2-1
abstracts them from several development processes, including waterfall and
iterative ones.

6
Alfred A. Hough and Janice E. Cuny, “Initial experiences with a pattern-oriented parallel
debugger.” PADD ‘88: Proceedings of the 1988 ACM SIGPLAN and SIGOPS workshop on
Parallel and distributed debugging November 1988 Pages 195–205
https://doi.org/10.1145/68210.69234
7
Dmitry Vostokov, Pattern-Oriented Debugging Process, in Theoretical Software Diagnostics:
Collected Articles, Third Edition, 2020 (ISBN-13: 978-1912636334), pp. 197-199
8
Ibid., “Analysis, Architectural, Design, Implementation and Usage Debugging Patterns,” p. 129
9
Accelerated Windows Debugging 4D, Third Edition, 2022 (ISBN-13: 978-1912636532)
10
Dmitry Vostokov, Introduction to Pattern-Driven Software Problem Solving, 2011 (ISBN-13:
978-1908043177)

22
Chapter 2 Pattern-Oriented Debugging

Figure 2-1. Stages of the typical software development process

Development Patterns
For each stage, there exists some pattern language such as a vocabulary of solutions to
common recurrent identifiable problems with grammar, semantics, and pragmatics.
Figure 2-2 also includes software usage and presentation patterns for human-computer
interaction. In this book, I assume you have familiarity with such pattern languages
(some references are provided below).

23
Chapter 2 Pattern-Oriented Debugging

Figure 2-2. Typical software development pattern languages

Debugging Process and Patterns


The debugging process mirrors the development process and development patterns, as
shown in Figure 2-3. Let’s look at each stage.

24
Chapter 2 Pattern-Oriented Debugging

Figure 2-3. Stages of the pattern-oriented debugging process

Elementary Diagnostics Patterns


Elementary software diagnostics patterns got inspiration from the Elemental Design
Patterns book title11, but they are different and correspond to requirements from the
software development process. These are what software users experience, and the
requirement is to eliminate such experiences via debugging.

11
Jason McC. Smith, Elemental Design Patterns, 2012 (ISBN-13: 978-0321711922)

25
Chapter 2 Pattern-Oriented Debugging

Debugging Analysis Patterns


You need to diagnose the right problem before doing any debugging. Debugging analysis
patterns correspond to software diagnostics. For example, in memory dump analysis,
there are analysis patterns such as Managed Code Exception, Managed Stack Trace,
Stack Overflow, Deadlock, Spiking Thread, and many others. There are hundreds of
them12. Trace and log analysis patterns such as Thread of Activity, Discontinuity, Time
Delta, Counter Value, State Dump, and many more are also included in this category13.
We look at the most common of them in Chapter 4.

Debugging Architecture Patterns


Debugging architecture patterns are partly inspired by POSA14, for example, Debug
Event Subscription/Notification. They are more high-level than design patterns that
may differ for specific technologies, for example, object-oriented and functional.

Debugging Design Patterns


Debugging design patterns are partly inspired by the GoF design pattern approach15, for
example, Punctuated Execution.
Both debugging architecture and debugging design patterns pertain to the
development of debugging tools and to actual debugging architectures and designs as
reusable solutions to common recurrent debugging problems in specific contexts.

12
Dmitry Vostokov, Encyclopedia of Crash Dump Analysis Patterns: Detecting Abnormal Software
Structure and Behavior in Computer Memory, Third Edition, 2020 (ISBN-13: 978-1912636303)
13
Dmitry Vostokov, Fundamentals of Trace and Log Analysis: A Pattern-Oriented Approach to
Monitoring, Diagnostics, and Debugging, Apress, 2023 (ISBN-13: 978-1484298954) and Dmitry
Vostokov, Trace, Log, Text, Narrative, Data: An Analysis Pattern Reference for Information Mining,
Diagnostics, Anomaly Detection, Fifth Edition, 2023 (ISBN-13: 978-1912636587)
14
Frank Buschmann et al., Pattern-Oriented Software Architecture: A System of Patterns, 1996
(ISBN-13: 978-0471958697)
15
Erich Gamma et al., Design Patterns: Elements of Reusable Object-Oriented Software, 1995
(ISBN-13: 978-0201633610)

26
Chapter 2 Pattern-Oriented Debugging

Debugging Implementation Patterns


Debugging implementation patterns are patterns of debugging strategies and core
debugging techniques, such as Break-in, Code Breakpoint, Data Breakpoint, and
others covered in subsequent chapters in Python debugging case studies.

Debugging Usage Patterns


Debugging usage patterns are about debugging pragmatics of reusable debugging
scenarios: how, what, when, and where to use the previous debugging pattern
categories, such as using data breakpoints in user (process) and kernel space debugging.

Debugging Presentation Patterns


Debugging presentation patterns are about user interface and interaction design16, for
example, watch dialog. These patterns are also related to debugging usage. We cover
such patterns in the chapter devoted to existing Python IDEs and their usage for Python
debugging.
In our opinion, recent Python debugging books17 correspond to debugging
implementation, usage, and presentation. Automated debugging18 belongs to
debugging architecture and design. In this book, we extract some of this knowledge
into corresponding debugging pattern languages, combine them with pattern-oriented
software diagnostics, and form a novel pattern-oriented Python debugging approach in
the context of machine learning and cloud computing environments.

16
Jan Borchers, A Pattern Approach to Interaction Design, 2001 (ISBN-13: 978-0471498285)
17
Kristian Rother, Pro Python Best Practices: Debugging, Testing and Maintenance, 2017
(ISBN-13: 978-1484222409) and R. L. Zimmerman, Python Debugging Handbook, 2020 (ISBN-13:
979-8610761725)
18
Andreas Zeller, The Debugging Book: Tools and Techniques for Automated Software Debugging,
www.debuggingbook.org/ (uses Python for examples)

27
Chapter 2 Pattern-Oriented Debugging

Summary
In this chapter, you learned about the pattern-oriented debugging process, its stages,
and corresponding pattern languages. The subsequent chapters provide examples of
debugging patterns from each category from a Python programming perspective. The
next chapter is about the first stage and its patterns: elementary diagnostics patterns.

28
CHAPTER 3

Elementary Diagnostics
Patterns
In the previous chapter, I introduced the pattern-oriented debugging process with
elementary (software) diagnostics patterns of abnormal software behavior that affect
users and trigger software diagnostics and debugging if necessary (Figure 3-1).

Figure 3-1. Pattern-oriented debugging process and elementary diagnostics


patterns

29
© Dmitry Vostokov 2024
D. Vostokov, Python Debugging for AI, Machine Learning, and Cloud Computing,
https://doi.org/10.1007/978-1-4842-9745-2_3
Chapter 3 Elementary Diagnostics Patterns

There are only a few such patterns divided into two groups. The goal is to have
the absolute minimum of them. In this chapter, you will look at them in more detail,
learn how to recognize them during software execution, and collect relevant software
execution artifacts. There are two groups of such patterns: functional and non-
functional.

Functional Patterns
The first group (functional) contains only one elementary diagnostics pattern: Use-case
Deviation.

Use-Case Deviation
By a use case, we mean a functional requirement, something that software is supposed
to do for users (or other programs) correctly, but instead we have a deviation from the
correct result, response, or course of action. Here tracing, logging, and running the
program under a debugger (live debugging) are useful debugging techniques.

Non-Functional Patterns
The second group (non-functional) contains a few elementary diagnostics patterns:

• Crash

• Hang

• Counter Value

• Error Message

Crash
A Crash manifests itself when a software process suddenly disappears from the list of
running processes. This list can be the output of the ps command in Linux, Activity
Monitor in macOS, or the Task Manager detailed process list in Windows. The crash can
happen from some Python exception, Python runtime, or an unhandled OS exception
from some native library. For latter cases, it is recommended to configure the system to
30
Chapter 3 Elementary Diagnostics Patterns

save process memory dumps (usually called core dumps in Linux and macOS and crash
dumps in Windows). These memory dumps may help to see backtraces (stack traces) in
case there is no output on the terminal (or console).
Saved memory dumps are loaded into a debugger to see the stack trace and program
variables (memory values) at the time of the crash (postmortem debugging).
You can also run a program under a debugger from the start or attach a debugger
before a crash. The debugger will also show a stack trace that led to a problem before the
process disappeared (live debugging).

How to Enable Process Core Dumps on Linux


Core dumps can be temporarily enabled for the current user using this command:

$ ulimit -c unlimited

Core dumps can be permanently enabled for every user except root by editing the
/etc/security/limits.conf file. Add or uncomment the following line:

*     soft  core  unlimited

To limit the root to 1GB, add or uncomment the following line:

*     hard  core  1000000

How to Enable Process Memory Dumps on Windows


This is best done via the LocalDumps registry key. The article Collecting User-Mode
Dumps1 at https://learn.microsoft.com/en-us/windows/win32/wer/collecting-
user-mode-dumps outlines how to do it.

Hang
A Hang manifests itself when a process becomes unresponsive (frozen) from a user’s
perspective (and also from the perspective of another process that may request some
functionality). But it is still visible from the process list command or GUI process
managers, which may or may not indicate that the process is frozen. This elementary
pattern also includes delays. Here API and library tracing may point to the blocked call,

1
https://learn.microsoft.com/en-us/windows/win32/wer/collecting-user-mode-dumps

31
Chapter 3 Elementary Diagnostics Patterns

or better, a manual memory dump should definitely show blocked process threads and
even suggest whether there is a deadlock (threads mutually waiting for each other), the
so-called postmortem debugging scenario.
It is also possible to start a program under a debugger (or attach it after the start),
wait until it hangs, and then inspect threads and memory (live debugging).

How to Generate Process Core Dumps on Linux


There are several methods:

• The kill command (requires ulimit)

$ kill -s SIGQUIT PID


$ kill -s SIGABRT PID
• gcore

$ gcore [-o filename] PID


• ProcDump2

How to Generate Process Memory Dumps on Windows


If you use a GUI environment, this can be done via Task Manager by selecting a Python
process, right-clicking, and choosing Create dump file, as shown in Figure 3-2.

2
https://github.com/Sysinternals/ProcDump-for-Linux

32
Random documents with unrelated
content Scribd suggests to you:
edellisen hallituksen aikana tämän riitakysymyksen johdosta
nostattanut Astrakanissa kapinan. Olipa kiihkoilijoitakin kuten noiden
sivistyneiden kansain keskuudessa, missä kaikki ovat olevinaan
jumaluusoppineita; ja Pietari, joka aina ajoi oikeuden julmuuteen
saakka, poltatti roviolla muutamia noista kurjista, joita sanottiin
vosko-jesuiitoiksi.

Lisäksi oli tsaarilla avarassa valtakunnassaan paljon muitakin


alamaisia, jotka eivät edes olleet kristittyjä. Niinpä ovat tataarit,
jotka asuvat Kaspianmeren ja Asovinmeren länsirannikolla,
muhamettilaisia; siperialaiset, ostjakit ja samojedit, jotka asuvat
Jäämeren puolella, olivat raakalaisia, toiset epäjumalain palvojia,
toisilla taas ei ollut minkäänlaista käsitystä jumalasta. Heidän
keskuuteensa sijoitetut ruotsalaiset sotavangit olivat kuitenkin
tyytyväisempiä heidän kuin vanhain moskovalaisten tapoihin.

Pietari Aleksejevitshin kasvatus oli omiaan vielä lisäämäänkin


tämän maailmanosan raakalaisuutta. Hänen luonteensa oli sentään
saanut hänet pitämään muukalaisista, ennenkuin hän edes tiesikään,
missä määrin nämä voisivat olla hänelle hyödyksi. Le Fort, kuten
tietty, oli ensimäinen apulainen, jota hän käytti muuttaaksensa
Venäjän muodon. Hänen mahtava neronsa, jota raakalaiskasvatus oli
siihen saakka kahlinnut, kehittyi nyt miltei yhdellä iskulla. Hän päätti
olla ihminen, hallita ihmisiä ja luoda uuden kansan. Ennen häntä
olivat useat ruhtinaat kieltäytyneet kruunusta siihen liittyvien
velvollisuuksien rasittavan taakan vuoksi, mutta kukaan ei ollut
luopunut kruunusta oppiakseen ensin kunnollisesti hallitsemaan.
Juuri niin teki Pietari Suuri.

Hallittuaan tuskin kaksi vuotta[10] hän jätti Venäjän v. 1698 ja


matkusti varsin jokapäiväisen salanimen suojassa Hollantiin, ollen
olevinaan tuon samaisen Le Fortin palvelija, jonka hän toimitti
ylimääräisenä lähettiläänä Hollannin yleis-eduskunnan luo.
Saavuttuaan Amsterdamiin hän kirjoittautui Intian amiraliteetin
kirvesmiesten luetteloihin ja työskenteli muiden kirvesmiesten tavoin
laivaveistämössä. Työnsä lomassa hän opiskeli sellaisia matematiikan
haaroja, jotka voivat olla ruhtinaalle hyödyksi, nimittäin
linnoitustaitoa, purjehdusoppia ja asemapiirroksien laatimista. Hän
kävi työläisten työhuoneissa ja tutki kaikenlaisia teollisuuslaitoksia;
mikään ei jäänyt häneltä huomaamatta. Täältä hän lähti Englantiin,
jossa täydensi tietojaan laivanrakennustaidossa; palasi sitten
Hollantiin ja tarkasteli kaikkea, josta voi olla hyötyä hänen
maallensa. Vihdoin hän kahden vuoden matkojen ja tehtävien
jälkeen, joihin kukaan muu ihminen paitsi hän ei olisi halunnut
alistua, palasi Venäjälle, vieden sinne mukanaan muun Euroopan
taidot.

Kaikenlaisia taitureita seurasi häntä sinne joukoittain. Ensimäistä


kertaa nähtiin suuria venäläisiä laivoja Mustallamerellä, Itämerellä ja
Atlantilla. Moskovan hökkelien keskelle kohosi säännöllisesti ja
kauniisti rakennettuja taloja. Hän perusti oppilaitoksia, akatemioita,
kirjapainoja, kirjastoja; kaupunkien olot järjestettiin; puvut ja tavat
muuttuivat vähitellen, joskin työläästi. Venäläiset oppivat asteittain
tuntemaan, mitä tarkoitetaan seuraelämällä. Itse taikauskokin
väheni, patriarkan arvo lakkautettiin. Tsaari julistautui itse uskonnon
päämieheksi. Tämä viime yritys, joka jollekulle vähemmän
itsevaltiaalle ruhtinaalle olisi maksanut valtaistuimen ja hengen,
onnistui miltei vastuksetta ja takasi hänelle kaikkien muiden
uudistuksien menestymisen.

Nöyryytettyään tietämättömän ja raa'an papiston hän uskalsi


yrittää sen sivistämistä, vaikkapa siten olikin pelättävä, että se
uudelleen kävisi vaaralliseksi, mutta hän uskoi olevansa kyllin
mahtava pelätäkseen enää heitä. Hän antoi opettaa filosofiaa ja
teologiaa niissä harvoissa luostareissa, jotka olivat jäljellä. Tosin
tämä teologia vieläkin muistutti sitä raakalaisuuden aikaa, josta
Pietari Aleksejevitsh oli vapauttanut isänmaansa. Muuan luotettava
henkilö on vakuuttanut minulle olleensa läsnä eräässä julkisessa
väittelyssä, jossa tahdottiin saada selville, oliko tupakanpoltto syntiä.
Vastaaja väitti, että paloviinasta luopuminen oli luvallista, mutta ei
tupakanpoltto, koska muka Pyhä kirja sanoo, että se, mikä tulee ulos
ihmisen suusta, saastuttaa hänet, mutta ei suinkaan se, mikä menee
sinne sisään.

Munkit eivät olleet tyytyväisiä näihin uudistuksiin. Tuskin oli tsaari


perustanut kirjapainoja, kun he käyttivät niitä hyväkseen hänen
parjaamisessaan. He painattivat, että hän oli Antikristus, ja
todistelivat väitettään sillä, että hän ajatti parran eläviltä ja
akatemiassaan antoi leikellä kuolleita. Mutta eräs toinen munkki,
joka tahtoi kiivetä onneen, väitti kirjan vääräksi ja todisti, ettei
Pietari voinut olla Antikristus, koska luku 666 ei sisältynyt hänen
nimeensä. Häväistyskirjan tekijä teilattiin, mutta vastakirjan laatija
korotettiin Rjäsanin piispaksi.

Venäjän uudistaja on muun muassa säätänyt erään viisaan lain,


joka saattaa häpeään monet sivistyneet valtiot. Se näet kielsi ketään
valtion virkamiestä tai porvariksi asettunutta taikka varsinkaan
alaikäistä menemästä luostariin.

Tämä ruhtinas käsitti, kuinka on tärkeätä estää sellaisia alamaisia,


jotka voivat olla hyödyksi, jättäytymästä joutilaisuuteen, samoin kuin
sellaisia määräämästä vapaasti itsestään, jotka ikänsä vuoksi eivät
vielä saaneet määrätä vapaasti omaisuudestaankaan. Kuitenkin
munkkien oveluus osaa joka päivä kiertää tätä ihmisyyden hyväksi
laadittua lakia, ikäänkuin munkeilla todellakin olisi hyötyä siitä, että
maansa kustannuksella kansoittavat luostareja.

Tsaari ei Turkin sulttaanien tavoin ainoastaan alistanut kirkkoa


valtion määräysvaltaan, vaan myös vielä suurempana valtiomiehenä
hävitti janitshaarien tapaisen sotaväen. Sen, mitä ottomaanit ovat
turhaan koettaneet tehdä, hän suoritti vähässä ajassa: hän hajoitti
moskovalaiset janitshaarit, nimeltä streltsit, jotka pitivät tsaareja
holhouksessaan. Tähän sotaväkeen, jota sen herrojen täytyi pelätä
enemmän kuin naapurien, kuului noin kolmekymmentätuhatta
jalkamiestä, joista toinen puoli majaili Moskovassa, toinen hajallaan
rajaseuduilla. Jokaisella streltsillä oli palkkaa vain neljä ruplaa
vuodessa, mutta heidän etuoikeutensa ja väärinkäytöksensä
korvasivat sen heille runsaasti. Pietari muodosti kohta yhden
komppanian muukalaista väkeä ja kirjoittautui siihen itsekin,
pitämättä arvolleen alentavana aloittaa uraansa rummunlyöjänä ja
palvella siitä asteittain ylöspäin, jotta kansa saisi hänestä hyvän
esimerkin. Vähitellen hän kohosi upseeriksi. Hiljaisuudessa hän
järjesteli uusia rykmenttejä, ja vihdoin, tuntiessaan olevansa kuriin
tottuneiden joukkojen käskijä, hän lakkautti streltsit, jotka eivät
uskaltaneet panna vastaan.

Ratsuväki oli miltei samanlainen kuin vieläkin on Puolan ratsuväki


ja kuin muinoin oli Ranskan, silloin kun Ranskan kuningaskunta oli
pelkkä rykelmä läänityksiä. Venäläiset aatelismiehet varustautuivat
ratsain omalla kustannuksellaan ja taistelivat ilman kuria, joskus
ilman muita aseita kuin sapeli tai nuolikotelo, kykenemättä
noudattamaan komentoa ja siis myöskään voittamaan.
Pietari Suuri opetti heidät tottelemaan omalla esimerkillään ja
ruumiinrangaistuksien avulla, sillä hän itse palveli tavallisena
sotamiehenä ja alempana upseerina ja rankaisi tsaarina ankarasti
pajareja eli aatelismiehiä, jotka väittivät aateliston etuoikeutena
muka olevan palvella valtiota ainoastaan oman tahtonsa mukaan.
Hän järjesti säännöllisen tykistöjoukon ja otti kirkoista viisisataa
kelloa kanuunain valamiseen. Hänellä olikin v. 1714 jo
tuhatkolmesataa metallikanuunaa. Samoin hän muodosti
rakuunajoukon, mikä aselaji hyvin soveltui venäläisten luonteeseen
ja heidän hevostensa pienikokoisuuteen: Venäjällä on nykyään (v.
1738) kolmekymmentä hyvin varustettua rakuunarykmenttiä, tuhat
miestä kussakin.

Myöskin husaarit hän on järjestänyt Venäjälle. Vieläpä hän lopuksi


perusti insinöörikoulun tuohon maahan, jossa kukaan ennen häntä ei
tuntenut edes mittausopin alkeita.

Hän itse oli kelpo insinööri, mutta erityisesti hän kunnostautui


kaikissa meriasiain taidoissa, ollen oivallinen laivakapteeni, taitava
luotsi, hyvä merimies, kätevä kirvesmies, mitkä kaikki taidot olivat
hänelle sitä suuremmaksi kunniaksi, kun hän luonnostaan kovasti
pelkäsi vettä. Nuoruudessaan hän ei voinut vapisematta kulkea
minkään sillan ylitse; hän antoi silloin sulkea vaununsa puiset
ikkunaluukut. Mutta miehuudellaan ja neroudellaan hän masensi
tämän vaistomaisen heikkoutensa.

Hän rakennutti Donin suulle Asovin luo kauniin sataman,


pitääkseen siellä kaleerilaivansa. Kun hän sittemmin oli varma siitä,
että nuo pitkät, matalat ja kepeät alukset voisivat kulkea
Itämerelläkin, niin hän rakennutti niitä yli kolmesataa
lempikaupunkinsa Pietarin luona. Hän opetti alamaisilleen taidon
rakentaa niitä tavallisesta kuusipuusta ja näytti heille, miten niitä
ohjataan. Vieläpä kirurgiaakin hän oli opiskellut; on nähty hänen
tarpeen tullen päästävän pois vettä vesitautisesta. Hän oli hyvin
selvillä myös mekaniikasta ja opetti sitä käsityöläisille.

Tsaarin rahavarat, hänen äärettömään valtakuntaansa verrattuina,


olivat todella mitättömät. Hänellä ei ole koskaan ollut tuloja 24
miljoonan arvosta, jos lasketaan markan vastaavan noin
viittäkymmentä livreä, kuten teemme vielä tänään, mutta emme
kenties enää huomenna. Mutta siinäpä rikkaus onkin, että voi
suorittaa suuria tekoja. Ei rahan puute tee valtakuntaa heikoksi,
vaan miesten ja kykyjen puute.

Venäjän kansa ei ole lukuisa, vaikkapa sen naiset ovatkin


hedelmällisiä ja miehet voimakkaita. Pietari itse, sivistyttäessään
valtakuntaansa, on valitettavasti edistänyt sen väestön vähentymistä.
Alituiset sotaväenotot hänen pitkän aikaa onnettomien sotiensa
kestäessä, väestön siirtämiset Kaspianmeren rannoilta Itämeren
partaille, niiden sortuminen töihin ja tuhoutuminen tauteihin, kolmen
neljättäosan lapsista kuoleminen Venäjällä rokkoon, mikä tässä
ilmanalassa on vaarallisempi kuin muualla, lopuksi pitkällisen ja
raa'an, vieläpä sivistyspuuhissaankin väkivaltaisen hallinnon surulliset
seuraukset ovat syynä siihen, että tässä suuressa mannermaan
osassa on vielä paljon autioita aroja. Nykyään lasketaan Venäjällä
olevan viisisataatuhatta perhettä aatelismiehiä, kaksisataatuhatta
virkasäätyyn kuuluvia, vähän yli viiden miljoonan porvareja ja
talonpoikia, jotka maksavat eräänlaista veroa, ja kuusisataatuhatta
asukasta Ruotsilta valloitetuissa maakunnissa. Ukrainan kasakoita ja
Venäjän vallan alaisia tataareja on noin kaksi miljoonaa. Kaiken
kaikkiaan on näiden äärettömien maa-alueiden laskettu sisältävän
ainoastaan neljätoista miljoonaa asukasta (v. 1727), mikä on vain
vähän enemmän kuin kaksi kolmannesta Ranskan väkiluvusta.

Tsaari Pietari, muuttaessaan maansa tavat, lait, sotalaitoksen ja


ulkoasun, tahtoi olla suuri myöskin kaupan alalla, mikä on yksityisen
valtion rikkauden ja samalla koko maailman hyödyn lähteenä. Hän
koetti tehdä Venäjästä Aasian ja Euroopan välisen kaupankäynnin
keskustan; hän tahtoi kanavilla, joihin hän itse laati suunnitelmat,
yhdistää Vienajoen, Volgan ja Donin toisiinsa ja avata uusia teitä
Itämerestä Mustaanmereen ja Kaspianmereen sekä näistä kahdesta
merestä Pohjoiseen Jäämereen.

Arkangelin satama, joka yhdeksän kuukautta vuodessa on jäiden


sulkema ja jonne päästiin vain pitkää ja vaarallista kiertotietä
myöten, ei näyttänyt hänestä kylliksi soveliaalta. Sentähden hän jo v.
1700 suunnitteli sataman rakentamista Itämeren rannalle, mistä
satamasta oli tuleva pohjoismaiden varastopaikka, ja kaupungin
perustamista, josta oli tuleva hänen valtakuntansa pääkaupunki.

Hän etsi jo kulkuväyliä koillisten merien kautta Kiinaan; Pariisin ja


Pekingin teollisuustuotteiden tuli koristaa hänen uutta kaupunkiaan.
Maantie, jonka pituus on 754 virstaa, tehtiin soiden keskitse, jotka
ensin täytyi kuivata, johtamaan Moskovasta hänen uuteen
kaupunkiinsa. Useimmat aikeistaan hän pani omakätisesti toimeen,
ja kaksi keisarinnaa, jotka seurasivat häntä perätysten, ovat vielä
jatkaneetkin hänen suunnitelmiaan, mikäli ne ovat olleet
toteutettavissa, ja jättäneet sikseen vain mahdottomat.

Hän matkusteli alituisesti valtakunnassaan, mikäli hänen sotansa


vain soivat siihen tilaisuutta. Mutta hän matkusteli sekä lainsäätäjänä
että lääkärinä, tutki kaikkialla luonnonsuhteita, koetti niitä korjata tai
täydentää, tarkasti itse jokien ja merien syvyyttä, järjesti sulkujen
rakennustöitä, tarkasteli laivaveistämöitä, avautti vuorikaivoksia,
tutki metalleja, teetti tarkkoja karttoja ja työskenteli siinä omin
käsin.

Hän rakennutti erämaahan keisarikaupunkinsa Pietarin, jossa


nykyään on kuusikymmentätuhatta taloa, jonne on syntynyt meidän
päivinämme loistava hovi ja jossa lopuksi jo tunnetaan elämän
hienotkin nautinnot. Nevan suulle hän rakennutti Kronstadtin
sataman, Persian rajalle Sainte-Croixin, Ukrainaan useita linnoituksia,
samoin Siperiaan; Arkangeliin, Pietariin, Astrakaniin ja Asoviin hän
perusti merisotavirastoja; lisäksi asevarastoja ja sairaaloita. Kaikki
tavalliset talot hän rakennutti pieniä ja jotenkin mauttomia, mutta
julkiset rakennukset hän teetti sangen komeita ja suuria.

Tieteet, jotka muualla ovat olleet niin monien vuosisatojen hitaasti


kypsyviä hedelmiä, ovat hänen huolenpidostaan tulleet hänen
valtakuntaansa aivan täydellisessä muodossa. Hän perusti akatemian
Pariisin ja Lontoon kuuluisain seurain malliin: Delisle, Bulfinger,
Hermann, Bernouilli ja kuuluisa, kaikissa filosofian haaroissa etevä
Wolf kutsuttiin suurin kustannuksin Pietariin. Tämä akatemia on
vieläkin olemassa, ja siinä kehittyy jopa venäläisiä filosofejakin.

Hän pakoitti maansa aatelisen nuorison matkustelemaan,


opiskelemaan, tuomaan Venäjälle ulkomaiden hienoja tapoja. Olen
nähnyt sellaisia nuoria venäläisiä, jotka olivat erittäin henkeviä ja
tietorikkaita. Siten on tämä yksi ainoa mies muuttanut aivan toiseen
muotoon maailman suurimman valtakunnan. Paha vain, että tältä
suurelta ihmisten uudistajalta itseltään puuttui kaikkein ensimäinen
hyve, ihmisyys. Hänen huvitustensa raakuus, hänen tapojensa
villeys, hänen kostonsa julmuus himmensivät hänen suuria avujansa.
Hän sivistytti kansaansa, mutta oli itse raakalainen. Omin käsin hän
pani täytäntöön rikollisille määräämiään rangaistuksia, ja remuavissa
syömingeissään hän osoitti taitavuuttaan kaulojen katkaisussa.
Afrikassa on kyllä hallitsijoita, jotka omin käsin vuodattavat
alamaistensa verta, mutta näitä yksinvaltiaita pidetäänkin
raakalaisina. Oman pojan surmauttaminen, silloin kun kuritus tai
perinnöttömäksi tekeminen olisi riittänyt, tekisi Pietarin muiston
vihatuksi, jollei se hyvä, mitä hän on tehnyt alamaisilleen, saisi miltei
suomaan anteeksi hänen omaa vertansa vastaan osoittamaansa
julmuutta.

Sellainen oli tsaari Pietari, ja hänen suuret suunnitelmansa olivat


vasta alkuluonnoksia silloin kun hän liittyi Puolan ja Tanskan
kuninkaihin heidän kaikkien halveksimaa lasta vastaan. Venäjän
perustaja tahtoi samalla olla valloittaja; hän luuli voivansa tulla siksi
ilman suurempaa vaivaa, varsinkin kun senlaatuinen sota olisi vain
hyödyksi hänen muille suunnitelmilleen. Sotataito oli samoin uusi
taito, joka hänen tuli opettaa kansalleen.

Sitäpaitsi hän tarvitsi satamaa Itämeren itärannalla, voidakseen


panna kaikki aatteensa toimeen. Hän tarvitsi Inkerinmaata, joka
sijaitsee koilliseen Liivinmaasta. Siellä olivat isäntinä ruotsalaiset;
siispä se täytyi temmata heiltä pois. Hänen edeltäjillään oli ollut
oikeuksia Inkerin-, Viron- ja Liivinmaahan; aika näytti suotuisalta
saattaa uudelleen voimaan nuo oikeudet, jotka oli menetetty jo sata
vuotta sitten ja rauhanteoissa julistettu mitättömiksi. Hän teki
senvuoksi liiton Puolan kuninkaan kanssa, riistääkseen nuorelta
Kaarle XII:lta kaikki ne alueet, jotka sijaitsevat Suomenlahden,
Itämeren, Puolan ja Venäjän välissä.
TOINEN KIRJA.

Ihmeellinen ja äkillinen muutos Kaarle XII:n luonteessa.


Kahdeksantoistavuotiaana hän käy sotaa Tanskaa, Puolaa ja Venäjää
vastaan, päättää Tanskan-sotansa kuudessa viikossa, lyö kahdeksalla
tuhannella ruotsalaisella kahdeksankymmentä tuhatta venäläistä ja
hyökkää Puolaan. Puolan ja sen hallinnon kuvaus. Kaarle voittaa
useita taisteluja, pääsee Puolan herraksi ja valmistautuu
nimittämään sinne uuden kuninkaan.

Kolme mahtavaa ruhtinasta uhkasi siten Kaarle XII:n nuoruutta.


Sodan valmisteluja koskevat huhut levittivät Ruotsissa hämmästystä
ja säikähdyttivät valtakunnanneuvostoa. Suuret kenraalit olivat
kuolleet; oli täysi syy pelätä pahinta nuoren kuninkaan johdossa,
joka siihen saakka oli osoittanut vain huonoja puoliansa.
Neuvostossa hän ei tehnyt koskaan juuri muuta kuin nosti säärensä
ristiin pöydälle; hajamielisenä, välinpitämättömänä hän ei näyttänyt
ottavan mihinkään osaa.

Neuvosto harkitsi hänen läsnäollessaan vaaraa, johon oli jouduttu;


muutamat neuvosherrat ehdottivat myrskyn kääntämistä
neuvottelujen avulla; silloin yhtäkkiä nuori ruhtinas nousee pystyyn,
kasvoillaan päätöksensä tehneen korkeamman ihmisen vakavuus ja
varmuus. "Hyvät herrat", hän sanoi, "olen päättänyt olla koskaan
käymättä väärää sotaa, mutta myöskin olla lopettamatta oikeaa,
ennenkuin viholliseni ovat tuhotut. Päätökseni on tehty: käyn sen
kimppuun, joka ensimäisenä julistaa sodan, ja hänet voitettuani
toivon voivani hieman pelottaa toisiakin." — Nämä sanat
hämmästyttivät kaikkia noita vanhoja neuvosherroja: he katselivat
toisiaan tohtimatta vastata. Vihdoin he, kummissaan siitä, että heillä
oli moinen kuningas ja häveten toivoa vähemmin kuin hän, ottivat
ihmetellen vastaan hänen sotaa koskevat määräyksensä.

Yllätys tuli vielä suuremmaksi, kun nähtiin hänen heti paikalla


luopuvan nuoruuden viattomimmistakin huvituksista. Siitä hetkestä
alkaen, jolloin hän ryhtyi sotavalmistuksiin, hän aloitti aivan uuden
elämän, josta hän sittemmin ei koskaan hetkeksikään poikennut.
Ajatellen alituisesti Aleksanteria ja Caesaria hän päätti jäljitellä näitä
kahta valloittajaa kaikessa muussa paitsi heidän vioissaan. Hän ei
tahtonut enää tietää mitään komeudesta, leikeistä tai huvituksista;
hän supisti ateriansa mitä suurimpaan kohtuullisuuteen. Hän oli
rakastanut komeita pukuja; tästedes hän pukeutui aivan kuin halpa
sotilas. Oli luultu hänen olleen kiintynyt erääseen hovinsa naiseen;
olkoonpa tämän jutun laita miten tahansa, totta ainakin on, että hän
nyt ainiaaksi kieltäytyi naisista, ei ainoastaan pelosta joutua heidän
talutusnuoraansa, vaan myös halusta antaa siinä esimerkkiä
sotilailleen, joita hän tahtoi pitää mitä ankarimmassa kurissa; kenties
myös turhamaisuudesta olla ainoa kaikkien kuninkaiden joukossa,
joka kykeni hillitsemään niin vaikeasti masennettavan taipumuksen.
Samoin hän päätti pidättyä viinistä koko vastaisen elämänsä ajan.
Jotkut ovat vakuuttaneet minulle, että hän teki mainitun päätöksen
voittaakseen täydellisesti luontonsa ja lisätäkseen uuden hyveen
sankarimaisuuteensa. Useimmat ovat kuitenkin vakuuttaneet
minulle, että hän tahtoi siten rangaista itseään erään sopimattoman
hurjistelun vuoksi ja häväistyksen johdosta, jonka hän pöydässä
äitinsä, kuningattaren, läsnäollessa oli tuottanut eräälle naiselle. Jos
asianlaita on sellainen, niin tämä itsensä tuomitseminen ja tämä
kieltäytyminen, johon hän alistui koko elämänsä ajaksi, osoittavat
sankaruutta, joka ei ole vähemmän ihmeteltävää.

Hän aloitti sodan vakuuttamalla langolleen, Holsteinin herttualle,


apuansa. Heti lähetettiin kahdeksantuhatta miestä Holsteinin
naapurimaakuntaan Pommeriin suojelemaan herttuaa tanskalaisten
hyökkäyksiltä. Herttua tarvitsikin tukea, sillä tanskalaiset olivat jo
havitelleet hänen maitansa, valloittaneet hänen linnansa Gottorpin ja
piirittivät parhaillaan itsepintaisesti hänen kaupunkiaan Tönningeniä,
jonka luo Tanskan kuningas oli mieskohtaisesti saapunut nauttimaan
varmaksi luulemastaan valloituksesta. Tämä kipinä uhkasi sytyttää
liekkiin koko Saksan valtakunnan. Yhdeltä puolelta marssivat Puolan
kuninkaan saksilaiset joukot, Brandenburgin, Wolfenbüttelin ja
Hessen-Kasselin rykmentit, yhtyäkseen tanskalaisiin; toiselta puolelta
Ruotsin kuninkaan kahdeksantuhatta miestä ynnä Hannoverin ja
Cellen joukot kiirehtivät herttuan avuksi.

Holsteinin pienen maan ollessa siten sotanäyttämönä ilmestyivät


Englannin ja Hollannin laivastot Itämerelle. Nämä kaksi valtaa olivat
tanskalaisten rikkoman Altonan sopimuksen takaajia; nyt he
kiiruhtivat Holsteinin ahdistetun herttuan avuksi, koska Tanskan
kuninkaan mahdin suureneminen ei soveltunut heidän
kauppaetuihinsa. He tiesivät tanskalaisten Juutinrauman isäntinä
tulevan raskaasti verottamaan kauppaa käyviä kansoja, kunhan vain
tuntisivat itsensä kyllin voimakkaiksi, voidakseen tehdä sen
rankaisematta. Tämä harrastus on pitkät ajat saattanut Englannin ja
Hollannin, mikäli se heille on ollut mahdollista, pitämään yllä
tasapainoa pohjoismaisten ruhtinaitten kesken. He liittyivät
sentähden nyt Ruotsin nuoreen kuninkaaseen, kun tämä näytti
olevan vaarassa joutua niin monien yhtyneitten vihollisten
muserrettavaksi, ja auttoivat häntä siitä samasta syystä, jonka
vuoksi häntä ahdistettiinkin, koska näet luultiin, ettei hän kykenisi
puolustautumaan.

Hän oli metsästämässä karhuja, saadessaan tiedon saksilaisten


hyökkäyksestä Liivinmaahan; hän harjoitti tätä urheilua yhtä uudella
kuin vaarallisellakin tavalla. Siinä ei käytetty mitään muita aseita kuin
haarukkamaisia seipäitä puihin kiinnitetyn verkon takana.
Tavattoman suuri karhu hyökkäsi kerran suoraan kuninkaan
kimppuun, joka pitkällisen ottelun perästä, verkon ja seipään avulla,
kaatoi sen maahan. On myönnettävä, että kuullessaan moisista
seikkailuista, kuningas Augustin ihmeellisistä voimista ja tsaarin
matkoista, luulee siirtyneensä Herkuleen ja Theseuksen aikoihin.

Hän lähti ensimäiselle sotaretkelleen 8 päivänä toukokuuta, uutta


lukua, v. 1700, jättäen Tukholman, jonne hän ei enää koskaan
palannut. Ääretön kansanpaljous saattoi häntä aina Karlskronan
satamaan saakka, toivottaen hänelle onnea, vuodattaen kyyneleitä ja
ihastellen häntä. Ennen Ruotsista lähtöään hän asetti Tukholmaan
useista senaattoreista muodostetun puolustusneuvoston. Tämän
toimikunnan tuli pitää huolta kaikesta, mikä koski laivastoa,
sotajoukkoa ja maan linnoituksia. Koko senaatin tuli väliaikaisesti
johtaa kaikkia muita valtakunnan sisäisiä asioita. Saatuaan täten
valtakunnassaan kaikki varmaan järjestykseen hän koko sielullaan,
vapaana kaikista muista huolista, antautui yksinomaan sota-asioihin.
Hänen laivastoonsa kuului neljäkymmentäkolme alusta; siinä, johon
hän itse nousi ja jonka nimi oli Kuningas Kaarle, oli
satakaksikymmentä kanuunaa. Kreivi Piper, hänen pääministerinsä,
ja kenraali Rehnsköld astuivat laivaan hänen kanssaan. Pian hän
tapasi liittolaisten merivoimat. Tanskan laivasto vältti taistelua ja salli
noiden kolmen yhtyneen laivaston lähestyä niin likelle
Köpenhaminaa, että he voivat ampua sinne muutamia pommeja.

On varmaa, että juuri kuningas itse nyt ehdotti kenraali


Rehnsköldille maallenousua ja Köpenhaminan saartamista maan
puolelta, samalla kun se oli saarroksissa merenkin puolelta.
Rehnsköld hämmästyi moista ehdotusta, joka osoitti yhtä suurta
taitavuutta kuin rohkeuttakin nuoressa ja kokemattomassa
ruhtinaassa. Pian oli kaikki kunnossa maallenousua varten. Annettiin
käsky viedä laivoihin viisituhatta Ruotsin rannikolla majailevaa
miestä, jotka nyt liitettiin jo ennestään laivastossa oleviin joukkoihin.
Kuningas jätti suuren laivansa ja astui kepeähköön fregattiin. Aluksi
laskettiin kolmesataa krenatööriä pienissä pursissa kulkemaan edellä.
Näiden pursien välissä matalakulkuiset veneet kuljettivat
risukimppuja, hirsipaalustoja ja vallintekijäin työkaluja.
[Suojuslaitteita, jotka vastaavat nykyajan piikkilanka-aitoja. Noin 5-6
m pituisen hirren läpi oli pistelty ristiin teräväkärkisiä, usein
rautapiikeillä varustettuja paaluja ("espanjalainen ratsuri"). — Suom.
muist.] Viisisataa valiomiestä seurasi toisissa pursissa. Sitten tulivat
kuninkaan sotalaivat ynnä kaksi englantilaista ja kaksi hollantilaista
fregattia, joiden piti kanuunoillaan suojella maallenousua.

Tanskan pääkaupunki Köpenhamina sijaitsee Seelannin saarella,


keskellä kaunista tasankoa, kaakkoon Juutinraumasta ja länteen
Itämerestä, missä silloin oli Ruotsin kuningas. Nähdessään laivojen
odottamattoman liikehtimisen, joka ennusti maallenousua, asukkaat
laivastonsa toimettomuudesta ja ruotsalaisten laivojen liikkeistä
tyrmistyneinä katselivat pelon vallassa, mihin paikkaan hirmumyrsky
purkautuisi. Kaarlen laivasto pysähtyi vastapäätä Humblebekiä,
seitsemän penikulmaa Köpenhaminasta. — Tanskalaiset kokosivat
heti ratsuväkensä tähän kohtaan. Nostoväkeä sijoitettiin paksujen
rintasuojusten taa, ja ne tykit, jotka voitiin kuljettaa paikalle,
suunnattiin ruotsalaisia kohti.

Kuningas jätti nyt fregattinsa asettuakseen ensimäiseen purteen


kaartinsa etunenään. Ranskan lähettiläs oli silloin hänen seurassaan.

"Herra lähettiläs", sanoi kuningas hänelle latinaksi, sillä hän ei


tahtonut milloinkaan käyttää ranskaa, "teillä ei ole mitään tekemistä
tanskalaisten kanssa, suvaitkaa siis pysyä loitommalla". — "Sire",
vastasi kreivi de Guiscard hänelle ranskaksi, "herrani kuningas on
määrännyt minut oleskelemaan teidän majesteettinne läheisyydessä;
rohkenen olettaa, että te ette juuri tänään karkoita minua
hovistanne, joka ei milloinkaan ole ollut niin loistava".

Näin sanoen hän tarjosi kätensä kuninkaalle, joka hyppäsi


purteen, johon myöskin kreivi Piper ja lähettiläs astuivat.
Laivatykkien ammunnan suojellessa maihinnousua mentiin
eteenpäin. Maihinnousuveneet olivat enää ainoastaan kolmensadan
askeleen päässä rannasta. Kaarle XII, malttamatta odottaa, kunnes
olisi ehditty päästä kylliksi lähelle rantaa, hyppäsi purrestaan mereen
miekka kädessä, veden ulottuessa häntä vyötäisiin. Hänen
ministerinsä, Ranskan lähettiläs, upseerit ja sotamiehet seurasivat
heti esimerkkiä ja lähestyivät rantaa, huolimatta muskettitulen
kuulasateesta. Kuningas, joka ei vielä koskaan elämässään ollut
kuullut musketinkuulien vinkunaa, kysyi päämajoitusmestari
Stuartilta, joka sattui olemaan hänen vieressään, mitä tuo hieno
viuhina oli, jonka hän kuuli korvissansa.

"Se on niiden pyssynkuulien vinkunaa, joita ammutaan meitä


kohti", vastasi majoitusmestari. — "Hyvä!" sanoi kuningas, "se on
vastedes oleva minun musiikkiani". — Samassa tuokiossa
majoitusmestari, joka juuri oli selittänyt musketinkuulien vinkunaa,
sai niistä yhden olkaansa, ja eräs luutnantti kaatui hengetönnä
kuninkaan toisella sivulla.

On tavallista, että ne joukot, joiden kimppuun käydään heidän


varustuksissaan, tulevat lyödyiksi, koska hyökkääjät aina ovat täynnä
hurjaa intoa, jota eivät voi tuntea ne, jotka vain puolustautuvat, ja
koska vihollisen odottaminen vallitusten takana useinkin on vain
oman heikommuuden ja vihollisen voimakkaammuuden
tunnustamista. Tanskalainen ratsuväki ja nostoväki pakenivat heikon
vastarinnan jälkeen. Päästyään heidän varustustensa herraksi
kuningas heti heittäytyi polvilleen kiittääkseen Jumalaa aseittensa
ensimäisestä menestyksestä. Hän laitatti heti varustuksia kaupungin
puolelle ja merkitsi itse leiripaikan. Samalla hän lähetti laivansa
Skooneen, joka on Kööpenhaminaa lähinnä oleva Ruotsin osa,
hakemaan sieltä yhdeksäntuhatta miestä apuväkeä. Kaikki
asianhaarat liittoutuivat suosimaan Kaarlen malttamattomuutta: nuo
yhdeksäntuhatta miestä seisoivat rannalla valmiina astumaan
laivoihin, ja jo seuraavana päivänä myötäinen tuuli toi ne hänelle
avuksi.

Kaikki tämä oli tapahtunut tanskalaisen laivaston näkyvissä, joka ei


ollut rohjennut lähestyä. Säikähtynyt Köpenhamina lähetti heti
valtuutettuja kuninkaan luo pyytämään, ettei hän pommittaisi
kaupunkia. Hän otti heidät vastaan ratsain kaartinrykmenttinsä
etunenässä; valtuutetut laskeutuivat polvilleen hänen edessään. Hän
määräsi kaupungin maksamaan 400,000 riikintaaleria pakkoveroa ja
käski tuoda leiriinsä kaikenlaatuisia elintarpeita, jotka lupasi
säntillisesti maksaa. Hänelle tuotiinkin elintarpeita, koska oli
täytymys totella, mutta ei ollenkaan osattu odottaa, että voittajat
suvaitsisivat niistä suorittaa korvauksen. Tuojat hämmästyivätkin
kovin, kun armeijan halvimmatkin sotamiehet maksoivat heille
kaikesta runsaasti ja viipymättä.

Jo kauan aikaa oli Ruotsin sotajoukoissa vallinnut sellainen kuri,


joka melkoisesti oli edistänyt heidän voittojansa; nuori kuningas vielä
kovensi sen ankaruutta. Sotamies ei olisi uskaltanut kieltäytyä
maksamasta ostoksiaan, vielä vähemmän lähteä ryöstelemään, eipä
edes poistua leiristä. Lisäksi hän tahtoi, että hänen joukkonsa eivät
voiton jälkeen ryhtyisi ryöstämään kuolleita, ennenkuin olivat
saaneet siihen luvan, ja helposti hän saikin aikaan, että tätä
määräystä toteltiin. Kahdesti päivässä pidettiin hänen leirissään aina
rukoushetki: kello seitsemän aamulla ja kello neljä iltapäivällä. Itse
hän ei koskaan laiminlyönyt olla silloin läsnä ja siten antaa
sotamiehilleen esimerkkiä hurskaudesta, joka aina vaikuttaa ihmisiin,
kun nämä eivät epäile siinä mitään ulkokultaisuutta. Hänen
leirissään, jossa vallitsi parempi järjestys kuin Köpenhaminassa, oli
kaikkea yltäkylläisesti. Talonpojat möivät mieluummin
ruokatavaransa ruotsalaisille, vihollisilleen, kuin tanskalaisille, jotka
eivät niistä maksaneet niin hyvin. Kaupungin porvarien täytyikin
useammin kuin kerran tulla Ruotsin kuninkaan leiriin etsimään
elintarpeita, joita ei ollut saatavissa heidän toreiltaan.

Tanskan kuningas oli silloin Holsteinissa, jonne hän näytti


lähteneen ainoastaan lakkauttamaan Tönningenin piiritystä. Hän näki
vihollislaivojen peittävän Itämerta, nuoren valloittajan olevan jo
Seelannin herrana ja valmiina valtaamaan hänen pääkaupunkinsa.
Hän julistutti alueillaan, että ne, jotka tarttuivat aseihin ruotsalaisia
vastaan, pääsisivät vapaiksi maaorjuudesta. Tämä julistus oli sangen
tärkeäarvoinen maassa, joka aikaisemmin oli ollut vapaa ja jossa
nykyään kaikki talonpojat, vieläpä paljon porvaristoakin ovat
maaorjia. Kaarle käski ilmoittaa Tanskan kuninkaalle käyvänsä sotaa
ainoastaan pakoittaaksensa hänet rauhantekoon; hänen tuli siis pian
sallia Holsteinin herttuan päästä jälleen oikeuksiinsa, tai muutoin hän
saisi nähdä Köpenhaminan tuhottuna ja kuningaskuntansa alttiina
tulelle ja verelle. Tanskalainen oli kovin onnellinen siitä, että oli
tekemisissä voittajan kanssa, joka näytti harrastavan vain oikeutta.
Niinpä kokoonnuttiinkin neuvottelemaan Traventhalin kaupunkiin
Holsteinin rajalle. Ruotsin kuningas ei suvainnut, että ministerien
taito pääsisi viivyttämään asiain käsittelyä; hän tahtoi, että
rauhanteko kävisi yhtä nopeasti kuin hänen maihinnousunsa
Seelantiin. Todellakin saatiin sopimus aikaan 5 p:nä elokuuta
Holsteinin herttuan eduksi, joka sai korvauksen kaikista
sotakuluistaan ja vapautui ahdistajastaan. Ruotsin kuningas ei
tahtonut mitään itselleen, hän oli tyytyväinen siihen, että oli
pelastanut liittolaisensa ja nöyryyttänyt vihollisensa. Siten Kaarle XII,
kahdeksantoistavuotiaana, aloitti ja lopetti tämän sodan
vähemmässä kuin kuudessa viikossa.

Aivan samaan aikaan Puolan kuningas saartoi Liivinmaan


pääkaupungin Riian, ja tsaari samosi idästä päin lähes
sadantuhannen miehen etunenässä. Riikaa puolusti vanha
ruotsalainen kenraali, kreivi Dahlberg, jossa
kahdeksankymmenvuotiaana yhtyi nuorukaisen palavaan intoon
kuudenkymmenen sotaretken kokemus. Kreivi Flemming, sittemmin
Puolan ministeri, yhtä etevä soturina kuin hallitusmiehenä, ja
liiviläinen Patkul jouduttivat yhdessä piiritystä kuninkaan nähden.
Mutta useista piirittäjäin saavuttamista eduista huolimatta vanhan
kreivi Dahlbergin kokeneisuus teki heidän ponnistuksensa tyhjiksi, ja
Puolan kuningas olikin epätoivoinen kaupungin valloitukseen nähden.
Vihdoin hän käytti tilaisuutta luopuakseen kunnialla piirityksestä.
Riika oli näet täynnä hollantilaisille kuuluvia tavaroita. Hollannin
yleis-eduskunta käski kuningas Augustin luona olevan lähettiläänsä
tehdä asiasta hänelle esityksiä, ja Puolan kuningasta ei tarvittukaan
kauan rukoilla. Hän suostui lakkauttamaan piirityksen mieluummin
kuin tuottamaan pienintäkään vahinkoa liittolaisilleen, jotka
puolestaan eivät ollenkaan hämmästyneet tätä hyväntahtoisuuden
puuskaa, johon he itse olivat todellisena syynä.

Päättääksensä ensimäisen sotaretkensä Kaarle XII:lla ei siis enää


ollut muuta tehtävää kuin marssia Pietari Aleksejevitshia vastaan,
joka tahtoi kilpailla hänen kanssaan kunniasta. Hän oli tälle sitäkin
enemmän suutuksissaan, kun Tukholmassa vielä oli kolme
moskovalaista lähettilästä, jotka vastikään olivat vannoneet
rikkomattoman rauhan uudistamisen. Hän, joka harrasti mitä
ankarinta rehellisyyttä, ei voinut ymmärtää, miten tsaarin tapainen
lainsäätäjä voi leikitellä niin pyhän ja korkean asian kanssa. Nuori
ruhtinas oli kunniantunnossaan sitä mieltä, ettei kuninkaita varten
saanut olla eri moraalia kuin yksityisille. Venäjän tsaari oli sillä välin
julkaissut manifestin, jonka hän paremminkin olisi saanut jättää
julkaisematta. Siinä hän mainitsi sodankäyntijulistuksensa syyksi,
ettei hänelle ollut osoitettu kylliksi kunnioitusta, kun hän incognito
[tuntematonna, salanimellä. — Suom. muist.] matkusti Riian kautta,
ja että hänen lähettiläilleen oli myöty elintarpeita liian kalliista
hinnasta. Nämä olivat ne valitukset, joiden vuoksi hän antoi
kahdeksankymmenen tuhannen miehen hävittäen hyökätä
Inkerinmaahan.

Hän ilmestyi Narvan eteen tämän suuren armeijan[11] etupäässä


1 p:nä lokakuuta, mikä vuodenaika tässä ilmanalassa on raaempi
kuin tammikuun Pariisissa. Tsaari, joka sellaisessa säässä joskus
matkusti postihevosilla neljäkinsataa penikulmaa, käydäkseen omin
silmin tarkastamassa jotakuta kaivosta tai kanavaa, ei säästänyt
sotamiehiään enemmän kuin itseäänkään. Sitäpaitsi hän tiesi
ruotsalaisten Kustaa Aadolfin ajoista lähtien voivan käydä sotaa
sydäntalvella yhtä hyvin kuin kesälläkin; hän tahtoi sentakia totuttaa
myös venäläisensäkin olemaan riippumattomia vuodenajoista,
tehdäkseen siten heidät kerran ainakin ruotsalaisten vertaisiksi.

Niinpä siis juuri sellaisena aikana, jolloin lauhkeammassa


ilmanalassa jää ja lumi pakoittavat muut kansat keskeyttämään
sodan, tsaari Pietari ryhtyi piirittämään Narvaa, joka sijaitsi
kolmekymmentä astetta pohjoisnavasta etelään, ja Kaarle XII samosi
sen avuksi. Tuskin oli tsaari saapunut kaupungin ääreen, kun hän jo
kiiruhti panemaan käytäntöön kaikkea sitä, mitä oli matkoillaan
oppinut. Hän suunnitteli leirin, varusti sen joka puolelta, rakennutti
määrävälien päähän toisistaan linnakkeita ja kaivatti juoksuhautoja.
Hän oli jättänyt armeijansa ylipäällikkyyden herttua de Croylle,
taitavalle saksalaiselle kenraalille,[12] jota venäläiset upseerit eivät
kuitenkaan silloin riittävästi avustaneet. Hänellä itsellään oli
sotajoukossaan pelkkä luutnantin arvo. Hän tahtoi siten antaa
esimerkin sotilaallisesta kuuliaisuudestaan siihen saakka kurittomalle
aatelistolleen, joka kykeni vain ilman kokemusta ja järjestystä
johtamaan huonosti asestettuja orjia. Ei ollutkaan mitään
ihmeteltävää siinä, että se mies, joka Amsterdamissa oli ruvennut
kirvesmieheksi, saadakseen itselleen laivaston, esiintyi Narvan luona
luutnanttina, voidakseen opettaa kansalleen sotataitoa.

Venäläiset ovat voimakkaita, väsymättömiä, kenties yhtä rohkeita


kuin ruotsalaisetkin; mutta vasta ajanmittaan sotajoukot tottuvat
sotatoimiin ja vain kuri tekee heidät voittamattomiksi. Ainoat
rykmentit, joilta voitiin odottaa jotakin, olivat saksalaisten upseerien
komentamia; mutta niitä oli vain muutamia. Muu joukko oli
metsistään ajettuja raakalaisia, puettuina petoeläinten nahkoihin,
toiset varustettuina jousilla, toiset nuijilla; vain harvoilla oli pyssy;
kukaan ei ollut nähnyt säännöllistä piiritystä. Koko armeijassa ei ollut
yhtään ainoaa kelvollista tykkimiestä. Ne sataviisikymmentä tykkiä,
jotka helposti olisivat voineet ampua Narvan pienen kaupungin
mäsäksi, olivat tuskin saaneet syntymään aukkoa muuriin, samalla
kun kaupungin tykistö joka hetki tuhosi kokonaisia rivejä
juoksuhaudoissa. Narva oli melkein linnoittamaton; vapaaherra
Hornilla, joka siellä oli päällikkönä, ei ollut käytettävänään täyttä
tuhatta miestä säännöllistä sotaväkeä. Kuitenkaan tuo suunnaton
armeija ei ollut kyennyt vielä kuudessa viikossa valtaamaan
kaupunkia.

Oli jo marraskuun 15 päivä, kun tsaari sai kuulla Ruotsin


kuninkaan kahdellasadalla kuljetuslaivalla tulleen meren yli ja
marssivan parhaillaan Narvan avuksi. Ruotsalaisia oli ainoastaan
kaksikymmentätuhatta, mutta tsaarilla olikin vain miesten paljous
etunaan. Ollenkaan halveksimatta vihollistaan hän päinvastoin käytti
kaiken taitonsa musertaakseen hänet.

Tyytymättä kahdeksaankymmeneentuhanteen mieheensä hän


valmistautui asettamaan Kaarlea vastaan vielä toisenkin armeijan ja
pidättämään häntä joka askeleella. Hän oli jo määrännyt siihen
kolmekymmentätuhatta miestä, jotka nyt riensivät pikamarsseissa
Pihkovasta käsin. Sitten hän teki tempun, joka olisi herättänyt
halveksimista, jos sellainen olisi mahdollista lainsäätäjää kohtaan,
joka on suorittanut niin suuria asioita. Hän jätti leirinsä, missä hänen
läsnäolonsa oli välttämätön, muka hakeakseen tuon uuden joukko-
osaston, joka ilman häntäkin olisi voinut varsin hyvin saapua, ja
näytti siis ikäänkuin pelkäävän taistella linnoitetussa leirissään
nuorta, kokematonta ruhtinasta vastaan, joka saapui häntä
ahdistamaan.
Welcome to our website – the perfect destination for book lovers and
knowledge seekers. We believe that every book holds a new world,
offering opportunities for learning, discovery, and personal growth.
That’s why we are dedicated to bringing you a diverse collection of
books, ranging from classic literature and specialized publications to
self-development guides and children's books.

More than just a book-buying platform, we strive to be a bridge


connecting you with timeless cultural and intellectual values. With an
elegant, user-friendly interface and a smart search system, you can
quickly find the books that best suit your interests. Additionally,
our special promotions and home delivery services help you save time
and fully enjoy the joy of reading.

Join us on a journey of knowledge exploration, passion nurturing, and


personal growth every day!

ebookbell.com

You might also like