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

Python Debugging for AI, Machine Learning, and Cloud Computing: A Pattern-Oriented Approach 1st Edition Dmitry Vostokov instant download

The document promotes the ebook 'Python Debugging for AI, Machine Learning, and Cloud Computing: A Pattern-Oriented Approach' by Dmitry Vostokov, available for download at ebookmass.com. It includes links to various related titles and offers a comprehensive overview of debugging patterns and methodologies. The content covers fundamental vocabulary, pattern-oriented debugging, and specific debugging patterns for different scenarios.

Uploaded by

kireikurtes
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
11 views

Python Debugging for AI, Machine Learning, and Cloud Computing: A Pattern-Oriented Approach 1st Edition Dmitry Vostokov instant download

The document promotes the ebook 'Python Debugging for AI, Machine Learning, and Cloud Computing: A Pattern-Oriented Approach' by Dmitry Vostokov, available for download at ebookmass.com. It includes links to various related titles and offers a comprehensive overview of debugging patterns and methodologies. The content covers fundamental vocabulary, pattern-oriented debugging, and specific debugging patterns for different scenarios.

Uploaded by

kireikurtes
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 79

Download the full version and explore a variety of ebooks

or textbooks at https://ebookmass.com

Python Debugging for AI, Machine Learning, and


Cloud Computing: A Pattern-Oriented Approach 1st
Edition Dmitry Vostokov

_____ Follow the link below to get your download now _____

https://ebookmass.com/product/python-debugging-for-ai-
machine-learning-and-cloud-computing-a-pattern-oriented-
approach-1st-edition-dmitry-vostokov/

Access ebookmass.com now to download high-quality


ebooks or textbooks
We have selected some products that you may be interested in
Click the link to download now or visit ebookmass.com
for more options!.

Python Debugging for AI, Machine Learning, and Cloud


Computing: A Pattern-Oriented Approach 1st Edition
Vostokov
https://ebookmass.com/product/python-debugging-for-ai-machine-
learning-and-cloud-computing-a-pattern-oriented-approach-1st-edition-
vostokov/

Fundamentals of Trace and Log Analysis: A Pattern-Oriented


Approach to Monitoring, Diagnostics, and Debugging 1st
Edition Dmitry Vostokov
https://ebookmass.com/product/fundamentals-of-trace-and-log-analysis-
a-pattern-oriented-approach-to-monitoring-diagnostics-and-
debugging-1st-edition-dmitry-vostokov-2/

Fundamentals of Trace and Log Analysis A Pattern-Oriented


Approach to Monitoring, Diagnostics, and Debugging 1st
Edition Dmitry Vostokov
https://ebookmass.com/product/fundamentals-of-trace-and-log-analysis-
a-pattern-oriented-approach-to-monitoring-diagnostics-and-
debugging-1st-edition-dmitry-vostokov/

Foundations of ARM64 Linux Debugging, Disassembling, and


Reversing Dmitry Vostokov

https://ebookmass.com/product/foundations-of-arm64-linux-debugging-
disassembling-and-reversing-dmitry-vostokov/
Artificial Intelligence and Machine Learning for EDGE
Computing 1st Edition Rajiv Pandey

https://ebookmass.com/product/artificial-intelligence-and-machine-
learning-for-edge-computing-1st-edition-rajiv-pandey/

Productionizing AI: How to Deliver AI B2B Solutions with


Cloud and Python 1st Edition Barry Walsh

https://ebookmass.com/product/productionizing-ai-how-to-deliver-
ai-b2b-solutions-with-cloud-and-python-1st-edition-barry-walsh/

Financial Machina: Machine Learning For Finance: The


Quintessential Compendium for Python Machine Learning For
2024 & Beyond Sampson
https://ebookmass.com/product/financial-machina-machine-learning-for-
finance-the-quintessential-compendium-for-python-machine-learning-
for-2024-beyond-sampson/

Productionizing AI: How to Deliver AI B2B Solutions with


Cloud and Python 1st Edition Barry Walsh

https://ebookmass.com/product/productionizing-ai-how-to-deliver-
ai-b2b-solutions-with-cloud-and-python-1st-edition-barry-walsh-2/

Machine Learning Guide for Oil and Gas Using Python Hoss
Belyadi

