কোনও ফাংশন থেকে স্ট্রাক্ট ফিরে আসার সময় সম্ভাব্য জিসিসি বাগ


133

আমি বিশ্বাস করি ও'নিলের পিসিজি পিআরএনজি বাস্তবায়নের সময় আমি জিসিসিতে একটি বাগ পেয়েছি। ( গডবোল্টের সংকলক এক্সপ্লোরার এর প্রাথমিক কোড )

, (আরডিআই-তে সংরক্ষিত ফলাফল) oldstateদ্বারা গুণ করার পরে MULTIPLIER, জিসিসি সেই ফলাফলটিকে INCREMENTআরডিএক্সে যোগ করে না INCREMENT, যা পরে র্যান্ড 32_ret.state এর রিটার্ন মান হিসাবে ব্যবহৃত হয়

একটি সর্বনিম্ন পুনরুত্পাদনযোগ্য উদাহরণ ( সংকলক এক্সপ্লোরার ):

#include <stdint.h>

struct retstruct {
    uint32_t a;
    uint64_t b;
};

struct retstruct fn(uint64_t input)
{
    struct retstruct ret;

    ret.a = 0;
    ret.b = input * 11111111111 + 111111111111;

    return ret;
}

উত্পন্ন সমাবেশ (জিসিসি 9.2, x86_64, -O3):

fn:
  movabs rdx, 11111111111     # multiplier constant (doesn't fit in imm32)
  xor eax, eax                # ret.a = 0
  imul rdi, rdx
  movabs rdx, 111111111111    # add constant; one more 1 than multiplier
     # missing   add rdx, rdi   # ret.b=... that we get with clang or older gcc
  ret
# returns RDX:RAX = constant 111111111111 : 0
# independent of input RDI, and not using the imul result it just computed

মজার বিষয় হচ্ছে, প্রথম সদস্য হিসাবে uint64_t থাকার কাঠামোটি পরিবর্তন করে সঠিক কোড তৈরি করে যেমন উভয় সদস্যকে uint64_t হিসাবে পরিবর্তন করা হয়

x86-64 সিস্টেম ভি আরডিএক্স: আরএক্স-এ 16 বাইটের চেয়ে কম স্ট্রাক্ট রিটার্ন করে যখন তারা তুচ্ছভাবে অনুলিপিযোগ্য হয়। এই ক্ষেত্রে ২ য় সদস্য আরডিএক্সে রয়েছে কারণ উচ্চতর অর্ধেক RAX প্রান্তিককরণের জন্য প্যাডিং বা .bযখন .aসংকীর্ণ ধরণের হয়। ( sizeof(retstruct)যে কোনও উপায়ে 16 টি; আমরা ব্যবহার করছি না __attribute__((packed))তাই এটি অ্যালাইনফের সম্মান করে (uint64_t) = 8.)

এই কোডটিতে এমন কোনও অপরিজ্ঞিত আচরণ রয়েছে যা জিসিসিকে "ভুল" অ্যাসেম্বলিটি নির্গত করতে দেয়?

যদি তা না হয় তবে https://gcc.gnu.org/bugzilla/ এ এই প্রতিবেদন করা উচিত


মন্তব্যগুলি বর্ধিত আলোচনার জন্য নয়; এই কথোপকথন চ্যাটে সরানো হয়েছে ।
স্যামুয়েল লিউ

উত্তর:


102

আমি এখানে কোনও ইউবি দেখতে পাচ্ছি না; আপনার প্রকারগুলি স্বাক্ষরিত না হওয়ায় স্বাক্ষরিত-ওভারফ্লো ইউবি অসম্ভব, এবং অদ্ভুত কিছু নেই। (এবং স্বাক্ষরিত হলেও, এটি ইনপুটগুলির জন্য সঠিক আউটপুট উত্পাদন করতে পারে যা ওভারফ্লো ইউবি যেমন না ঘটায় rdi=1)। এটি জিসিসির সি ++ ফ্রন্ট-এন্ডের সাথেও ভেঙে গেছে।

এছাড়াও, জিসিসি 8.2 এটিকে আআআর্ক 64 এবং আরআইএসসি-ভি এর জন্য সঠিকভাবে সংকলন করেছে (কনস্ট্যান্টগুলি নির্মাণের maddপরে কোনও নির্দেশে movk, বা আরআইএসসি-ভি মুল এবং কনস্ট্যান্টগুলি লোড করার পরে যুক্ত করুন)। এটি যদি ইউসি হয় যে জিসিসি সন্ধান করছে, আমরা সাধারণত এটি খুঁজে পেতে এবং অন্যান্য আইএসএর জন্যও আপনার কোডটি ভেঙে ফেলার আশা করি, কমপক্ষে একই ধরণের প্রস্থ এবং প্রস্থ নিবন্ধন করুন।

