আমার সি সংকলিত কোড সহ একটি আর প্যাকেজ রয়েছে যা বেশ কিছু সময়ের জন্য তুলনামূলকভাবে স্থিতিশীল ছিল এবং প্রায়শই বিভিন্ন ধরণের প্ল্যাটফর্ম এবং সংকলক (উইন্ডোজ / অক্স / ডেবিয়ান / ফেডোরা জিসিসি / ক্ল্যাং) এর বিপরীতে পরীক্ষা করা হয়।
প্যাকেজটি আবার পরীক্ষা করতে আরও একটি নতুন প্ল্যাটফর্ম যুক্ত হয়েছিল:
Logs from checks with gcc trunk aka 10.0.1 compiled from source
on Fedora 30. (For some archived packages, 10.0.0.)
x86_64 Fedora 30 Linux
FFLAGS="-g -O2 -mtune=native -Wall -fallow-argument-mismatch"
CFLAGS="-g -O2 -Wall -pedantic -mtune=native -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong -fstack-clash-protection -fcf-protection"
CXXFLAGS="-g -O2 -Wall -pedantic -mtune=native -Wno-ignored-attributes -Wno-deprecated-declarations -Wno-parentheses -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong -fstack-clash-protection -fcf-protection"
কোন বিন্দুতে সংকলিত কোডটি এই লাইনগুলি দিয়ে তাত্ক্ষণিকভাবে সেগফল্টিং শুরু করেছে:
*** caught segfault ***
address 0x1d00000001, cause 'memory not mapped'
আমি অপ্টিমাইজেশন স্তর সহ rocker/r-base
ডকার পাত্রে ব্যবহার করে ধারাবাহিকভাবে সেগফল্ট পুনরুত্পাদন করতে সক্ষম হয়েছি । কম অপ্টিমাইজেশান চালানো সমস্যা থেকে মুক্তি পায়। ওয়েলগ্র্রাইন্ড (-O0 এবং -O2 উভয়), ইউবিএসএএন (জিসিসি / কলং) সহ অন্য কোনও সেট আপ চালানো মোটেই কোনও সমস্যা দেখায় না। আমি যুক্তিসঙ্গতভাবে নিশ্চিত যে এটির নীচে চলেছে , তবে ডেটা নেই।gcc-10.0.1
-O2
gcc-10.0.0
আমি gcc-10.0.1 -O2
সংস্করণটি চালিয়েছি gdb
এবং এমন কিছু লক্ষ্য করেছি যা আমার কাছে অদ্ভুত বলে মনে হচ্ছে:
হাইলাইট করা বিভাগে পা রাখার সময় এটি অ্যারের দ্বিতীয় উপাদানগুলির সূচনাটি এড়িয়ে যায় বলে মনে হয় ( আর-এ নিয়ন্ত্রণ ফিরে আসার সময় স্ব আবর্জনা সংগ্রহ R_alloc
করে malloc
এমন চারপাশে একটি মোড়ক ; আর-এ ফিরে যাওয়ার আগে সেগফল্ট ঘটে)) পরে, আন-ইনিশিয়েলাইজড উপাদানটি (gcc.10.0.1 -O2 সংস্করণে) অ্যাক্সেস করা হলে প্রোগ্রামটি ক্র্যাশ হয়।
আমি কোডটিতে স্পষ্টতই প্রশ্নটির উপাদানটিকে প্রাথমিকভাবে প্রাথমিকভাবে শুরু করে এটিকে সংশোধন করেছিলাম যা শেষ পর্যন্ত উপাদানটির ব্যবহারের দিকে পরিচালিত করে, তবে এটি সত্যিই একটি খালি স্ট্রিংয়ে সূচনা করা উচিত ছিল, বা কমপক্ষে এটিই আমি ধরে নিয়েছি।
আমি কি স্পষ্ট কিছু মিস করছি বা বোকা কিছু করছি? উভয় যুক্তিসঙ্গতভাবে সম্ভাবনা C দ্বারা আমার দ্বিতীয় ভাষা হয় পর্যন্ত । এটি কেবল আশ্চর্যজনক যে এটি এখনই ক্রপ হয়েছে এবং সংকলকটি কী করার চেষ্টা করছে তা আমি বুঝতে পারি না।
আপডেট : নির্দেশাবলী এই পুনর্গঠন করা, যদিও এই কেবল তাই যতদিন পুনর্গঠন করা হবে debian:testing
Docker কন্টেনার রয়েছে gcc-10
এ gcc-10.0.1
। এছাড়াও, আপনি যদি আমাকে বিশ্বাস না করেন তবে কেবল এই আদেশগুলি চালাবেন না ।
দুঃখিত, এটি একটি সর্বনিম্ন পুনরুত্পাদনযোগ্য উদাহরণ নয়।
docker pull rocker/r-base
docker run --rm -ti --security-opt seccomp=unconfined \
rocker/r-base /bin/bash
apt-get update
apt-get install gcc-10 gdb
gcc-10 --version # confirm 10.0.1
# gcc-10 (Debian 10-20200222-1) 10.0.1 20200222 (experimental)
# [master revision 01af7e0a0c2:487fe13f218:e99b18cf7101f205bfdd9f0f29ed51caaec52779]
mkdir ~/.R
touch ~/.R/Makevars
echo "CC = gcc-10
CFLAGS = -g -O2 -Wall -pedantic -mtune=native -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong -fstack-clash-protection -fcf-protection
" >> ~/.R/Makevars
R -d gdb --vanilla
তারপরে আর কনসোলে, প্রোগ্রামটি চালানোর জন্য টাইপ run
করার পরে gdb
:
f.dl <- tempfile()
f.uz <- tempfile()
github.url <- 'https://github.com/brodieG/vetr/archive/v0.2.8.zip'
download.file(github.url, f.dl)
unzip(f.dl, exdir=f.uz)
install.packages(
file.path(f.uz, 'vetr-0.2.8'), repos=NULL,
INSTALL_opts="--install-tests", type='source'
)
# minimal set of commands to segfault
library(vetr)
alike(pairlist(a=1, b="character"), pairlist(a=1, b=letters))
alike(pairlist(1, "character"), pairlist(1, letters))
alike(NULL, 1:3) # not a wild card at top level
alike(list(NULL), list(1:3)) # but yes when nested
alike(list(NULL, NULL), list(list(list(1, 2, 3)), 1:25))
alike(list(NULL), list(1, 2))
alike(list(), list(1, 2))
alike(matrix(integer(), ncol=7), matrix(1:21, nrow=3))
alike(matrix(character(), nrow=3), matrix(1:21, nrow=3))
alike(
matrix(integer(), ncol=3, dimnames=list(NULL, c("R", "G", "B"))),
matrix(1:21, ncol=3, dimnames=list(NULL, c("R", "G", "B")))
)
# Adding tests from docs
mx.tpl <- matrix(
integer(), ncol=3, dimnames=list(row.id=NULL, c("R", "G", "B"))
)
mx.cur <- matrix(
sample(0:255, 12), ncol=3, dimnames=list(row.id=1:4, rgb=c("R", "G", "B"))
)
mx.cur2 <-
matrix(sample(0:255, 12), ncol=3, dimnames=list(1:4, c("R", "G", "B")))
alike(mx.tpl, mx.cur2)
জিডিবিতে পরিদর্শন করা খুব দ্রুত দেখায় (যদি আমি সঠিকভাবে বুঝতে পারি) তবে
CSR_strmlen_x
এটি স্ট্রিংটি অ্যাক্সেস করার চেষ্টা করছে যা শুরু হয়নি that
আপডেট 2 : এটি একটি অত্যন্ত পুনরাবৃত্ত ফাংশন, এবং তারপরে স্ট্রিং ইনিশিয়ালাইজেশন বিটটিকে অনেকগুলি, বহুবার ডাকা হয়। এটি বেশিরভাগ খ / সি আমি অলস হয়ে পড়েছিলাম, আমাদের কেবল একবারে স্ট্রিংগুলি শুরু করার প্রয়োজন হয়েছিল যখন আমরা বাস্তবে আমরা পুনরাবৃত্তিতে রিপোর্ট করতে চাই এমন কিছু মুখের মুখোমুখি হই, তবে প্রতিবারই যখন কোনও কিছুর মুখোমুখি হওয়া সম্ভব হয় তখন এটি আরম্ভ করা সহজ ছিল। আমি এটি উল্লেখ করছি কারণ আপনি পরবর্তীটি যা দেখবেন তা একাধিক সূচনা দেখায় তবে এর মধ্যে কেবলমাত্র একটি (সম্ভবত ঠিকানাটি <0x1400000001> ব্যবহার করা হচ্ছে) ব্যবহার করা হচ্ছে।
আমি গ্যারান্টি দিতে পারি না যে আমি যে জিনিসগুলি এখানে দেখছি সেগুলি সেগফোল্টের কারণে যে উপাদানটির সাথে সরাসরি সম্পর্কিত (যদিও এটি একই অবৈধ ঠিকানার প্রবেশাধিকার) তবে @ ন্যাট-লেদার্ডেজ জিজ্ঞাসা করে এটি দেখায় যে অ্যারে উপাদানটি নেই রিটার্নের ঠিক আগে বা কলিং ফাংশনে ফিরে আসার ঠিক পরে শুরু হয়েছিল। কলিং ফাংশনটি এর মধ্যে 8 টি আরম্ভ করছে এবং নকল আবর্জনা বা অ্যাক্সেস অ্যাক্সেসযোগ্য স্মৃতিতে ভরাট করে আমি সেগুলি সমস্ত দেখাই Note
আপডেট 3 , প্রশ্নে কার্য বিচ্ছিন্নকরণ:
Breakpoint 1, ALIKEC_res_strings_init () at alike.c:75
75 return res;
(gdb) p res.current[0]
$1 = 0x7ffff46a0aa5 "%s%s%s%s"
(gdb) p res.current[1]
$2 = 0x1400000001 <error: Cannot access memory at address 0x1400000001>
(gdb) disas /m ALIKEC_res_strings_init
Dump of assembler code for function ALIKEC_res_strings_init:
53 struct ALIKEC_res_strings ALIKEC_res_strings_init() {
0x00007ffff4687fc0 <+0>: endbr64
54 struct ALIKEC_res_strings res;
55
56 res.target = (const char **) R_alloc(5, sizeof(const char *));
0x00007ffff4687fc4 <+4>: push %r12
0x00007ffff4687fc6 <+6>: mov $0x8,%esi
0x00007ffff4687fcb <+11>: mov %rdi,%r12
0x00007ffff4687fce <+14>: push %rbx
0x00007ffff4687fcf <+15>: mov $0x5,%edi
0x00007ffff4687fd4 <+20>: sub $0x8,%rsp
0x00007ffff4687fd8 <+24>: callq 0x7ffff4687180 <R_alloc@plt>
0x00007ffff4687fdd <+29>: mov $0x8,%esi
0x00007ffff4687fe2 <+34>: mov $0x5,%edi
0x00007ffff4687fe7 <+39>: mov %rax,%rbx
57 res.current = (const char **) R_alloc(5, sizeof(const char *));
0x00007ffff4687fea <+42>: callq 0x7ffff4687180 <R_alloc@plt>
58
59 res.target[0] = "%s%s%s%s";
0x00007ffff4687fef <+47>: lea 0x1764a(%rip),%rdx # 0x7ffff469f640
0x00007ffff4687ff6 <+54>: lea 0x18aa8(%rip),%rcx # 0x7ffff46a0aa5
0x00007ffff4687ffd <+61>: mov %rcx,(%rbx)
60 res.target[1] = "";
61 res.target[2] = "";
0x00007ffff4688000 <+64>: mov %rdx,0x10(%rbx)
62 res.target[3] = "";
0x00007ffff4688004 <+68>: mov %rdx,0x18(%rbx)
63 res.target[4] = "";
0x00007ffff4688008 <+72>: mov %rdx,0x20(%rbx)
64
65 res.tar_pre = "be";
66
67 res.current[0] = "%s%s%s%s";
0x00007ffff468800c <+76>: mov %rax,0x8(%r12)
0x00007ffff4688011 <+81>: mov %rcx,(%rax)
68 res.current[1] = "";
69 res.current[2] = "";
0x00007ffff4688014 <+84>: mov %rdx,0x10(%rax)
70 res.current[3] = "";
0x00007ffff4688018 <+88>: mov %rdx,0x18(%rax)
71 res.current[4] = "";
0x00007ffff468801c <+92>: mov %rdx,0x20(%rax)
72
73 res.cur_pre = "is";
74
75 return res;
=> 0x00007ffff4688020 <+96>: lea 0x14fe0(%rip),%rax # 0x7ffff469d007
0x00007ffff4688027 <+103>: mov %rax,0x10(%r12)
0x00007ffff468802c <+108>: lea 0x14fcd(%rip),%rax # 0x7ffff469d000
0x00007ffff4688033 <+115>: mov %rbx,(%r12)
0x00007ffff4688037 <+119>: mov %rax,0x18(%r12)
0x00007ffff468803c <+124>: add $0x8,%rsp
0x00007ffff4688040 <+128>: pop %rbx
0x00007ffff4688041 <+129>: mov %r12,%rax
0x00007ffff4688044 <+132>: pop %r12
0x00007ffff4688046 <+134>: retq
0x00007ffff4688047: nopw 0x0(%rax,%rax,1)
End of assembler dump.
আপডেট 4 :
সুতরাং, এখানে স্ট্যান্ডার্ডটির মাধ্যমে পার্স করার চেষ্টা করা হচ্ছে এর অংশগুলি যা প্রাসঙ্গিক বলে মনে হচ্ছে ( সি 11 খসড়া ):
.3.৩.২.৩ পার7 রূপান্তর> অন্যান্য অপারেন্ডস> পয়েন্টার
কোনও অবজেক্ট টাইপের একটি পয়েন্টারকে পয়েন্টারটিতে আলাদা আলাদা অবজেক্ট টাইপের রূপান্তর করা যেতে পারে। যদি রেফারেন্সড টাইপের জন্য ফলাফল পয়েন্টারটি সঠিকভাবে সংযুক্ত না হয় তবে আচরণটি অপরিজ্ঞাত।
অন্যথায়, যখন আবার ফিরে রূপান্তরিত হয়, ফলাফলটি মূল পয়েন্টারের সমান তুলনা করে। যখন কোনও অবজেক্টের পয়েন্টারকে পয়েন্টারকে একটি অক্ষর টাইপের রূপান্তর করা হয়, ফলাফলটি বস্তুটির সর্বনিম্ন সম্বোধিত বাইটে নির্দেশ করে। ফলাফলের ক্রমবৃদ্ধি, অবজেক্টের আকার পর্যন্ত অবজেক্টের অবশিষ্ট বাইটগুলিতে পয়েন্টার দেয়।
6.5 পার 6 এক্সপ্রেশন
তার সঞ্চিত মানটিতে অ্যাক্সেসের জন্য কোনও বস্তুর কার্যকর ধরণ হ'ল বস্তুর ঘোষিত প্রকার, যদি থাকে। ৮)) যদি কোনও মান কোনও লভালুতে কোনও অক্ষর প্রকার নয় এমন কোনও প্রকারের মাধ্যমে কোনও ঘোষিত প্রকারের মধ্যে কোনও স্ট্রোক করা থাকে, তবে লভালুর প্রকারটি অ্যাক্সেসের জন্য এবং পরবর্তী অ্যাক্সেসের জন্য অবজেক্টের কার্যকর ধরণের হয়ে যায় সঞ্চিত মানটি পরিবর্তন করুন। মেমকি বা মেমমোভ ব্যবহার করে কোনও ঘোষিত প্রকারবিহীন কোনও বস্তুতে যদি কোনও মান অনুলিপি করা হয়, বা অক্ষর প্রকারের অ্যারে হিসাবে অনুলিপি করা হয়, তবে সেই অ্যাক্সেসের জন্য এবং পরবর্তী পরিবর্তনগুলিতে মানটি সংশোধন না করে পরিবর্তিত অবজেক্টের কার্যকর ধরণটি হ'ল কার্যকর ধরণের বস্তু যা থেকে মানটি অনুলিপি করা হয়, যদি এটির একটি থাকে। কোনও ঘোষিত প্রকার না থাকা কোনও বস্তুর অন্যান্য সমস্ত অ্যাক্সেসের জন্য, অবজেক্টের কার্যকর ধরণটি অ্যাক্সেসের জন্য ব্যবহৃত লভ্যালের ধরণ।
87) বরাদ্দকৃত বস্তুর কোনও ঘোষিত প্রকার নেই।
আইআইইউসি R_alloc
একটি malloc
এড ব্লকে একটি অফসেট প্রদান করে যা double
প্রান্তিককরণের গ্যারান্টিযুক্ত এবং অফসেটের পরে ব্লকের আকারটি অনুরোধ করা আকারের (আর নির্দিষ্ট ডেটার জন্য অফসেটের আগে বরাদ্দও রয়েছে)। প্রত্যাবর্তনের সময় R_alloc
পয়েন্টার যে কাস্ট (char *)
।
বিভাগ 6.2.5 পার 29
অকার্যকর করার জন্য একটি পয়েন্টারের একটি চরিত্রের ধরণের পয়েন্টার হিসাবে একই উপস্থাপনা এবং প্রান্তিককরণের প্রয়োজনীয়তা থাকতে হবে। 48) একইভাবে, সামঞ্জস্যপূর্ণ ধরণের যোগ্য বা অযোগ্য সংস্করণের পয়েন্টারগুলির একই প্রতিনিধিত্ব এবং প্রান্তিককরণের প্রয়োজনীয়তা থাকবে। কাঠামোর ধরণের সমস্ত পয়েন্টারের একে অপরের মতো প্রতিনিধিত্ব এবং প্রান্তিককরণের প্রয়োজনীয়তা থাকতে হবে।
ইউনিয়নের ধরণের সমস্ত পয়েন্টারগুলির একে অপরের মতো প্রতিনিধিত্ব এবং প্রান্তিককরণের প্রয়োজনীয়তা থাকতে হবে।
অন্যান্য ধরণের পয়েন্টারগুলির একই প্রতিনিধিত্ব বা প্রান্তিককরণের প্রয়োজনীয়তা থাকা দরকার না।৪৮) একই প্রতিনিধিত্ব এবং প্রান্তিককরণের প্রয়োজনীয়তাগুলি হ'ল ফাংশনগুলিতে বিনিময়যোগ্যতা হিসাবে চিহ্নিতকরণ, ফাংশন থেকে মূল্যগুলি ফেরত দেওয়া এবং ইউনিয়নের সদস্যদের বোঝানো।
সুতরাং প্রশ্নটি হ'ল "আমাদের কি এটিকে পুনরায় পোস্ট (char *)
করার অনুমতি দেওয়া হয়েছে (const char **)
এবং এটি লিখতে হবে (const char **)
"? উপরের আমার পড়াটি হ'ল এতক্ষণ সিস্টেমে পয়েন্টার হিসাবে কোড চালিত কোডগুলি সারিবদ্ধকরণের সাথে সামঞ্জস্য করে double
, তবে ঠিক আছে।
আমরা কি "কঠোর আলিয়াজিং" লঙ্ঘন করছি? অর্থাৎ,
6.5 পার 7
একটি অবজেক্টের তার সঞ্চিত মানটি কেবলমাত্র একটি মূল্যবান এক্সপ্রেশন দ্বারা অ্যাক্সেস করতে হবে যার নিম্নলিখিত ধরণের একটি রয়েছে: ৮৮)
- বস্তুর কার্যকর ধরণের সাথে সামঞ্জস্যপূর্ণ একটি প্রকার ...
৮৮) এই তালিকার উদ্দেশ্যটি হল সেই পরিস্থিতিতে নির্দিষ্ট করা যা কোনও বস্তুর অ্যালাইজড হতে পারে বা নাও হতে পারে।
সুতরাং, সংকলকটি কী (বা ) দ্বারা নির্দেশিত বস্তুর কার্যকর ধরণটি মনে করে ? সম্ভবত ঘোষিত ধরণটি , বা এটি আসলেই অস্পষ্ট? আমার কাছে এটি অনুভূত হয় যে এটি কেবল এই ক্ষেত্রে নয় কারণ একই বস্তুকে অ্যাক্সেস করার সুযোগের অন্য কোনও 'লভ্যালু' নেই।res.target
res.current
(const char **)
আমি স্বীকার করব যে আমি স্ট্যান্ডার্ডের এই বিভাগগুলি থেকে জ্ঞান আহরণের জন্য দৃ m়তার সাথে সংগ্রাম করছি।
-mtune=native
আপনার মেশিনের নির্দিষ্ট সিপিইউর জন্য অনুকূলিত izes এটি বিভিন্ন পরীক্ষার্থীর জন্য আলাদা হবে এবং এটি ইস্যুটির অংশ হতে পারে। আপনি যদি সংকলনটি চালনা করেন তবে -v
আপনার কম্পিউটারে কোন সিপিইউ পরিবার রয়েছে তা দেখতে সক্ষম হওয়া উচিত (যেমন -mtune=skylake
আমার কম্পিউটারে)।
disassemble
জিডিবির ভিতরে নির্দেশিকাটিও ব্যবহার করতে পারেন ।