https://ebookmass.com/product/machine-learning-guide-for-oil-and-gas-
using-python-hoss-belyadi/
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
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 [email protected]; for reprint,
paperback, or audio rights, please e-mail [email protected].
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
Other documents randomly have
different content
lectured for three years on the Practice of Physic, and then he and
Cullen agreed to give alternate lectures on the Theory and Practice
of Medicine. The university possessing three such able teachers as
Gregory, Cullen and Black, grew more and more prosperous. It is
impossible to go over the records of these years without admiration
for John Gregory, who, amidst all the strife that waged around him
and around Cullen, has not left a record of any bitterness. That he
must have felt these annoyances is obvious, but his worries were
only Edinburgh worries, and outside he knew that both he and
Cullen were appreciated and valued for their individual work. On his
appointment to the Edinburgh chair he had resigned his King’s
College professorship.
When Dr Gregory came to Edinburgh, he came with his six children.
Elizabeth, his youngest little girl, died in 1771. His eldest son James
was studying medicine, the other boys were at work, and Dorothea
and Anna Margaretta, his elder daughters, were growing into more
charming companions for him with every day that passed. They
were tall, willowy girls, promising great beauty, and full of
sweetness. Dorothea, or Dolly as she was called, was a god-
daughter of Mrs Montague’s, and when that lady came to stay with
Dr Gregory, she was absolutely fascinated by her godchild. Her visit
was a great pleasure to the Gregorys, to whom she was ever her
most charming self.
Edinburgh society did not take kindly to her, if we are to believe Dr
Carlyle, and in fact he is rather bitter upon the subject, calls her ‘a
faded beauty,’ ‘a candidate for glory,’ and says she might have been
admired by the first order of minds had she not been ‘greedy of
more praise than she was entitled to.’ Even he, however,
acknowledged her a wit, a critic, an author of some fame,
possessing some parts and knowledge, which is praise to a certain
point, though not to the point which Mrs Montague would have
desired! ‘Old Edinburgh was not a climate for the success of
impostures,’ writes the minister of Inveresk, and then to support his
judgment with a little legal weight, he added, ‘Lord Kames, who was
at first catched with her Parnassian coquetry, said at last that he
thought she had as much learning as a well-educated college lad
here of sixteen.’ Alas, poor Mrs Montague! and then, too, Dr Carlyle
has unwittingly pointed out the rock on which she struck—‘she
despised the women’—and by such obvious silliness did she not
evoke her fate? Gray the poet was also a visitor at the Gregorys’ and
Gregory was asked to meet anyone of interest who came to the
town. With Smollett, indeed, who lived in St John Street for a winter,
he could have little real friendship, for the novelist had put Lord
Lyttleton into Roderick Random in anything but a kindly spirit, and
the Gregories were notoriously ‘Love me, love my dog’ people. He
lived on terms of close intimacy with Dr Robertson, Dr Blair, David
Hume, John Home, Lord Kames, Lord Monboddo, and Lord
Woodhouselee. He was a member of the Poker Club, though he went
there very seldom, because of the way he was laughed at when he
uttered his favourite doctrine of the superiority of women over men.
This at least was the gossip of the time, but there is just a possibility
that he thought his own company more entertaining than the
constant attendance at the Poker from three in the afternoon till
eight at night, and though no one knew it, he was busy drawing up
a book of advices for his daughters against the time, which he felt
could not be very far off, when he would no longer be with them.
‘My Dear Girls—You had the misfortune to be deprived of your
Mother at a time of life when you were insensible of your loss, and
could receive little benefit either from her instruction or her example.
Before this comes to your hands, you will likewise have lost your
Father. I have had many melancholy reflections on the forlorn and
helpless situation you must be in if it should please God to remove
me from you before you arrive at that period of life, when you will
be able to think and act for yourselves.... I have been supported
under the gloom ... by a reliance on the Goodness of that Providence
which has hitherto preserved you, and given me the most pleasing
prospect of the goodness of your dispositions, and by the secret
hope that your Mother’s virtues will entail a blessing on her children.’
This was the spirit in which the book was written, and though it is a
type of book which has entirely passed out of fashion, it is
interesting to read it and remember that in the days of our great-
grandmothers it had its place on every girl’s table.
Dr Gregory had a very observant way of watching girls, he knew life,
and his advice was shrewd and tender. In the chapter on Conduct
and Behaviour there are many quaint observations as to what gifts
are attractive in a girl.
‘Wit,’ he says, ‘is the most dangerous talent you can possess, it must
be guarded with great discretion and good nature, otherwise it will
create you many enemies’.... ‘Be even cautious in displaying your
good sense. It will be thought you assume a superiority over the rest
of the company—But if you happen to have any learning, keep it a
profound secret, especially from the men’.... ‘Beware of detraction,
especially when your own sex are concerned. You are generally
accused of being particularly addicted to this vice—I think unjustly—
Men are fully as guilty of it when their interests interfere. As your
interests more frequently clash, and as your feelings are quicker
than ours, your temptations to it are more frequent. For this reason,
be particularly tender of the reputation of your own sex, especially
when they happen to rival you in our regards.’ Later on, there is a
pathetic feeling of how little he can foretell his daughters’ tastes. ‘I
do not want to make you anything, I want to know what Nature has
made you, and to perfect you on her plan.’
A Father’s Legacy to his Daughter was intended only for his own
girls, and was not published till after Dr Gregory’s death. During his
time in Edinburgh he brought out besides his Comparative View,
Lectures on the Duties and Qualifications of a Physician, which were
his introductory lectures, and Elements of the Practice of Physic, a
first volume of a text-book for his students which he did not live to
complete. He thought medicine required a more comprehensive
mind than any other profession, and often brought much besides
mere technical knowledge into his lectures. As a speaker he was
simple, natural and vigorous. He lectured only from notes, ‘in a style
happily attempered,’ said one of his contemporaries, ‘between the
formality of studied composition, and the ease of conversation.’ On
one thing he insisted, that every student should appreciate the
limitations of medicine, for only so could they learn to extend its
borders.
During these years, too, he carried on a constant correspondence
with James Beattie, Professor of Moral Philosophy in Aberdeen, and
a poet. Both Beattie and Thomas Reid, who held the corresponding
chair in Glasgow, were engaged in combating the teaching of David
Hume, which had become very fashionable, and Gregory, though
much attached to David Hume as a man, feared him as a teacher,
and dreaded the growth of that scepticism which marked the time—
a tendency quite as bitterly lamented in England by Samuel Johnson.
‘I am well convinced,’ Gregory wrote to Beattie in a letter dated
Edinburgh, 16th June 1767, ‘that the great deference paid to our
modern heathens has been productive of the worst effects. Young
people are impressed with an idea of their being men of superior
abilities, whose genius has raised them above the vulgar prejudices,
and who have spirit enough to avow openly their contempt of them.
Atheism and Materialism are the present fashion. If one speak with
warmth of an infinitely wise and good Being, who sustains and
directs the frame of nature, or expresses his steady belief of a future
state of existence, he gets hints of his having either a very weak
understanding, or of his being a very great hypocrite.... You are the
best man I know to chastise these people as they deserve, you have
more Philosophy and more wit than will be necessary for the
purpose, though you can never employ any of them in so good a
cause.’
When Beattie’s answer to Hume was in manuscript, he sent it to Dr
Gregory, who read it, and cordially approved of it, but one result of
this was that Gregory had to become a partaker in the acrimony of
Hume’s friends. His advices as to an attractive style were somewhat
curious, ‘You are well aware of the antipathy, which the present race
of readers have against all abstract reasoning, except what is
employed in defence of the fashionable principles; but though they
pretend to admire their metaphysical champions, yet they never
read them, nor if they did, could they understand them. Among Mr
Hume’s numerous disciples, I do not know one who ever read his
Treatise on Human Nature. In order, therefore, to be read, you must
not be satisfied with reasoning with justness and perspicuity; you
must write with pathos, with elegance, with spirit, and endeavour to
warm the imagination and touch the heart of those who are deaf to
the voice of reason. Whatever you write in the way of criticism will
be read, and, if my partiality to you does not deceive me, be
admired. Everything relating to the ‘Belles Lettres’ is read, or
pretended to be read. What has made Lord Kames’ Elements of
Criticism so popular in England, is his numerous illustrations and
quotations from Shakespeare.... This is a good political hint to you in
your capacity of an author.’
Gregory was also consulted about the sketch design of Beattie’s
Poem, The Minstrel, which he admired, and the closing stanza
written by his friend the poet, when he heard of Gregory’s death,
was supposed to be very beautiful poetry. Cowper wrote in one of
his letters to the Rev. William Unwin, ‘If you have not his poem
called The Minstrel, and cannot borrow it, I must beg you to buy it
for me, for though I cannot afford to deal largely in so expensive a
commodity as books, I must afford to purchase at least the poetical
works of Beattie.’
Gregory’s views of his friend’s high gifts then were shared by
Cowper. Gray also held him in high estimation, and Mrs Siddons
spent an afternoon with Beattie, crying because they were so happy
over poetry and music, and some of the poetry must have been his
own. As for Beattie’s lines on Gregory, they are as much calculated
to draw smiles as tears from our eyes.
‘Adieu, ye lays that fancy’s flowers adorn,
The soft amusement of the vacant mind!
He sleeps in dust and all the Muses mourn,
He whom each virtue fired, each grace refined,
Friend, teacher, pattern, darling of mankind!
He sleeps in dust: and how should I pursue
My theme? To heart-consuming grief resigned,
Here on his recent grave I fix my view,
And pour my bitter tears. Ye flowery lays, adieu!