ঝাঁকুনি এটি সঠিকভাবে সংকলন করে।

এটি জিসিসি 5 থেকে 6 এর একটি রিগ্রেশন বলে মনে হয়; GCC5.4 সংকলন সঠিকভাবে, 6.1 এবং পরে না। ( গডবোল্ট )

আপনি আপনার প্রশ্ন থেকে MCVE ব্যবহার করে জিসিসির বাগজিলায় এটি প্রতিবেদন করতে পারেন ।

দেখে মনে হচ্ছে এটি x86-64 সিস্টেম ভি স্ট্রাক্ট-রিটার্ন হ্যান্ডলিংয়ের একটি বাগ, সম্ভবত প্যাডিং যুক্ত স্ট্রাইকগুলির। এটি aইনলাইন করার সময় এবং uint64_t প্রশস্ত হওয়ার সময় (প্যাডিং এড়ানো) কেন কাজ করে তা ব্যাখ্যা করবে ।



11
@ ভিটারহ্নান মনে হচ্ছে এটি ঠিক হয়ে গেছে master
এসএস আন

19

এটি trunk/ / এ স্থির করা হয়েছে master

এখানে প্রাসঙ্গিক প্রতিশ্রুতি

এবং এটি সমস্যাটি সমাধান করার জন্য একটি প্যাচ

প্যাচ একটি মন্তব্য উপর ভিত্তি করে, reload_combine_recognize_patternফাংশন সামঞ্জস্য করার চেষ্টা ছিল ব্যবহারের insns


14

এই কোডটিতে এমন কোনও অপরিজ্ঞিত আচরণ রয়েছে যা জিসিসিকে "ভুল" অ্যাসেম্বলিটি নির্গত করতে দেয়?

প্রশ্নে উপস্থাপিত কোডের আচরণটি C99 এবং পরবর্তীকালে সি ভাষার মানগুলির সাথে ভালভাবে সংজ্ঞায়িত হয়েছে। বিশেষত, সি বিন্যাস ছাড়াই কাঠামোর মানগুলি ফিরিয়ে আনতে ফাংশনগুলিকে অনুমতি দেয়।


2
জিসিসি ফাংশনটির এককভাবে সংজ্ঞা তৈরি করে; এটিই আমরা লক্ষ্য করছি, আপনি যখন অন্য ফাংশনগুলির সাথে অনুবাদ ইউনিটে এটি সংকলন করেন তখন তা চলে কিনা তা নির্বিশেষে। আপনি __attribute__((noinline))নিজেই অনুবাদ অনুবাদে এটি নিজেই সংকলন করে এবং এলটিওর সাথে সংযোগ স্থাপনের মাধ্যমে, বা -fPICসমস্ত গ্লোবাল প্রতীকগুলি (ডিফল্টরূপে) ইন্টারপোজেবল দ্বারা সংযুক্ত করে সংকলন করে ঠিক যেমন সহজে কল করতে পারেন তবে কলকারীদের মধ্যে linedোকানো যায় না। তবে প্রকৃতপক্ষে কলকারী নির্বিশেষে উত্পন্ন এ্যাসেমটি দেখে সমস্যাটি সনাক্তযোগ্য।
পিটার কর্ডেস

@ পিটারকর্ডস যথেষ্ট ন্যায্য, যদিও আমি যুক্তিযুক্ত আত্মবিশ্বাসী যে গডবোল্টে আমার অধীনে থেকে সেই বিবরণটি পরিবর্তিত হয়েছিল।
জন বলিঞ্জার

প্রশ্নটির সংস্করণ 1 গডবোল্টের সাথে যুক্ত হয়েছে একটি অনুবাদ ইউনিটে কেবল ফাংশনের সাথে, যখন আপনি উত্তর দিয়েছিলেন তখন নিজেই প্রশ্নের অবস্থা। আপনি যে সমস্ত সংশোধনী বা মন্তব্যগুলি দেখেছিলেন তা আমি পরীক্ষা করে দেখিনি। ব্রিজের নীচে জল, তবে আমি মনে করি না যে কখনও দাবী ছিল যে উত্সটি যখন ব্যবহৃত হয় তখন কেবলমাত্র asm সংজ্ঞাটি কেবল ভেঙে যায় __attribute__((noinline))। (এটি একটি জিসিসি নির্ভুলতা বাগের উপায়টি অবাক করে দেওয়ার মতো নয়) তবে তা মর্মাহত হবে। সম্ভবত এটি ফলাফল পরীক্ষা করে এমন একটি পরীক্ষা কলার করার জন্য উল্লেখ করা হয়েছিল।
পিটার কর্ডেস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.