Art thou, my Gregory, for ever fled?


And am I left to unavailing woe?
When fortune’s storms assail this weary head,
Where cares long since have shed untimely snow,
Ah, now, for comfort whither shall I go?
No more thy soothing voice my anguish cheers,
Thy placid eyes with smiles no longer glow,
My hopes to cherish and allay my fears.
‘Tis meet that I should mourn, flow forth afresh my tears.’

Gregory wrote little upon religious subjects, except some chapters in


the Comparative View and in the Father’s Legacy, but he spoke often
of the things which pertain to the Life Eternal. To him they were as
really present as the circumstances of every day.
His mind was deeply religious, but it was of that sort that lives more
by meditation than church-going. Though he was a Presbyterian
himself, he had his younger children brought up as Episcopalians,
wishing them in everything to be likened as much as possible to
their mother.
One day in the beginning of February 1773, John Gregory was
talking to his son James about his health. His son told him that he
feared it was likely he would soon have a bad attack of gout, a
disease from which he had been entirely free for three years.
Professor Gregory, who felt himself in full vigour, and who was in the
height of his work, was much vexed with this prognosis. Gout was a
dread enemy in his mother’s family, and he always feared its
visitations. He had suffered from it more or less since he was
eighteen, and the preface to the Father’s Legacy indicates his
anticipation of an early death.
On the morning of the 10th he was found dead in bed. His face was
peaceful, everything was smooth and still, showing that death had
come gently. But the familiar presence had passed away for ever
from his home. It is said that Gregory had a great fear of darkness,
and that after his wife’s death he used to have an old woman come
and sit by him to hold his hand till he fell asleep, and if this is true, it
is most strange. He was forty-nine when he died.
John Gregory was succeeded in the chair by William Cullen, who,
when his time came, made room for James Gregory, the fourth
incumbent of the chair: a son of Dorothea Gregory, William Pulteney
Alison was the sixth.
In appearance John Gregory was tall and strongly built. His face in
repose was kind, although too full and heavy to look clever; even his
eyes were dull. When he was talking there was a complete change.
Interest, life and expression transformed his features, until one could
hardly suppose him to be the same man. The charm of his manner
has never been gainsaid, and like the beauty of his wife, it is
mentioned in every biography.
After her father died, Dorothea went to live with her godmother, Mrs
Montague, under whose care she spent the rest of her unmarried
life. She was made very happy, and gave great pleasure wherever
she went. She had inherited, if not all her mother’s beauty, a great
share of it, and her nature was as sweet and strong as her father’s
and mother’s in one. When Sir William Pulteney, who had been a
friend of her father’s, heard of Dorothea’s engagement to the Rev.
Archibald Alison, he wanted to satisfy himself that she was making a
suitable marriage, and with this object in view went himself to see if
all the good things that were said about the bridegroom were true.
He gives a pleasant description of the expedition.
‘Andrew Stuart and I accompanied Mr Alison to Thrapston, and the
marriage took place on the 19th, by a license from the Archbishop of
Canterbury. I conducted them afterwards to their residence, and we
left them next morning after breakfast, as happy as it is possible for
people to be. Mr Alison was obliged to come round by London, in
order to take an oath at granting the license, and I was glad of the
opportunity which the journey afforded me of making an
acquaintance with him; for tho’ I had little doubt that Miss Gregory
had made a proper choice, yet I wished to be perfectly satisfied, and
the result is, that I think neither you nor Mr Nairne have said a word
too much in his favour.’
Dorothea Gregory’s two sons were William Pulteney Alison, Professor
of the Practice of Physic, and Sir Archibald Alison, the historian. Her
daughter Montague, before her marriage with Colonel Gerard, was
loved by Thomas Campbell, the poet, and by Francis Jeffrey.
Anna, John Gregory’s second daughter, married John Forbes, Esq. of
Blackford, in Aberdeenshire. William the second son went into the
Church, and was appointed one of the ‘six preachers’ in Canterbury
Cathedral. Of his sons one was a successful doctor in London, and
another, John, Governor of the Bahammas, was the father of Mr
Philip Spencer Gregory, who has already been referred to in this
book.
Dr Gregory changed the spelling of his name from Gregorie to
Gregory during his stay in London. Curiously enough, the only other
branch of the Gregories who had up to that time emigrated to the
south had made the same alteration.
Professor John Gregory’s fame, while it may not have extended as
widely as that of his son, was yet far-reaching. When Beattie had an
interview with the king in 1773, His Majesty made special enquiries
about his First Physician for Scotland. This was probably shortly after
the professor’s death.
His life published in 1800 along with sketches of Lord Kames, David
Hume, and Adam Smith, ends with these words—
‘Upon the whole, whether he is considered as a man of genius and
of the world, or with regard to his conduct in the line of his
profession, few human characters will be found to equal that of the
late Dr John Gregory.’
CHAPTER IX

JAMES GREGORY, 1753–1821

‘If in doubt, “lead with trumps,” is counsel so old


As never to fail with the game in a fixture;
And medical men, in their doubt, I am told,
Are safe when they lead with—Gregory’s Mixture!’

—Old Play.

It was in the middle of the session, 1772–73, that John Gregory


died, leaving as we know his work in full swing. The university
authorities were told, not of his illness, but of his death, and they
were greatly at a loss as to who should continue the course of
lectures which Professor Gregory had commenced with so much
vigour. In this difficulty it was that James Gregory his son stepped
forward; although he was only a medical student, he offered to
deliver lectures on the Practice of Physic till the end of the term, and
this proposal was most gratefully accepted by the university.
There is something which is perhaps not wholly unattractive in the
idea of being the professor as well as the student; but at nineteen to
lecture, and to lecture so well as to receive in consequence the offer
of a chair at twenty-three, is a triumph which is rare indeed.
James Gregory was born in Aberdeen in 1753, and even as a child
his mind always seems to have been keenly awake. He left the
Grammar School of Aberdeen when he was eleven, having learned
all that was to be learned there, and entered King’s College at an
age at which clever boys now leave a preparatory school.
In the same year when his father removed to Edinburgh James
Gregory entered that university, and there he spent the next years of
his life. Later he went up to Christ Church, Oxford, of which his
cousin was then dean. Oxford did not inspire him much, for indeed
learning was then at a very low level there, but he continued his
work at classics, and came to write Latin with fluency, Greek when
there was occasion, and both ‘with classical elegance,’ if we are to
believe his admiring contemporaries.
It is probable that it was at Oxford that James Gregory resolved to
follow in his father’s footsteps, and become a doctor. There were of
course many inducements, and all the influence of his family would
be brought to bear on that side; but beyond this may we not believe
that visions were given him of the golden fame that a hitherto
unimagined mixture would bring to the name of Gregory unto all
time? Whether the vision was vouchsafed to him or not, he returned
to Scotland and began his medical studies in 1767.
It was a brilliant time in Edinburgh University. The medical
professoriate contained a number of remarkable men. Cullen was
there who had revolutionised medicine, Alexander Monro ‘Secundus,’
the greatest of a great family, Black who was acknowledged by
Lavoisier as the pioneer of modern chemistry, John Hope the
botanist and John Gregory. Under such teachers as these James
made rapid progress, and although there are no tales of medals or
prizes we cannot forget the instance of his medical foresight when
he predicted an attack of gout for his father, which attack came, to
his sorrow, so soon and so fatally after the prediction.
The Chair of the Practice of Physic was given to Cullen, and young
Gregory went to St George’s Hospital, London, to gain a wider
experience. He took his M.D. degree in Edinburgh in 1774: his thesis
entitled De morbis Coeli Mutatione Medendis treats in detail Phthisis
Pulmonalis, Hypochondriasis, and Gout, and concludes by noticing
the advantage of change of air in the prolonging of human life.
Startlingly wide in subject as this thesis appears to us, it was greatly
admired for its style and minuteness, and thus Gregory, quitting
Edinburgh for a time of study on the continent, left behind him a
very favourable impression both of his talent and hard-working
research.
Leyden, Paris, and Italy formed matter for enchanting letters which
were the delight of his friends. Where are those letters gone to?
How pleasant would it be to live through them a student’s life in
these years. Whatever James Gregory could be, he was never dull,
and besides in them we might have found the early tokens of that
fierce temper which is the only pity of his professional career in
Edinburgh.
There are two portraits of Gregory, or rather a portrait[7] and a bust,
which were said to be very like. A tall man, large, ungainly, of a rare
presence. A man having authority impressed on every feature,
radiant with affection for his friends, intolerant of enemies, asking
his own way and getting his own way, loving, hating, thinking,
speaking, feeling, always with intensest ardour. Here was a man
whom none of his associates could regard dispassionately; they
either loved him as a friend or hated him as an enemy.

7. The portrait is by Raeburn, and there is also a miniature of the


professor by the same artist, which is in the possession of Mr
Philip Spencer Gregory.
Even in Edinburgh which was full of personalities, real individuals,
men who were above all things themselves, Gregory stands out a
great original. Lord Cockburn and Sir Robert Christison were not
inclined to agree with each other on most subjects, yet about
Gregory’s power there is a refreshing unanimity in their opinions.
In June 1773 he was elected to the Chair of the Institutes of
Medicine. This chair had been practically vacant for three years,
during which time it was offered over and over again to Alexander
Monro Drummond, whose chief merit seems to have been that he
united the names of the great teaching Monroes with that of
Drummond, perhaps the noblest citizen Edinburgh has ever had. It
has been suggested, however, that this was only done to keep the
appointment open for Gregory, when he should have completed his
studies, and certainly when he returned, his election was
unanimous. He entered upon his duties with happy vigour. Teaching
was, as with every Gregory, his greatest gift, and the classes grew
steadily all the time he was professor. The university never made
greater progress than it did about this time, the medical graduates
rising in number from about twenty in 1776 to one hundred and
sixty in 1827.
In the teaching of his class Professor Gregory daily felt the need for
his students of a new book on the Theory of Medicine, so he wrote
the Conspectus Medicinae Theoreticae which proved such a valuable
handbook on the subject. This book was most successful, it passed
through many editions, was translated into English and several other
languages, was used sometimes as a medical book and sometimes
as a Latin text, for the Latin was as much admired as the
information which it imparted. Considering the success of this
volume, it is surprising that this was James Gregory’s only medical
publication: he alas wrote many books afterwards, but with the
exception of some chapters on philology and some literary essays,
he wrote nothing but controversial works, prodigiously long, violent,
personal, and acrid; their only excuse that they were never written
for selfish ends and their only merit that they were a source of
infinite amusement to the general public.
Gregory lived in his father’s old house, No. 15 Canongate, and to this
home he brought his first wife, the gentle Galloway girl, called Mary
Ross, whose companionship was his, for such a short time in life’s
journey. She died in 1784. In the years following her death he
resumed his early classical studies, and it is a rather curious fact that
he wrote nearly all the Latin epitaphs or dedications which were
wanted for any purpose in Edinburgh from this time till his death.
Principal Shairp, referring to Burns’ meeting with Gregory at
Ochtertyre, describes how the poet ‘was charmed with the
conversation of that last of the Scottish line of Latinists, which began
with Buchanan and ended with Gregory.’
In 1787, he published his essay on the Theory of Moods and Verbs,
and in 1792, Philosophical and Literary Essays. He was a great
student of words, loved epigram, and spent much of his leisure in
translating poetry. He was also interested in metaphysics, but as his
great maxim was that in metaphysics there could be no discovery,
his writings on this subject do not appear to have added much to his
fame. Throughout these years, too, he kept up a constant
correspondence with his cousin Thomas Reid, and proved himself
just the appreciative critic that Reid required in the writing of his
books. Dugald Stewart and Gregory together revised the proofs of
Reid’s Essays on the Intellectual Powers, and to them this book was
dedicated.
‘I send you,’ writes Reid, ‘what I propose as the title of my Essays,
with an epistle which I hope you and Mr Stewart will allow me to
prefix to them. Whether your name should go first on account of
your doctor’s degree, or Mr Stewart’s, I leave you to adjust between
yourselves. I know not how to express my obligations to you both
for the aid you have given me.’
Towards the end of 1790 it became apparent that Cullen, the
greatest doctor of his time was failing in strength, and on his
resigning the Chair of the Practice of Physic the Town Council
reappointed him in kindly recognition of his great services to the
university, but appointed James Gregory to be joint-professor during
his lifetime with the sole right of survivorship. This comradeship did
not last long, for in the same year Cullen died. To no less strong man
could the task of succeeding this veteran teacher, who had raised
the reputation of the Edinburgh School to such a height, have been
wisely entrusted.
As Professor of the Theory of Physic, Gregory had shown remarkable
gifts, but in his new subject his teaching was superb. Sir Robert
Christison in his autobiography, says of him, ‘Equal in fluency as in
choice of language, he surpassed all lecturers I have ever heard. His
doctrines were set forth with great clearness and simplicity in the
form of a commentary on Cullen’s First Lines of the Practice of
Physic. His measures for the cure of disease were sharp and incisive.
In acute diseases there was no ‘médecine expectante’ for Gregory,
he somehow left us with the impression that we were to be masters
over nature in all such diseases, that they must of necessity give
way before the physician who is early enough and bold enough in
encountering them.’ He had a memory so clear that he was never
known to forget a case, and in his lectures he made his students see
not only the general features of a disease, but an actual case of it
which had come under his care. He used stories and history, and his
own experience to vivify his lectures, and no doubt he succeeded for
he had seen many sides of life. He never had time for more than
two-thirds of his subject in one course, but whatever he missed out
he always discussed fevers and inflammations. In much that he
taught he was in advance of his age. In observing how frequently
rheumatic fever tends to heart disease; in limiting the use of blood-
letting[8] at a time when it was becoming almost a universal panacea
with doctors, in urging a liberal dietary in certain stages of
consumption, and in the invention and use of his mixture he showed
that his views were in advance of those held by most of his brother
physicians. Professor Gregory had an odd habit of wearing his
cocked hat while he lectured.

8. In whole classes of cases, however, Gregory was a decided


advocate of blood-letting.
It was in the summer of 1796 that dear old Thomas Reid, who was
becoming very frail, was induced to pay a visit to St Andrew’s
Square, to which Gregory had migrated. His daughter, Mrs
Carmichael, was anxious to have the opinion of Dr Gregory, as to
whether there was anything she could do to retard the bodily decay
which increased daily in her father. It was a happy time to them all.
Gregory delighted in the keenness of the old man’s mind. As he was
not fit for much exercise, he passed his time in solving algebraical
problems, and discussing abstruse subjects with Dugald Stewart.
Gregory was no doubt busy. His practice increased daily, and besides
this, he probably spent a good deal of his time in the house of Mr
M’Leod of Geanies, the Sheriff of Ross-shire; to whose daughter,
Isabella, he was married on the 19th of October, just ten days after
Thomas Reid’s death.
Miss M’Leod was a very beautiful girl, both winning and attractive, if
Raeburn’s portrait of her is true to life, and she made both a good
wife and good mother. Among Raeburn’s other portraits, and
interesting to us because they were the friends of the Gregories, are
such men as Dugald Stewart, Principal Robertson, Blair, Home,
Ferguson, Mackenzie, Francis Horner, and Jeffrey. How much is it
Raeburn, one wonders, who makes these men and women so
charming, for it is their looks and what we know of their lives, far
more than their writings, that attract us. Principal Robertson, with all
his sweetness and dignity, has only written histories which are now
superseded. Jeffrey railed at Wordsworth. Blair’s sermons are but a
lingering tradition. The eloquence of Dugald Stewart, which brought
Melbourne, Lord John Russell, and Palmerston to Edinburgh
University, is now forgotten. It is not by their books that we know
these men, it is because we love them when we see their portraits;
it is because Cockburn lets us know them in their homes—it is
because John Brown, who lived early enough to be in touch with
those who remembered them, has written about them lovingly and
tenderly. They were delightful men, but more delightful in their lives
than in their books. The witty criticisms of the Edinburgh Review
have passed away; they were for their day—but the remembrance of
Jeffrey’s pleasant after-intercourse with Wordsworth, the kindliness
with which Gregory welcomed all the young Edinburgh reviewers
into his house at a time when no other Tories except the ‘man of
feeling’ and Archibald Alison would receive them, and the occasional
permission which Principal Robertson gave little Henry Cockburn to
feast off his cherry tree—these are memories which will appeal to
the kindly hearts of all time.
Then it is amusing to read Dr Gregory’s critical letter to Burns, who
must have required all his admiration for the great doctor to bear
patiently the numerous suggestions which he showered upon him.

‘Edinburgh, 2nd June 1789.

‘Dear Sir,—I take the first leisure hour I could command, to thank
you for your letter and the copy of verses enclosed in it. As there is
real poetic merit, I mean both fancy and tenderness, and some
happy expressions, in them, I think they well deserve that you
should revise them carefully and polish them to the utmost. This I
am sure you can do if you please, for you have great command both
of expression and of rhymes; and you may judge, from the two last
pieces of Mrs Hunter’s poetry that I gave you, how much correctness
and high polish enhance the value of such compositions. As you
desire it, I shall with great freedom give you my most rigorous
criticisms on your verses. I wish you would give me another edition
of them, much amended, and I will send it to Mrs Hunter, who, I am
sure, will have much pleasure in reading it. Pray give me likewise for
myself, and her too, a copy (as much amended as you please) of the
“Waterfowl on Loch Turit.”
‘The “Wounded Hare” is a pretty good subject, but the measure or
stanza you have chosen for it is not a good one: it does not flow
well; and the rhyme of the fourth line is almost lost by its distance
from the first, and the two interposed, close rhymes. If I were you I
would put it into a different stanza yet.
‘Stanza 1.—The execrations in the first two lines are too strong or
coarse, but they may pass. “Murder-aiming” is a bad compound
epithet and not very intelligible. “Blood-stained” in Stanza III. line 4
has the same fault: Bleeding bosom is infinitely better. You have
accustomed yourself to such epithets and have no notion how stiff
and quaint they appear to others and how incongruous with poetic
fancy and tender sentiments. Suppose Pope had written “Why that
bloodstained bosom gored” how would you have liked it? Form is
neither a poetic nor a dignified nor a plain common word: it is a
mere sportsman’s word: unsuitable to pathetic or serious poetry.
“Mangled” is a coarse word. “Innocent,” in this sense, is a nursery
word; but both may pass.
‘Stanza 4. “Who will now provide that life a mother only can bestow”
will not do at all: it is not grammar—it is not intelligible. Do you
mean “provide for that life which the mother had bestowed and used
to provide for?” There was a ridiculous slip of the pen, “Feeling” (I
suppose) for “Fellow,” in the title of your copy of the verses; but
even “fellow” would be wrong: it is but a colloquial and vulgar word,
unsuitable to your sentiments. “Shot” is improper too. On seeing a
person (or a sportsman) wound a hare: it is needless to add with
what weapon; but if you think otherwise, you should say with a
fowling-piece. Let me see you when you come to town, and I will
shew you some more of Mrs Hunter’s poems.’

Perhaps when Burns submitted his lines, ‘On seeing a wounded hare
limp by me, which a fellow had just shot at,’ he hoped for as kindly a
criticism as Dr Gregory had given to Clarinda’s verses, which the
poet had shown him in December 1787; but if so, he was much
disappointed. ‘Dr Gregory is a good man, but he crucifies me,’ wrote
Burns soon after; and again, ‘I believe in the iron justice of Dr
Gregory; but like the devils I believe and tremble.’ It was a curious
friendship, but friendship it was. There is an English translation of
Cicero, which the physician had given to Burns in Edinburgh in 1787,
and on the fly-leaf of this is written, ‘This book, a present from the
truly worthy and learned Dr Gregory, I shall preserve to my latest
hour as a mark of the gratitude, esteem and veneration I bear the
owner—so help me God.—Robert Burns.’ Clarinda’s desire to make
Gregory’s acquaintance which is surely an indication of how much
her Sylvander admired him, finds utterance in a letter of 1787, ‘Pray
is Dr Gregory pious? I have heard so, I wish I knew him.’
It was at Lord Monboddo’s that Gregory first met Burns. Besides the
queer old judge, who was made a laughing stock for saying that
men originally had tails, there was his charming daughter, the
beautiful Miss Burnet, to whom Gregory is said to have offered his
heart and hand.
One of the stories that Lord Cockburn tells of Gregory is in
connection with Miss Sophia Johnston (generally known in the
Edinburgh of that day as ‘Suphy’) one of the Hilton family; about
whom, because of her curious upbringing, there were many odd
stories. ‘When Suphy’s day was visibly approaching, Dr Gregory
prescribed abstinence from animal food, and recommended “spoon-
meat” unless she wished to die. “Dee, doctor, odd, I’m thinking
they’ve forgotten an auld wife like me up yonder!” However, when
he came back next day, the doctor found her at the spoon-meat,
supping a haggis—she was remembered.’
Gregory lived now, as we know, in St Andrew Square, having left the
old home in the Canongate, but besides this he bought a house
called Canaan Lodge, which was then at a sufficient distance from
Edinburgh to be in the real country. Walking towards this house he
might often be seen of an evening with his all too warlike stick over
his shoulder, possibly the very stick with which he smote his brother
physician Professor Hamilton within the sacred precincts of the
university. The story does not end here, nor even at the Law Courts,
where he was made to pay £100 damages to the infuriated object of
his attack, but with Gregory, who as usual had the last word, and
the last laugh in the matter, and said as he paid his fine, that he
would willingly pay double for another chance.
‘A’ the country, far and near,
Hae heard Macgregor’s fame, lady.

He was a hedge about his friends,


A heckle to his foes, lady;
If any man did him gainsay,
He felt his deadly blows, lady.

It is really a pity, but no sketch of Professor James Gregory could be


adequate without mentioning some of the more important of his
professional feuds. Take the Infirmary for example, with which he
was connected from so early a date as 1777, and where he made
one of the most sweeping and necessary reforms that have ever
taken place in the management of that institution. He early saw that
it was neither for the good of the patients, nor for the good of the
students, that the physicians and surgeons should attend the wards
for only a month at a time, and against this he set himself with all
the zeal of which he was capable. He disapproved the time-
honoured privilege enjoyed by every member of the Royal College of
Physicians, and every member of the Royal College of Surgeons, to
doctor the Infirmary patients; and getting more and more enraged
with the infatuation of his medical brethren, he presented a
memorial to the managers of the Infirmary, expounding his views,
that Infirmary appointments should be made either for life, or at
least for a number of years, but unfortunately doing so in language,
of which the following paragraph is but one specimen:—
‘Let us suppose that in consequence of this memorial, every
individual member of the College of Surgeons shall to his own share,
make forty times more noise than Orlando Furioso did at full moon
when he was maddest, and shall continue in that unparalleled state
of uproar for twenty years without ceasing. I can see no great harm
in all that noise, and no harm at all to any but those who make it.
Ninety-nine parts in the hundred of all that noise would of course be
bestowed on me, whom it would not deprive of one hour’s natural
sleep, and to whom it would afford infinite amusement and
gratification while I am awake,’ etc.
Such bitter writing was not, however, solely on one side. On another
occasion, by the consent of the Royal College of Physicians, ‘A
narrative of the conduct of Dr James Gregory towards the Royal
College of Physicians of Edinburgh’ was published, which opens with
this ominous paragraph, ‘It is with great pain, that the Royal College
of Physicians, not a numerous, but hitherto, they trust, a very
respectable society, find themselves compelled to come before the
public with a narrative of their internal dissensions. The intemperate
and injurious conduct of one of their members however has now
made this a matter of necessity. Like other collections of individuals,
they have had their dissensions and disagreements, but till very
lately they were always conducted with the temper and the language
of gentlemen, and were begun and ended within the walls of the
College. Dr James Gregory has introduced a new style and a new
jurisdiction.’
There is not much to choose between in these samples of
professional controversy, but on the whole Gregory was usually more
right in his views, and more wrong in his expression, than the other
side. In spite of these quarrels Gregory’s practice increased steadily.
In 1818 his professional income was £2723, and in the following
year £100 more, while in the same years he derived from his
professorship by way of fees, £1364 and £1200 respectively. These
figures represented a much larger sum in 1818 than they would in
1900, and give a substantial proof of Gregory’s popularity.
A story told of Professor Gregory is peculiarly touching. One day
when he was giving out the tickets for his class, he had to go into
another room to fetch something. When he came back he saw a
student, who was waiting for his ticket, take some money off his
table and put it into his pocket. The Professor gave him his pass and
said nothing, but just as the lad was leaving the room, he rose up
and laying his hand on his shoulder said, ‘I saw what you did, and I
am so sorry. I know how great must have been your need before
you would take money. Keep it, keep it,’ he added, seeing that the
student meant to give the stolen money back to him, ‘but for God’s
sake, never do it again.’
Sir Walter Scott has remembered also how Professor Gregory on one
occasion gave a very ready reply to a learned member of the
Scottish Bar. He was giving evidence about a man, who in his
opinion, was insane. On a cross-examination, the professor was
obliged to admit that the person in question played an admirable
game of whist. The eminent counsel thought he had made a point.
‘And do you seriously say, Doctor,’ he added, ‘that a person having a
superior capacity for a game so difficult, and which requires in a pre-
eminent degree, memory, judgment, and combination, can be at the
same time deranged in his understanding?’ ‘I am no card player,’
replied the doctor, ‘but I have read in history that cards were
invented for the amusement of an insane king.’ Needless to say, he
won his case!
In 1818 Gregory had a serious carriage accident, in which his arm
was broken, and from this shock he never really recovered, though
we still see him in the midst of work. He was one of a deputation
from the University of Edinburgh to congratulate George IV. on his
accession to the throne, and while in London he received the honour
of a private audience of the king. During that visit his thoughts went
back often to his time of study in London, and to all the prosperity
that had come to him since. He had received almost every honour
which his profession could bring him. He had been President of the
College of Physicians. He was made king’s physician to George III.,
and his commission had been most graciously renewed (during this
visit) by George IV. Innumerable societies had bestowed their
honorary membership upon him, and many towns had given him the
privilege of their freedom, but he felt that his days were nearly over.
During the last year he had attacks of difficulty of breathing, which
made it impossible for him to lecture after Christmas 1820. The end
came in April. He died of hydro-thorax at the age of sixty-eight.
Of Gregory’s eleven children only five survived him. Two of them
were in their turn to become teachers. William, afterwards Professor
of Chemistry in Aberdeen and Edinburgh, and Duncan Farquharson,
the Cambridge mathematician.
There was not lacking one token of the love and esteem in which the
great professor was held. The voices of his rivals were hushed. His
friends mourned for him, and the town where he had been such a
familiar figure arranged a public funeral for him. He lies buried in the
family vault in the Canongate Churchyard.
‘Vir priscae virtutis, per omnes vitae gradus et in omni vitae officio
probatissimae.’
CHAPTER X

WILLIAM GREGORY, 1803–1858

‘Were it of hoot, or cold, or moyste, or drye,


And where they engendered and of what humour,
He was a verray parfit praktisour.’

—Chaucer, Prologue 420–422.

William Gregory was the last of this great academic family to hold a
chair in a Scottish University.
He was the fourth son of Professor James Gregory, and having been
brought up among the traditions of medicine, he turned to the study
of it instinctively, though the necessity laid upon him was by no
means the same as that which had made his forefathers physicians
in spite of themselves. He had not gone far in his medical course
when he decided to be a chemist rather than a doctor. The magic of
Professor Hope’s experiments made at least one convert and as he
sat in the class-room observing the strange effects of chemicals, he
made up his mind that if it were possible he would some day take
the teacher’s place. With rude implements he would spend hours at
home repeating the processes which he had watched in the class,
his mind all alive to the interest of his subject, and his poor body
much neglected. These happy hours in his laboratory were dearly
paid for by the delicacy, which began to show itself about this time.
The noxious fumes of the chemicals acted as a slow poison, and
from this stage of his life he had to struggle with ill health, all his
occupations being interrupted at times by unconquerable pain.
He graduated M.D. in 1828, and then went abroad to study
chemistry in the famous schools of the continent. At Giessen, the
most important of these, he had the good fortune to attract the
attention of the great teacher, whose work had made the university
famous, and from this time forward, Liebig was the friend and
correspondent of William Gregory.
During the years when Gregory was completing his studies abroad,
and teaching successively in Edinburgh, Glasgow, and Dublin, King’s
College, Aberdeen, was going through considerable difficulties in
connection with the post of mediciner. In the days of John Gregory’s
tenure of that office, he had as we already know, made efforts to
improve the medical curriculum there, but without success. A step in
advance was made in 1801, when it was determined that a
candidate for the degree of M.D. must ‘oblidge himself that he is
not, nor will be concerned in the sale of quack medicines of any
description!’ and a further step was taken in 1817 by the authorities
insisting on a satisfactory account of the ‘classical, literary and
scientifical education of the candidate.’
Between 1824 and 1826, an attempt was made by the Chancellor
and Senatus to insist that the mediciner should teach medicine, but
Dr Bannerman, who then held that office, would only consent to
consider the matter for a year, and after that time he let it rest. In
1836, he was advised that if he would neither teach nor appoint a
substitute, a lecturer would be chosen, and paid out of his salary.
This threat, however, was never carried out, and he died in 1838,
and it was to this post of mediciner, made vacant by his death, that
William Gregory was appointed on February 19th, 1839.
Dr William Pulteney Alison, to whom the electors of King’s College
applied for suggestions as to a suitable candidate, had curiously
enough never mentioned the name of his cousin, and it was only
owing to the intervention of Thomas Clark who held the Chair of
Chemistry in Marischal College that Gregory came to apply. After
giving him minute instructions as to the form which his application
must take, he added, ‘Don’t mention me no more than the Devil.’
The name of this friend was therefore kept out of sight, and Gregory
was in due course appointed to the vacant professorship. It was with
great joy that his advent was announced to the professors of King’s
College. Their difficulties in improving the medical course, when the
very mediciner would not teach a class, had been insuperable, but
now they felt a man of influence was coming amongst them, who
would be the means of promoting the interests of their university,
and who would give the benefit of a hereditary power of teaching to
the students, whom they felt sure his great name would attract to
their midst.
While in Aberdeen William Gregory became intensely interested in
the welfare of King’s College, and busied himself in trying to secure
revenue from the government to found new chairs, but in this he
was unsuccessful.
He taught Materia Medica in a house fitted up for a Medical School in
Kingsland Place, and he had a good class, but from the witticisms of
the students as to the effect of their professor’s preparation of
muriate of morphia it is evident that William Gregory’s physical
weakness was growing upon him, and that it was only with the most
strenuous effort that he could get to his class at ten o’clock.
As his power of walking failed him, the professor found much solace
in music, and sweet snatches of melody were carried across his old-
fashioned garden to the ears of passers-by. He played beautifully,
and his wife, who was a niece of Colonel Scott of Gala, added
greatly to the charms of their musical parties. It is said that they
were the first to shock the people of Aberdeen by playing secular
music on Sunday.
To the Aberdonians, however, he gave a more serious cause for
complaint—William Gregory was of a singularly childlike and trustful
disposition, and he was intensely interested in the occult science of
Spiritualism; the result was that he became the patron of a most
undesirable throng of quasi-scientific humbugs, whose presence in
their midst they resented with extreme frankness. There is a
continual atmosphere of table-turning, mesmerism and magnetic
flames in the tales extant about him, and though the narrators are
tender about his memory, they have perforce to take up the attitude
of counsel for the defence.
As a chemist, he undoubtedly came first in Scotland. He invented
processes for the more perfect preparation of hydrochloric acid,
muriate of morphia and oxyde of silver, besides making important
observations on many other chemicals. He had an accurate
command of practical chemistry, a power of condensation and clear
expression, and a just perception of the value of discoveries, which
made his writings unsurpassed for the use of students.
In 1844 Dr William Gregory realised the dream of his youth. After a
sharp contest with Dr Lyon Playfair, he was appointed to succeed
Professor Hope in his chair in the University of Edinburgh. ‘The chair
was given to him,’ says Sir Alexander Grant, ‘under a new title, for
the Town Council now judiciously omitted “Medicine” from its
province, and elected Dr Gregory to be Professor of Chemistry.’
His health was much impaired, so much so, that people even went
the length of saying that he was physically unfit for his new position,
and it is at any rate true that his finest teaching was given to his
students in Aberdeen. He was an able teacher, if at times erratic and
absent-minded. His class was always kept wide awake, for with what
alarms would not the professor bring back the straying imaginations
of his audience! ‘Gentlemen,’ he would say, while with his long
awkward fingers he lifted up the tube of some chemical before
them, ‘If this were to fall, not one of you could reach the door alive;’
and then, considering the matter over, he would place the tube
carelessly upon the edge of a plate, while the students near the
doorway filtered through it, and the others, hat in hand, awaited the
longed-for close of the lecture, feeling a fresh tremor with every
approach of Gregory’s loose fingers to the fatal vial.
Good as his teaching was, the books which he wrote while in
Edinburgh were his most valuable contribution to the Science of
Chemistry. In the preface to the Outlines of Chemistry, which was
published in 1845, he sketched the divisions which he intended to
make in his subject for the fuller elucidation of the facts, and, had
his health permitted him to carry out his plan, ‘the instruction from
his class would probably have been more complete than from any
other scientific chair in Europe.’ At the request of Liebig, he
translated several of his more important books into English, and in
the preface to the Familiar Letters on Chemistry, Liebig writes, ‘From
his intimate familiarity with chemical science, and especially with the
physiological subjects here treated, I am confident that the task
could not have been entrusted to better hands than those of my
friend Dr Gregory.’ Their friendship lasted throughout life, and only a
few days before Professor Gregory’s death, he was propped up in his
bed to write a pamphlet supporting some new theories of Liebig,
which the German had just communicated to him.
Gregory’s appearance was most noticeable. He was of great
proportions, obese, slouching and loosely hung together. In later
years his body was a great burden to him, but the mind kept the
mastery.
He was, like his father, a keen student of language, and would wile
away many of the weary hours of forced inaction by the study of
foreign tongues. French and German were to him as familiar as
English. With a microscope, too, he did beautiful work, and was in
his day, the greatest authority on the Diatomaceae. The slides which
he made of these microscopic water-plants with their sculptured
valves, were another resource of his declining years. He presented
valuable memoirs on this subject to the Royal Society of Edinburgh,
of which he was a member.
Professor William Gregory died in Edinburgh in April 1858, and was
honoured with a public funeral.
He was succeeded in the university by Dr Lyon Playfair (afterwards
Lord Playfair) who had contested the chair unsuccessfully at the time
of Gregory’s appointment.
William Gregory was survived by an only son, who was called after
his father’s far-famed friend, James Liebig Gregory.
Duncan Farquharson Gregory was considerably younger than his
brother the Professor of Chemistry, and was not at all like him in
personal appearance. His face was a beautiful one, fine, pale,
bearing on it already in this life some of the light and joyousness
that often mark out for especial love those who are to pass quickly
from this earth. His hair, which was thick and curling, fell more about
his brow than is usual, and his eyes like dark lamps illuminated his
features.
When he was hardly more than a baby, his father used fondly to
predict distinction for him. ‘He had pleasure in conversing with him
as with an equal on subjects of History and Geography,’ so Mr Ellis
wrote, and this when the boy was not more than six, for his father
died before he had left the nursery. He was a great inventor of
games for himself, and made an orrery with his busy little hands, on
which he would send the planets spinning round in their orbits.
Till he was nine years old he was taught entirely by his mother, who
was quite as attractive to her children as she had ever been in
society, and for whom Duncan had always a peculiar reverence and
affection. He passed out of her hands into the care of a tutor, and
then was sent to the Edinburgh Academy. From school he went
abroad to Geneva, where his mother and sisters were spending a
winter, and on his return he attended classes at the University of
Edinburgh. In mathematics he made astonishing strides, under
Professor Wallace, and those who saw the master and pupil together
in Cambridge in after days, said that the old man’s pride in his pupil’s
success never diminished.
In 1833 Mr Gregory’s name was entered at Trinity College,
Cambridge, and shortly afterwards he went to reside there. He took
with him a most unusual amount of knowledge on almost all
scientific subjects, in fact many men said that it was the diffuseness
of his learning that prevented him from taking the first place in the
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!

ebookmasss.com

You might also like